diff --git a/CHANGES b/CHANGES index d4fe2509a..eb545b009 100644 --- a/CHANGES +++ b/CHANGES @@ -2930,4 +2930,5 @@ * ldap: automatically detect pagination support * ubuntu: alert for 20.04 support being deprecated * domains: vanity nameservers +* token: access can by restricted by ip range(s) diff --git a/dashboard/public/translation/en.json b/dashboard/public/translation/en.json index 294c2bd8f..053ebcfa3 100644 --- a/dashboard/public/translation/en.json +++ b/dashboard/public/translation/en.json @@ -457,7 +457,9 @@ "neverUsed": "never", "scope": "Scope", "readonly": "Readonly", - "readwrite": "Read and Write" + "readwrite": "Read and Write", + "allowedIpRangesPlaceholder": "Comma separated IPs or Subnets", + "allowedIpRanges": "Allowed IPs" }, "loginTokens": { "title": "Login Tokens", @@ -502,7 +504,8 @@ "description": "New API token:", "copyNow": "Please copy the API token now. It won't be shown again for security purposes.", "generateToken": "Generate API Token", - "access": "API Access" + "access": "API Access", + "allowedIpRanges": "Allowed IP Range(s)" }, "changePasswordAction": "Change Password", "disable2FAAction": "Disable 2FA", diff --git a/dashboard/public/translation/nl.json b/dashboard/public/translation/nl.json index f8b06740f..877ed7c08 100644 --- a/dashboard/public/translation/nl.json +++ b/dashboard/public/translation/nl.json @@ -1019,7 +1019,7 @@ "mountTypeWarning": "Het bestemmingsbestandssysteem moet bestandsmachtigingen en eigendom ondersteunen om de verhuizing te laten werken" }, "mounts": { - "title": "Koppelpunten", + "title": "Volume koppelpunten", "readOnly": "Alleen-lezen", "volume": "Volume", "noMounts": "Er zijn geen Volumes gekoppeld.", diff --git a/dashboard/src/components/ApiTokens.vue b/dashboard/src/components/ApiTokens.vue index ffacc001c..46ca8b597 100644 --- a/dashboard/src/components/ApiTokens.vue +++ b/dashboard/src/components/ApiTokens.vue @@ -20,6 +20,8 @@ const newDialog = useTemplateRef('newDialog'); const addedToken = ref(''); const tokenName = ref(''); const tokenScope = ref('r'); +const tokenAllowedIpRanges = ref(''); +const tokenAllowedIpRangesError = ref(''); const columns = { name: { label: t('profile.apiTokens.name'), @@ -37,6 +39,10 @@ const columns = { label: t('profile.apiTokens.scope'), sort: true }, + allowedIpRanges: { + label: t('profile.apiTokens.allowedIpRanges'), + sort: true + }, actions: {} }; @@ -57,8 +63,12 @@ async function onSubmitAddApiToken(){ if (!isValid.value) return; const scope = { '*': tokenScope.value }; - const [error, apiToken] = await tokensModel.add(tokenName.value, scope); - if (error) return console.error(error); + const allowedIpRanges = tokenAllowedIpRanges.value; + const [error, apiToken] = await tokensModel.add(tokenName.value, scope, allowedIpRanges); + if (error) { + tokenAllowedIpRangesError.value = error.body ? error.body.message : 'Internal error'; + return; + } addedToken.value = apiToken.accessToken; @@ -75,6 +85,8 @@ function onReset() { addedToken.value = ''; tokenName.value = ''; tokenScope.value = 'r'; + tokenAllowedIpRanges.value = ''; + tokenAllowedIpRangesError.value = ''; }, 500); } @@ -128,6 +140,12 @@ onMounted(async () => { + + + +
{{ tokenAllowedIpRangesError }}
+ +
@@ -157,6 +175,10 @@ onMounted(async () => { {{ $t('profile.apiTokens.readwrite') }} {{ $t('profile.apiTokens.readonly') }} +