2021-08-26 14:37:55 +02:00
'use strict' ;
const crypto = require ( 'crypto' ) ;
2021-08-30 14:00:53 +02:00
/ * *
* @ typedef { 'read-only' | 'full-access' } TokenType
* /
2021-08-27 09:44:29 +02:00
/ * *
* @ typedef ApiToken
*
2021-08-30 14:00:53 +02:00
* @ property { number | string } id
2021-08-27 09:44:29 +02:00
* @ property { string } name
* @ property { string } [ description ]
* @ property { string } accessKey
2021-08-30 14:00:53 +02:00
* @ property { TokenType } type
2021-08-27 09:44:29 +02:00
* /
2021-09-02 10:47:06 +02:00
/** @constant {Array<string>} */
2021-10-05 13:13:45 +02:00
const SELECT _FIELDS = [ 'id' , 'name' , 'description' , 'type' , 'createdAt' ] ;
2021-09-02 10:47:06 +02:00
2021-08-26 14:37:55 +02:00
/ * *
2021-08-27 16:23:19 +02:00
* @ param { Object } whereParams
2021-09-16 14:36:54 +02:00
* @ param { string | number } [ whereParams . id ]
* @ param { string } [ whereParams . name ]
2021-08-27 16:23:19 +02:00
* @ param { string } [ whereParams . description ]
2021-09-16 14:36:54 +02:00
* @ param { string } [ whereParams . accessKey ]
2021-08-26 14:37:55 +02:00
*
2021-08-27 10:30:18 +02:00
* @ returns { Promise < boolean > }
2021-08-26 14:37:55 +02:00
* /
2021-08-27 16:23:19 +02:00
const exists = async ( whereParams = { } ) => {
2021-09-16 14:36:54 +02:00
const apiToken = await getBy ( whereParams ) ;
2021-08-27 16:23:19 +02:00
return ! ! apiToken ;
} ;
/ * *
* @ param { string } accessKey
*
* @ returns { string }
* /
const hash = accessKey => {
return crypto
2021-10-26 12:18:53 +02:00
. createHmac ( 'sha512' , strapi . config . get ( 'admin.apiToken.salt' ) )
2021-08-27 17:06:05 +02:00
. update ( accessKey )
2021-08-27 16:23:19 +02:00
. digest ( 'hex' ) ;
2021-08-26 14:37:55 +02:00
} ;
/ * *
* @ param { Object } attributes
2021-08-30 14:00:53 +02:00
* @ param { TokenType } attributes . type
2021-08-26 14:37:55 +02:00
* @ param { string } attributes . name
* @ param { string } [ attributes . description ]
*
2021-08-27 09:44:29 +02:00
* @ returns { Promise < ApiToken > }
2021-08-26 14:37:55 +02:00
* /
const create = async attributes => {
const accessKey = crypto . randomBytes ( 128 ) . toString ( 'hex' ) ;
2021-08-27 16:23:19 +02:00
const apiToken = await strapi . query ( 'admin::api-token' ) . create ( {
2021-09-02 10:47:06 +02:00
select : SELECT _FIELDS ,
2021-08-26 14:37:55 +02:00
data : {
... attributes ,
2021-08-27 16:23:19 +02:00
accessKey : hash ( accessKey ) ,
2021-08-26 14:37:55 +02:00
} ,
} ) ;
2021-08-27 16:23:19 +02:00
return {
... apiToken ,
accessKey ,
} ;
} ;
/ * *
* @ returns { void }
* /
const createSaltIfNotDefined = ( ) => {
2021-10-26 12:18:53 +02:00
if ( strapi . config . get ( 'admin.apiToken.salt' ) ) {
2021-08-27 16:23:19 +02:00
return ;
}
2021-08-27 16:47:02 +02:00
if ( process . env . API _TOKEN _SALT ) {
throw new Error (
` There's something wrong with the configuration of your api-token salt. If you have changed the env variable used in the configuration file, please verify that you have created and set the variable in your .env file. `
) ;
2021-08-27 16:23:19 +02:00
}
2021-08-27 16:47:02 +02:00
const salt = crypto . randomBytes ( 16 ) . toString ( 'hex' ) ;
strapi . fs . appendFile ( '.env' , ` API_TOKEN_SALT= ${ salt } \n ` ) ;
2021-10-26 12:18:53 +02:00
strapi . config . set ( 'admin.apiToken.salt' , salt ) ;
2021-08-26 14:37:55 +02:00
} ;
2021-08-27 08:14:36 +02:00
/ * *
2021-09-02 10:47:06 +02:00
* @ returns { Promise < Omit < ApiToken , 'accessKey' >> }
2021-08-27 08:14:36 +02:00
* /
const list = async ( ) => {
2021-08-30 14:00:53 +02:00
return strapi . query ( 'admin::api-token' ) . findMany ( {
2021-09-02 10:47:06 +02:00
select : SELECT _FIELDS ,
2021-08-27 08:39:08 +02:00
orderBy : { name : 'ASC' } ,
} ) ;
2021-08-27 08:14:36 +02:00
} ;
2021-08-31 15:31:54 +02:00
/ * *
* @ param { string | number } id
*
2021-09-02 10:47:06 +02:00
* @ returns { Promise < Omit < ApiToken , 'accessKey' >> }
2021-08-31 15:31:54 +02:00
* /
const revoke = async id => {
2021-09-02 10:47:06 +02:00
return strapi . query ( 'admin::api-token' ) . delete ( { select : SELECT _FIELDS , where : { id } } ) ;
2021-08-31 15:31:54 +02:00
} ;
2021-09-02 11:56:14 +02:00
/ * *
* @ param { string | number } id
*
* @ returns { Promise < Omit < ApiToken , 'accessKey' >> }
* /
2021-09-06 15:14:45 +02:00
const getById = async id => {
2021-09-16 14:36:54 +02:00
return getBy ( { id } ) ;
2021-09-02 11:56:14 +02:00
} ;
2021-09-08 14:38:43 +02:00
/ * *
* @ param { string } name
*
* @ returns { Promise < Omit < ApiToken , 'accessKey' >> }
* /
const getByName = async name => {
2021-09-16 14:36:54 +02:00
return getBy ( { name } ) ;
2021-09-08 14:38:43 +02:00
} ;
2021-09-06 13:30:52 +02:00
/ * *
* @ param { string | number } id
* @ param { Object } attributes
* @ param { TokenType } attributes . type
* @ param { string } attributes . name
* @ param { string } [ attributes . description ]
*
* @ returns { Promise < Omit < ApiToken , 'accessKey' >> }
* /
const update = async ( id , attributes ) => {
return strapi
. query ( 'admin::api-token' )
. update ( { where : { id } , data : attributes , select : SELECT _FIELDS } ) ;
} ;
2021-09-16 14:36:54 +02:00
/ * *
* @ param { Object } whereParams
* @ param { string | number } [ whereParams . id ]
* @ param { string } [ whereParams . name ]
* @ param { string } [ whereParams . description ]
* @ param { string } [ whereParams . accessKey ]
*
* @ returns { Promise < Omit < ApiToken , 'accessKey' > | null > }
* /
const getBy = async ( whereParams = { } ) => {
if ( Object . keys ( whereParams ) . length === 0 ) {
return null ;
}
return strapi . query ( 'admin::api-token' ) . findOne ( { select : SELECT _FIELDS , where : whereParams } ) ;
} ;
2021-08-26 14:37:55 +02:00
module . exports = {
create ,
exists ,
2021-08-27 16:23:19 +02:00
createSaltIfNotDefined ,
hash ,
2021-08-27 08:14:36 +02:00
list ,
2021-08-31 15:31:54 +02:00
revoke ,
2021-09-06 15:14:45 +02:00
getById ,
2021-09-06 13:30:52 +02:00
update ,
2021-09-08 14:38:43 +02:00
getByName ,
2021-09-16 14:36:54 +02:00
getBy ,
2021-08-26 14:37:55 +02:00
} ;