feat(api tokens): validate title field when creating a new token
This commit is contained in:
parent
e47ad021a3
commit
021f92303d
|
@ -150,8 +150,10 @@
|
||||||
"60d": "60 Days",
|
"60d": "60 Days",
|
||||||
"90d": "90 Days",
|
"90d": "90 Days",
|
||||||
"permissionExplanation": "Permissions allow you to scope what an api token is allowed to do.",
|
"permissionExplanation": "Permissions allow you to scope what an api token is allowed to do.",
|
||||||
|
"titleRequired": "The title is required",
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"title": "Title",
|
"title": "Title",
|
||||||
|
"titlePlaceholder": "Enter a title you will recognize later",
|
||||||
"expiresAt": "Expires at",
|
"expiresAt": "Expires at",
|
||||||
"permissions": "Permissions"
|
"permissions": "Permissions"
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ export interface IApiPermission {
|
||||||
|
|
||||||
export interface IApiToken extends IAbstract {
|
export interface IApiToken extends IAbstract {
|
||||||
id: number
|
id: number
|
||||||
|
title: string
|
||||||
token: string
|
token: string
|
||||||
permissions: IApiPermission
|
permissions: IApiPermission
|
||||||
expiresAt: Date
|
expiresAt: Date
|
||||||
|
|
|
@ -3,6 +3,7 @@ import type {IApiToken} from '@/modelTypes/IApiToken'
|
||||||
|
|
||||||
export default class ApiTokenModel extends AbstractModel<IApiToken> {
|
export default class ApiTokenModel extends AbstractModel<IApiToken> {
|
||||||
id = 0
|
id = 0
|
||||||
|
title = ''
|
||||||
token = ''
|
token = ''
|
||||||
permissions = null
|
permissions = null
|
||||||
expiresAt: Date = null
|
expiresAt: Date = null
|
||||||
|
|
|
@ -16,6 +16,8 @@ const availableRoutes = ref(null)
|
||||||
const newToken = ref(new ApiTokenModel())
|
const newToken = ref(new ApiTokenModel())
|
||||||
const newTokenExpiry = ref<string | number>(30)
|
const newTokenExpiry = ref<string | number>(30)
|
||||||
const newTokenPermissions = ref({})
|
const newTokenPermissions = ref({})
|
||||||
|
const newTokenTitleValid = ref(true)
|
||||||
|
const apiTokenTitle = ref()
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
tokens.value = await service.getAll()
|
tokens.value = await service.getAll()
|
||||||
|
@ -38,8 +40,13 @@ function deleteToken() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createToken() {
|
async function createToken() {
|
||||||
|
if (!newTokenTitleValid.value) {
|
||||||
|
apiTokenTitle.value.focus()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const expiry = Number(newTokenExpiry.value)
|
const expiry = Number(newTokenExpiry.value)
|
||||||
if(!isNaN(expiry)) {
|
if (!isNaN(expiry)) {
|
||||||
// if it's a number, we assume it's the number of days in the future
|
// if it's a number, we assume it's the number of days in the future
|
||||||
newToken.value.expiresAt = new Date((new Date()) + expiry * MILLISECONDS_A_DAY)
|
newToken.value.expiresAt = new Date((new Date()) + expiry * MILLISECONDS_A_DAY)
|
||||||
}
|
}
|
||||||
|
@ -113,19 +120,27 @@ async function createToken() {
|
||||||
<input
|
<input
|
||||||
class="input"
|
class="input"
|
||||||
id="apiTokenTitle"
|
id="apiTokenTitle"
|
||||||
|
ref="apiTokenTitle"
|
||||||
type="text"
|
type="text"
|
||||||
v-focus
|
v-focus
|
||||||
v-model="newToken.title"/>
|
:placeholder="$t('user.settings.apiTokens.attributes.titlePlaceholder')"
|
||||||
|
v-model="newToken.title"
|
||||||
|
@keyup="() => newTokenTitleValid = newToken.title !== ''"
|
||||||
|
@focusout="() => newTokenTitleValid = newToken.title !== ''"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<p class="help is-danger" v-if="!newTokenTitleValid">
|
||||||
|
{{ $t('user.settings.apiTokens.titleRequired') }}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Expiry -->
|
<!-- Expiry -->
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="apiTokenTitle">{{
|
<label class="label" for="apiTokenExpiry">
|
||||||
$t('user.settings.apiTokens.attributes.expiresAt')
|
{{ $t('user.settings.apiTokens.attributes.expiresAt') }}
|
||||||
}}</label>
|
</label>
|
||||||
<div class="control select">
|
<div class="control select">
|
||||||
<select class="select" v-model="newTokenExpiry">
|
<select class="select" v-model="newTokenExpiry" id="apiTokenExpiry">
|
||||||
<option value="30">{{ $t('user.settings.apiTokens.30d') }}</option>
|
<option value="30">{{ $t('user.settings.apiTokens.30d') }}</option>
|
||||||
<option value="60">{{ $t('user.settings.apiTokens.60d') }}</option>
|
<option value="60">{{ $t('user.settings.apiTokens.60d') }}</option>
|
||||||
<option value="90">{{ $t('user.settings.apiTokens.90d') }}</option>
|
<option value="90">{{ $t('user.settings.apiTokens.90d') }}</option>
|
||||||
|
|
Reference in New Issue
Block a user