feat(xo-server): authentication tokens can have a description
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
// TODO: Prevent token connections from creating tokens.
|
||||
// TODO: Token permission.
|
||||
export async function create({ expiresIn }) {
|
||||
export async function create({ description, expiresIn }) {
|
||||
return (
|
||||
await this.createAuthenticationToken({
|
||||
description,
|
||||
expiresIn,
|
||||
userId: this.connection.get('user_id'),
|
||||
})
|
||||
@@ -12,6 +13,10 @@ export async function create({ expiresIn }) {
|
||||
create.description = 'create a new authentication token'
|
||||
|
||||
create.params = {
|
||||
description: {
|
||||
optional: true,
|
||||
type: 'string',
|
||||
},
|
||||
expiresIn: {
|
||||
optional: true,
|
||||
type: ['number', 'string'],
|
||||
@@ -53,3 +58,16 @@ deleteAll.description = 'delete all tokens of the current user except the curren
|
||||
deleteAll.params = {
|
||||
except: { type: 'string', optional: true },
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export async function set({ id, ...props }) {
|
||||
await this.updateAuthenticationToken({ id, user_id: this.connection.get('user_id') }, props)
|
||||
}
|
||||
|
||||
set.description = 'changes the properties of an existing token'
|
||||
|
||||
set.params = {
|
||||
description: { type: ['null', 'string'], optional: true },
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
@@ -224,6 +224,7 @@ async function setUpPassport(express, xo, { authentication: authCfg, http: { coo
|
||||
const setToken = async (req, res, next) => {
|
||||
const { user, isPersistent } = req.session
|
||||
const token = await xo.createAuthenticationToken({
|
||||
description: 'web sign in',
|
||||
expiresIn: isPersistent ? PERMANENT_VALIDITY : SESSION_VALIDITY,
|
||||
userId: user.id,
|
||||
})
|
||||
|
||||
@@ -4,6 +4,7 @@ import { ignoreErrors } from 'promise-toolbox'
|
||||
import { invalidCredentials, noSuchObject } from 'xo-common/api-errors.js'
|
||||
import { parseDuration } from '@vates/parse-duration'
|
||||
|
||||
import patch from '../patch.mjs'
|
||||
import Token, { Tokens } from '../models/token.mjs'
|
||||
import { forEach, generateToken } from '../utils.mjs'
|
||||
|
||||
@@ -163,7 +164,7 @@ export default class {
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
async createAuthenticationToken({ expiresIn, userId }) {
|
||||
async createAuthenticationToken({ description, expiresIn, userId }) {
|
||||
let duration = this._defaultTokenValidity
|
||||
if (expiresIn !== undefined) {
|
||||
duration = parseDuration(expiresIn)
|
||||
@@ -175,6 +176,7 @@ export default class {
|
||||
const now = Date.now()
|
||||
const token = new Token({
|
||||
created_at: now,
|
||||
description,
|
||||
id: await generateToken(),
|
||||
user_id: userId,
|
||||
expiration: now + duration,
|
||||
@@ -198,8 +200,10 @@ export default class {
|
||||
)
|
||||
}
|
||||
|
||||
async getAuthenticationToken(id) {
|
||||
let token = await this._tokens.first(id)
|
||||
async getAuthenticationToken(properties) {
|
||||
const id = typeof properties === 'string' ? properties : properties.id
|
||||
|
||||
let token = await this._tokens.first(properties)
|
||||
if (token === undefined) {
|
||||
throw noSuchAuthenticationToken(id)
|
||||
}
|
||||
@@ -233,4 +237,11 @@ export default class {
|
||||
|
||||
return tokens
|
||||
}
|
||||
|
||||
async updateAuthenticationToken(properties, { description }) {
|
||||
const token = await this.getAuthenticationToken(properties)
|
||||
patch(token, { description })
|
||||
await this._tokens.update(token)
|
||||
return token
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user