mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-31 09:56:44 +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
	 Ben Irvin
						Ben Irvin