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