mirror of
https://github.com/strapi/strapi.git
synced 2025-07-31 21:09:39 +00:00
add lifespan and expiresAt fields
This commit is contained in:
parent
c8af2cef6b
commit
36d37706ce
@ -60,5 +60,15 @@ module.exports = {
|
|||||||
configurable: false,
|
configurable: false,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
expiresAt: {
|
||||||
|
type: 'datetime',
|
||||||
|
configurable: false,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
lifespan: {
|
||||||
|
type: 'number',
|
||||||
|
configurable: false,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,17 @@ describe('API Token', () => {
|
|||||||
hexedString: '6170692d746f6b656e5f746573742d72616e646f6d2d6279746573',
|
hexedString: '6170692d746f6b656e5f746573742d72616e646f6d2d6279746573',
|
||||||
};
|
};
|
||||||
|
|
||||||
const SELECT_FIELDS = ['id', 'name', 'description', 'lastUsed', 'type', 'createdAt', 'updatedAt'];
|
const SELECT_FIELDS = [
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'description',
|
||||||
|
'lastUsed',
|
||||||
|
'type',
|
||||||
|
'lifespan',
|
||||||
|
'expiresAt',
|
||||||
|
'createdAt',
|
||||||
|
'updatedAt',
|
||||||
|
];
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
jest
|
jest
|
||||||
@ -48,12 +58,16 @@ describe('API Token', () => {
|
|||||||
data: {
|
data: {
|
||||||
...attributes,
|
...attributes,
|
||||||
accessKey: apiTokenService.hash(mockedApiToken.hexedString),
|
accessKey: apiTokenService.hash(mockedApiToken.hexedString),
|
||||||
|
expiresAt: null,
|
||||||
|
lifespan: null,
|
||||||
},
|
},
|
||||||
populate: ['permissions'],
|
populate: ['permissions'],
|
||||||
});
|
});
|
||||||
expect(res).toEqual({
|
expect(res).toEqual({
|
||||||
...attributes,
|
...attributes,
|
||||||
accessKey: mockedApiToken.hexedString,
|
accessKey: mockedApiToken.hexedString,
|
||||||
|
expiresAt: null,
|
||||||
|
lifespan: null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
const { isNumber, isNil } = require('lodash');
|
||||||
const { omit, difference, isEmpty, map, isArray } = require('lodash/fp');
|
const { omit, difference, isEmpty, map, isArray } = require('lodash/fp');
|
||||||
const { ValidationError, NotFoundError } = require('@strapi/utils').errors;
|
const { ValidationError, NotFoundError } = require('@strapi/utils').errors;
|
||||||
const constants = require('./constants');
|
const constants = require('./constants');
|
||||||
@ -17,6 +18,8 @@ const constants = require('./constants');
|
|||||||
* @property {string} [description]
|
* @property {string} [description]
|
||||||
* @property {string} accessKey
|
* @property {string} accessKey
|
||||||
* @property {number} lastUsed
|
* @property {number} lastUsed
|
||||||
|
* @property {number} lifespan
|
||||||
|
* @property {number} expiresAt
|
||||||
* @property {TokenType} type
|
* @property {TokenType} type
|
||||||
* @property {(number|ApiTokenPermission)[]} [permissions]
|
* @property {(number|ApiTokenPermission)[]} [permissions]
|
||||||
*/
|
*/
|
||||||
@ -30,7 +33,17 @@ const constants = require('./constants');
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/** @constant {Array<string>} */
|
/** @constant {Array<string>} */
|
||||||
const SELECT_FIELDS = ['id', 'name', 'description', 'lastUsed', 'type', 'createdAt', 'updatedAt'];
|
const SELECT_FIELDS = [
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'description',
|
||||||
|
'lastUsed',
|
||||||
|
'type',
|
||||||
|
'lifespan',
|
||||||
|
'expiresAt',
|
||||||
|
'createdAt',
|
||||||
|
'updatedAt',
|
||||||
|
];
|
||||||
|
|
||||||
/** @constant {Array<string>} */
|
/** @constant {Array<string>} */
|
||||||
const POPULATE_FIELDS = ['permissions'];
|
const POPULATE_FIELDS = ['permissions'];
|
||||||
@ -75,10 +88,27 @@ const hash = (accessKey) => {
|
|||||||
.digest('hex');
|
.digest('hex');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} lifespan
|
||||||
|
*
|
||||||
|
* @returns {null|number}
|
||||||
|
*/
|
||||||
|
const getExpirationFields = (lifespan) => {
|
||||||
|
if (!isNumber(lifespan) && !isNil(lifespan)) {
|
||||||
|
throw new ValidationError('lifespan must be a number or null');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
lifespan: lifespan || null,
|
||||||
|
expiresAt: lifespan ? Date.now() + lifespan : null,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} attributes
|
* @param {Object} attributes
|
||||||
* @param {TokenType} attributes.type
|
* @param {TokenType} attributes.type
|
||||||
* @param {string} attributes.name
|
* @param {string} attributes.name
|
||||||
|
* @param {number} attributes.lifespan
|
||||||
* @param {string[]} [attributes.permissions]
|
* @param {string[]} [attributes.permissions]
|
||||||
* @param {string} [attributes.description]
|
* @param {string} [attributes.description]
|
||||||
*
|
*
|
||||||
@ -96,6 +126,7 @@ const create = async (attributes) => {
|
|||||||
data: {
|
data: {
|
||||||
...omit('permissions', attributes),
|
...omit('permissions', attributes),
|
||||||
accessKey: hash(accessKey),
|
accessKey: hash(accessKey),
|
||||||
|
...getExpirationFields(attributes.lifespan),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ const apiTokenCreationSchema = yup
|
|||||||
description: yup.string().optional(),
|
description: yup.string().optional(),
|
||||||
type: yup.string().oneOf(Object.values(constants.API_TOKEN_TYPE)).required(),
|
type: yup.string().oneOf(Object.values(constants.API_TOKEN_TYPE)).required(),
|
||||||
permissions: yup.array().of(yup.string()).nullable(),
|
permissions: yup.array().of(yup.string()).nullable(),
|
||||||
|
lifespan: yup.number().nullable(),
|
||||||
})
|
})
|
||||||
.noUnknown();
|
.noUnknown();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user