@strapi/admin 5.13.0-beta.0 → 5.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Auth/components/Register.js +1 -1
- package/dist/admin/admin/src/pages/Auth/components/Register.js.map +1 -1
- package/dist/admin/admin/src/pages/Auth/components/Register.mjs +1 -1
- package/dist/admin/admin/src/pages/Auth/components/Register.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Home/HomePage.js +4 -76
- package/dist/admin/admin/src/pages/Home/HomePage.js.map +1 -1
- package/dist/admin/admin/src/pages/Home/HomePage.mjs +5 -77
- package/dist/admin/admin/src/pages/Home/HomePage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.js +19 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.mjs +21 -3
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.js +4 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.mjs +4 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.js +32 -2
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.mjs +32 -2
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.js +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.mjs +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.mjs.map +1 -1
- package/dist/admin/admin/src/translations/ru.json.js +14 -1
- package/dist/admin/admin/src/translations/ru.json.js.map +1 -1
- package/dist/admin/admin/src/translations/ru.json.mjs +14 -1
- package/dist/admin/admin/src/translations/ru.json.mjs.map +1 -1
- package/dist/admin/src/pages/Settings/components/Tokens/FormHead.d.ts +4 -1
- package/dist/server/server/src/content-types/api-token.js +7 -0
- package/dist/server/server/src/content-types/api-token.js.map +1 -1
- package/dist/server/server/src/content-types/api-token.mjs +7 -0
- package/dist/server/server/src/content-types/api-token.mjs.map +1 -1
- package/dist/server/server/src/services/api-token.js +21 -3
- package/dist/server/server/src/services/api-token.js.map +1 -1
- package/dist/server/server/src/services/api-token.mjs +21 -3
- package/dist/server/server/src/services/api-token.mjs.map +1 -1
- package/dist/server/server/src/services/encryption.js +62 -0
- package/dist/server/server/src/services/encryption.js.map +1 -0
- package/dist/server/server/src/services/encryption.mjs +60 -0
- package/dist/server/server/src/services/encryption.mjs.map +1 -0
- package/dist/server/server/src/services/index.js +3 -1
- package/dist/server/server/src/services/index.js.map +1 -1
- package/dist/server/server/src/services/index.mjs +3 -1
- package/dist/server/server/src/services/index.mjs.map +1 -1
- package/dist/server/src/content-types/api-token.d.ts +7 -0
- package/dist/server/src/content-types/api-token.d.ts.map +1 -1
- package/dist/server/src/content-types/index.d.ts +7 -0
- package/dist/server/src/content-types/index.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +11 -0
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/services/api-token.d.ts.map +1 -1
- package/dist/server/src/services/encryption.d.ts +6 -0
- package/dist/server/src/services/encryption.d.ts.map +1 -0
- package/dist/server/src/services/index.d.ts +4 -0
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/shared/contracts/api-token.d.ts +1 -0
- package/dist/shared/contracts/api-token.d.ts.map +1 -1
- package/package.json +7 -7
- package/dist/admin/admin/src/pages/Home/components/ContentManagerWidgets.js +0 -179
- package/dist/admin/admin/src/pages/Home/components/ContentManagerWidgets.js.map +0 -1
- package/dist/admin/admin/src/pages/Home/components/ContentManagerWidgets.mjs +0 -176
- package/dist/admin/admin/src/pages/Home/components/ContentManagerWidgets.mjs.map +0 -1
- package/dist/admin/admin/src/services/homepage.js +0 -28
- package/dist/admin/admin/src/services/homepage.js.map +0 -1
- package/dist/admin/admin/src/services/homepage.mjs +0 -26
- package/dist/admin/admin/src/services/homepage.mjs.map +0 -1
- package/dist/admin/src/pages/Home/components/ContentManagerWidgets.d.ts +0 -3
- package/dist/admin/src/services/homepage.d.ts +0 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-token.mjs","sources":["../../../../../server/src/services/api-token.ts"],"sourcesContent":["import crypto from 'crypto';\nimport { omit, difference, isNil, isEmpty, map, isArray, uniq, isNumber } from 'lodash/fp';\nimport { errors } from '@strapi/utils';\nimport type { Update, ApiToken, ApiTokenBody } from '../../../shared/contracts/api-token';\nimport constants from './constants';\n\nconst { ValidationError, NotFoundError } = errors;\n\ntype ApiTokenPermission = {\n id: number | `${number}`;\n action: string;\n token: DBApiToken | number;\n};\n\ntype DBApiToken = ApiToken & {\n permissions: (number | ApiTokenPermission)[];\n};\n\nconst SELECT_FIELDS = [\n 'id',\n 'name',\n 'description',\n 'lastUsedAt',\n 'type',\n 'lifespan',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n];\n\nconst POPULATE_FIELDS = ['permissions'];\n\n// TODO: we need to ensure the permissions are actually valid registered permissions!\n\n/**\n * Assert that a token's permissions attribute is valid for its type\n */\nconst assertCustomTokenPermissionsValidity = (\n type: ApiTokenBody['type'],\n permissions: ApiTokenBody['permissions']\n) => {\n // Ensure non-custom tokens doesn't have permissions\n if (type !== constants.API_TOKEN_TYPE.CUSTOM && !isEmpty(permissions)) {\n throw new ValidationError('Non-custom tokens should not reference permissions');\n }\n\n // Custom type tokens should always have permissions attached to them\n if (type === constants.API_TOKEN_TYPE.CUSTOM && !isArray(permissions)) {\n throw new ValidationError('Missing permissions attribute for custom token');\n }\n\n // Permissions provided for a custom type token should be valid/registered permissions UID\n if (type === constants.API_TOKEN_TYPE.CUSTOM) {\n const validPermissions = strapi.contentAPI.permissions.providers.action.keys();\n const invalidPermissions = difference(permissions, validPermissions) as string[];\n\n if (!isEmpty(invalidPermissions)) {\n throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);\n }\n }\n};\n\n/**\n * Check if a token's lifespan is valid\n */\nconst isValidLifespan = (lifespan: unknown) => {\n if (isNil(lifespan)) {\n return true;\n }\n\n if (!isNumber(lifespan) || !Object.values(constants.API_TOKEN_LIFESPANS).includes(lifespan)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Assert that a token's lifespan is valid\n */\nconst assertValidLifespan = (lifespan: unknown) => {\n if (!isValidLifespan(lifespan)) {\n throw new ValidationError(\n `lifespan must be one of the following values:\n ${Object.values(constants.API_TOKEN_LIFESPANS).join(', ')}`\n );\n }\n};\n\n/**\n * Flatten a token's database permissions objects to an array of strings\n */\nconst flattenTokenPermissions = (token: DBApiToken): ApiToken => {\n if (!token) {\n return token;\n }\n\n return {\n ...token,\n permissions: isArray(token.permissions) ? map('action', token.permissions) : token.permissions,\n };\n};\n\ntype WhereParams = {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n};\n\n/**\n * Get a token\n */\nconst getBy = async (whereParams: WhereParams = {}): Promise<ApiToken | null> => {\n if (Object.keys(whereParams).length === 0) {\n return null;\n }\n\n const token = await strapi.db\n .query('admin::api-token')\n .findOne({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: whereParams });\n\n if (!token) {\n return token;\n }\n\n return flattenTokenPermissions(token);\n};\n\n/**\n * Check if token exists\n */\nconst exists = async (whereParams: WhereParams = {}): Promise<boolean> => {\n const apiToken = await getBy(whereParams);\n\n return !!apiToken;\n};\n\n/**\n * Return a secure sha512 hash of an accessKey\n */\nconst hash = (accessKey: string) => {\n return crypto\n .createHmac('sha512', strapi.config.get('admin.apiToken.salt'))\n .update(accessKey)\n .digest('hex');\n};\n\nconst getExpirationFields = (lifespan: ApiTokenBody['lifespan']) => {\n // it must be nil or a finite number >= 0\n const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;\n if (!isValidNumber && !isNil(lifespan)) {\n throw new ValidationError('lifespan must be a positive number or null');\n }\n\n return {\n lifespan: lifespan || null,\n expiresAt: lifespan ? Date.now() + lifespan : null,\n };\n};\n\n/**\n * Create a token and its permissions\n */\nconst create = async (attributes: ApiTokenBody): Promise<ApiToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n\n assertCustomTokenPermissionsValidity(attributes.type, attributes.permissions);\n assertValidLifespan(attributes.lifespan);\n\n // Create the token\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...omit('permissions', attributes),\n accessKey: hash(accessKey),\n ...getExpirationFields(attributes.lifespan),\n },\n });\n\n const result: ApiToken = { ...apiToken, accessKey };\n\n // If this is a custom type token, create and the related permissions\n if (attributes.type === constants.API_TOKEN_TYPE.CUSTOM) {\n // TODO: createMany doesn't seem to create relation properly, implement a better way rather than a ton of queries\n // const permissionsCount = await strapi.db.query('admin::api-token-permission').createMany({\n // populate: POPULATE_FIELDS,\n // data: attributes.permissions.map(action => ({ action, token: apiToken })),\n // });\n await Promise.all(\n uniq(attributes.permissions).map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: apiToken },\n })\n )\n );\n\n const currentPermissions = await strapi.db\n .query('admin::api-token')\n .load(apiToken, 'permissions');\n\n if (currentPermissions) {\n Object.assign(result, { permissions: map('action', currentPermissions) });\n }\n }\n\n return result;\n};\n\nconst regenerate = async (id: string | number): Promise<ApiToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: ['id', 'accessKey'],\n where: { id },\n data: {\n accessKey: hash(accessKey),\n },\n });\n\n if (!apiToken) {\n throw new NotFoundError('The provided token id does not exist');\n }\n\n return {\n ...apiToken,\n accessKey,\n };\n};\n\nconst checkSaltIsDefined = () => {\n if (!strapi.config.get('admin.apiToken.salt')) {\n // TODO V5: stop reading API_TOKEN_SALT\n if (process.env.API_TOKEN_SALT) {\n process.emitWarning(`[deprecated] In future versions, Strapi will stop reading directly from the environment variable API_TOKEN_SALT. Please set apiToken.salt in config/admin.js instead.\nFor security reasons, keep storing the secret in an environment variable and use env() to read it in config/admin.js (ex: \\`apiToken: { salt: env('API_TOKEN_SALT') }\\`). See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`);\n\n strapi.config.set('admin.apiToken.salt', process.env.API_TOKEN_SALT);\n } else {\n throw new Error(\n `Missing apiToken.salt. Please set apiToken.salt in config/admin.js (ex: you can generate one using Node with \\`crypto.randomBytes(16).toString('base64')\\`).\nFor security reasons, prefer storing the secret in an environment variable and read it in config/admin.js. See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`\n );\n }\n }\n};\n\n/**\n * Return a list of all tokens and their permissions\n */\nconst list = async (): Promise<Array<ApiToken>> => {\n const tokens: Array<DBApiToken> = await strapi.db.query('admin::api-token').findMany({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n orderBy: { name: 'ASC' },\n });\n\n if (!tokens) {\n return tokens;\n }\n\n return tokens.map((token) => flattenTokenPermissions(token));\n};\n\n/**\n * Revoke (delete) a token\n */\nconst revoke = async (id: string | number): Promise<ApiToken> => {\n return strapi.db\n .query('admin::api-token')\n .delete({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: { id } });\n};\n\n/**\n * Retrieve a token by id\n */\nconst getById = async (id: string | number) => {\n return getBy({ id });\n};\n\n/**\n * Retrieve a token by name\n */\nconst getByName = async (name: string) => {\n return getBy({ name });\n};\n\n/**\n * Update a token and its permissions\n */\nconst update = async (\n id: string | number,\n attributes: Update.Request['body']\n): Promise<ApiToken> => {\n // retrieve token without permissions\n const originalToken: DBApiToken = await strapi.db\n .query('admin::api-token')\n .findOne({ where: { id } });\n\n if (!originalToken) {\n throw new NotFoundError('Token not found');\n }\n\n const changingTypeToCustom =\n attributes.type === constants.API_TOKEN_TYPE.CUSTOM &&\n originalToken.type !== constants.API_TOKEN_TYPE.CUSTOM;\n\n // if we're updating the permissions on any token type, or changing from non-custom to custom, ensure they're still valid\n // if neither type nor permissions are changing, we don't need to validate again or else we can't allow partial update\n if (attributes.permissions || changingTypeToCustom) {\n assertCustomTokenPermissionsValidity(\n attributes.type || originalToken.type,\n attributes.permissions || originalToken.permissions\n );\n }\n\n assertValidLifespan(attributes.lifespan);\n\n const updatedToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: SELECT_FIELDS,\n where: { id },\n data: omit('permissions', attributes),\n });\n\n // custom tokens need to have their permissions updated as well\n if (updatedToken.type === constants.API_TOKEN_TYPE.CUSTOM && attributes.permissions) {\n const currentPermissionsResult = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n const currentPermissions = map('action', currentPermissionsResult || []);\n const newPermissions = uniq(attributes.permissions);\n\n const actionsToDelete = difference(currentPermissions, newPermissions);\n const actionsToAdd = difference(newPermissions, currentPermissions);\n\n // TODO: improve efficiency here\n // method using a loop -- works but very inefficient\n await Promise.all(\n actionsToDelete.map((action) =>\n strapi.db.query('admin::api-token-permission').delete({\n where: { action, token: id },\n })\n )\n );\n\n // TODO: improve efficiency here\n // using a loop -- works but very inefficient\n await Promise.all(\n actionsToAdd.map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: id },\n })\n )\n );\n }\n // if type is not custom, make sure any old permissions get removed\n else if (updatedToken.type !== constants.API_TOKEN_TYPE.CUSTOM) {\n await strapi.db.query('admin::api-token-permission').delete({\n where: { token: id },\n });\n }\n\n // retrieve permissions\n const permissionsFromDb = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n return {\n ...updatedToken,\n permissions: permissionsFromDb ? permissionsFromDb.map((p: any) => p.action) : undefined,\n };\n};\n\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::api-token').count({ where });\n};\n\nexport {\n create,\n count,\n regenerate,\n exists,\n checkSaltIsDefined,\n hash,\n list,\n revoke,\n getById,\n update,\n getByName,\n getBy,\n};\n"],"names":["ValidationError","NotFoundError","errors","SELECT_FIELDS","POPULATE_FIELDS","assertCustomTokenPermissionsValidity","type","permissions","constants","API_TOKEN_TYPE","CUSTOM","isEmpty","isArray","validPermissions","strapi","contentAPI","providers","action","keys","invalidPermissions","difference","join","isValidLifespan","lifespan","isNil","isNumber","Object","values","API_TOKEN_LIFESPANS","includes","assertValidLifespan","flattenTokenPermissions","token","map","getBy","whereParams","length","db","query","findOne","select","populate","where","exists","apiToken","hash","accessKey","crypto","createHmac","config","get","update","digest","getExpirationFields","isValidNumber","Number","isFinite","expiresAt","Date","now","create","attributes","randomBytes","toString","data","omit","result","Promise","all","uniq","currentPermissions","load","assign","regenerate","id","checkSaltIsDefined","process","env","API_TOKEN_SALT","emitWarning","set","Error","list","tokens","findMany","orderBy","name","revoke","delete","getById","getByName","originalToken","changingTypeToCustom","updatedToken","currentPermissionsResult","newPermissions","actionsToDelete","actionsToAdd","permissionsFromDb","p","undefined","count"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api-token.mjs","sources":["../../../../../server/src/services/api-token.ts"],"sourcesContent":["import crypto from 'crypto';\nimport { omit, difference, isNil, isEmpty, map, isArray, uniq, isNumber } from 'lodash/fp';\nimport { errors } from '@strapi/utils';\nimport type { Update, ApiToken, ApiTokenBody } from '../../../shared/contracts/api-token';\nimport constants from './constants';\nimport { getService } from '../utils';\n\nconst { ValidationError, NotFoundError } = errors;\n\ntype ApiTokenPermission = {\n id: number | `${number}`;\n action: string;\n token: DBApiToken | number;\n};\n\ntype DBApiToken = ApiToken & {\n permissions: (number | ApiTokenPermission)[];\n};\n\nconst SELECT_FIELDS = [\n 'id',\n 'name',\n 'description',\n 'lastUsedAt',\n 'type',\n 'lifespan',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n];\n\nconst POPULATE_FIELDS = ['permissions'];\n\n// TODO: we need to ensure the permissions are actually valid registered permissions!\n\n/**\n * Assert that a token's permissions attribute is valid for its type\n */\nconst assertCustomTokenPermissionsValidity = (\n type: ApiTokenBody['type'],\n permissions: ApiTokenBody['permissions']\n) => {\n // Ensure non-custom tokens doesn't have permissions\n if (type !== constants.API_TOKEN_TYPE.CUSTOM && !isEmpty(permissions)) {\n throw new ValidationError('Non-custom tokens should not reference permissions');\n }\n\n // Custom type tokens should always have permissions attached to them\n if (type === constants.API_TOKEN_TYPE.CUSTOM && !isArray(permissions)) {\n throw new ValidationError('Missing permissions attribute for custom token');\n }\n\n // Permissions provided for a custom type token should be valid/registered permissions UID\n if (type === constants.API_TOKEN_TYPE.CUSTOM) {\n const validPermissions = strapi.contentAPI.permissions.providers.action.keys();\n const invalidPermissions = difference(permissions, validPermissions) as string[];\n\n if (!isEmpty(invalidPermissions)) {\n throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);\n }\n }\n};\n\n/**\n * Check if a token's lifespan is valid\n */\nconst isValidLifespan = (lifespan: unknown) => {\n if (isNil(lifespan)) {\n return true;\n }\n\n if (!isNumber(lifespan) || !Object.values(constants.API_TOKEN_LIFESPANS).includes(lifespan)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Assert that a token's lifespan is valid\n */\nconst assertValidLifespan = (lifespan: unknown) => {\n if (!isValidLifespan(lifespan)) {\n throw new ValidationError(\n `lifespan must be one of the following values:\n ${Object.values(constants.API_TOKEN_LIFESPANS).join(', ')}`\n );\n }\n};\n\n/**\n * Flatten a token's database permissions objects to an array of strings\n */\nconst flattenTokenPermissions = (token: DBApiToken): ApiToken => {\n if (!token) {\n return token;\n }\n\n return {\n ...token,\n permissions: isArray(token.permissions) ? map('action', token.permissions) : token.permissions,\n };\n};\n\ntype WhereParams = {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n};\n\n/**\n * Get a token\n */\nconst getBy = async (whereParams: WhereParams = {}): Promise<ApiToken | null> => {\n if (Object.keys(whereParams).length === 0) {\n return null;\n }\n\n const token = await strapi.db.query('admin::api-token').findOne({\n select: [...SELECT_FIELDS, 'encryptedKey'],\n populate: POPULATE_FIELDS,\n where: whereParams,\n });\n\n if (!token) {\n return token;\n }\n\n const { encryptedKey, ...rest } = token;\n\n if (!encryptedKey) {\n return flattenTokenPermissions(rest);\n }\n\n const accessKey = getService('encryption').decrypt(encryptedKey);\n\n return flattenTokenPermissions({\n ...rest,\n accessKey,\n });\n};\n\n/**\n * Check if token exists\n */\nconst exists = async (whereParams: WhereParams = {}): Promise<boolean> => {\n const apiToken = await getBy(whereParams);\n\n return !!apiToken;\n};\n\n/**\n * Return a secure sha512 hash of an accessKey\n */\nconst hash = (accessKey: string) => {\n return crypto\n .createHmac('sha512', strapi.config.get('admin.apiToken.salt'))\n .update(accessKey)\n .digest('hex');\n};\n\nconst getExpirationFields = (lifespan: ApiTokenBody['lifespan']) => {\n // it must be nil or a finite number >= 0\n const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;\n if (!isValidNumber && !isNil(lifespan)) {\n throw new ValidationError('lifespan must be a positive number or null');\n }\n\n return {\n lifespan: lifespan || null,\n expiresAt: lifespan ? Date.now() + lifespan : null,\n };\n};\n\n/**\n * Create a token and its permissions\n */\nconst create = async (attributes: ApiTokenBody): Promise<ApiToken> => {\n const encryptionService = getService('encryption');\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n assertCustomTokenPermissionsValidity(attributes.type, attributes.permissions);\n assertValidLifespan(attributes.lifespan);\n\n // Create the token\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...omit('permissions', attributes),\n accessKey: hash(accessKey),\n encryptedKey,\n ...getExpirationFields(attributes.lifespan),\n },\n });\n\n const result: ApiToken = { ...apiToken, accessKey };\n\n // If this is a custom type token, create and the related permissions\n if (attributes.type === constants.API_TOKEN_TYPE.CUSTOM) {\n // TODO: createMany doesn't seem to create relation properly, implement a better way rather than a ton of queries\n // const permissionsCount = await strapi.db.query('admin::api-token-permission').createMany({\n // populate: POPULATE_FIELDS,\n // data: attributes.permissions.map(action => ({ action, token: apiToken })),\n // });\n await Promise.all(\n uniq(attributes.permissions).map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: apiToken },\n })\n )\n );\n\n const currentPermissions = await strapi.db\n .query('admin::api-token')\n .load(apiToken, 'permissions');\n\n if (currentPermissions) {\n Object.assign(result, { permissions: map('action', currentPermissions) });\n }\n }\n\n return result;\n};\n\nconst regenerate = async (id: string | number): Promise<ApiToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptionService = getService('encryption');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: ['id', 'accessKey'],\n where: { id },\n data: {\n accessKey: hash(accessKey),\n encryptedKey,\n },\n });\n\n if (!apiToken) {\n throw new NotFoundError('The provided token id does not exist');\n }\n\n return {\n ...apiToken,\n accessKey,\n };\n};\n\nconst checkSaltIsDefined = () => {\n if (!strapi.config.get('admin.apiToken.salt')) {\n // TODO V5: stop reading API_TOKEN_SALT\n if (process.env.API_TOKEN_SALT) {\n process.emitWarning(`[deprecated] In future versions, Strapi will stop reading directly from the environment variable API_TOKEN_SALT. Please set apiToken.salt in config/admin.js instead.\nFor security reasons, keep storing the secret in an environment variable and use env() to read it in config/admin.js (ex: \\`apiToken: { salt: env('API_TOKEN_SALT') }\\`). See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`);\n\n strapi.config.set('admin.apiToken.salt', process.env.API_TOKEN_SALT);\n } else {\n throw new Error(\n `Missing apiToken.salt. Please set apiToken.salt in config/admin.js (ex: you can generate one using Node with \\`crypto.randomBytes(16).toString('base64')\\`).\nFor security reasons, prefer storing the secret in an environment variable and read it in config/admin.js. See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`\n );\n }\n }\n};\n\n/**\n * Return a list of all tokens and their permissions\n */\nconst list = async (): Promise<Array<ApiToken>> => {\n const tokens: Array<DBApiToken> = await strapi.db.query('admin::api-token').findMany({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n orderBy: { name: 'ASC' },\n });\n\n if (!tokens) {\n return tokens;\n }\n\n return tokens.map((token) => flattenTokenPermissions(token));\n};\n\n/**\n * Revoke (delete) a token\n */\nconst revoke = async (id: string | number): Promise<ApiToken> => {\n return strapi.db\n .query('admin::api-token')\n .delete({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: { id } });\n};\n\n/**\n * Retrieve a token by id\n */\nconst getById = async (id: string | number) => {\n return getBy({ id });\n};\n\n/**\n * Retrieve a token by name\n */\nconst getByName = async (name: string) => {\n return getBy({ name });\n};\n\n/**\n * Update a token and its permissions\n */\nconst update = async (\n id: string | number,\n attributes: Update.Request['body']\n): Promise<ApiToken> => {\n // retrieve token without permissions\n const originalToken: DBApiToken = await strapi.db\n .query('admin::api-token')\n .findOne({ where: { id } });\n\n if (!originalToken) {\n throw new NotFoundError('Token not found');\n }\n\n const changingTypeToCustom =\n attributes.type === constants.API_TOKEN_TYPE.CUSTOM &&\n originalToken.type !== constants.API_TOKEN_TYPE.CUSTOM;\n\n // if we're updating the permissions on any token type, or changing from non-custom to custom, ensure they're still valid\n // if neither type nor permissions are changing, we don't need to validate again or else we can't allow partial update\n if (attributes.permissions || changingTypeToCustom) {\n assertCustomTokenPermissionsValidity(\n attributes.type || originalToken.type,\n attributes.permissions || originalToken.permissions\n );\n }\n\n assertValidLifespan(attributes.lifespan);\n\n const updatedToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: SELECT_FIELDS,\n where: { id },\n data: omit('permissions', attributes),\n });\n\n // custom tokens need to have their permissions updated as well\n if (updatedToken.type === constants.API_TOKEN_TYPE.CUSTOM && attributes.permissions) {\n const currentPermissionsResult = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n const currentPermissions = map('action', currentPermissionsResult || []);\n const newPermissions = uniq(attributes.permissions);\n\n const actionsToDelete = difference(currentPermissions, newPermissions);\n const actionsToAdd = difference(newPermissions, currentPermissions);\n\n // TODO: improve efficiency here\n // method using a loop -- works but very inefficient\n await Promise.all(\n actionsToDelete.map((action) =>\n strapi.db.query('admin::api-token-permission').delete({\n where: { action, token: id },\n })\n )\n );\n\n // TODO: improve efficiency here\n // using a loop -- works but very inefficient\n await Promise.all(\n actionsToAdd.map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: id },\n })\n )\n );\n }\n // if type is not custom, make sure any old permissions get removed\n else if (updatedToken.type !== constants.API_TOKEN_TYPE.CUSTOM) {\n await strapi.db.query('admin::api-token-permission').delete({\n where: { token: id },\n });\n }\n\n // retrieve permissions\n const permissionsFromDb = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n return {\n ...updatedToken,\n permissions: permissionsFromDb ? permissionsFromDb.map((p: any) => p.action) : undefined,\n };\n};\n\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::api-token').count({ where });\n};\n\nexport {\n create,\n count,\n regenerate,\n exists,\n checkSaltIsDefined,\n hash,\n list,\n revoke,\n getById,\n update,\n getByName,\n getBy,\n};\n"],"names":["ValidationError","NotFoundError","errors","SELECT_FIELDS","POPULATE_FIELDS","assertCustomTokenPermissionsValidity","type","permissions","constants","API_TOKEN_TYPE","CUSTOM","isEmpty","isArray","validPermissions","strapi","contentAPI","providers","action","keys","invalidPermissions","difference","join","isValidLifespan","lifespan","isNil","isNumber","Object","values","API_TOKEN_LIFESPANS","includes","assertValidLifespan","flattenTokenPermissions","token","map","getBy","whereParams","length","db","query","findOne","select","populate","where","encryptedKey","rest","accessKey","getService","decrypt","exists","apiToken","hash","crypto","createHmac","config","get","update","digest","getExpirationFields","isValidNumber","Number","isFinite","expiresAt","Date","now","create","attributes","encryptionService","randomBytes","toString","encrypt","data","omit","result","Promise","all","uniq","currentPermissions","load","assign","regenerate","id","checkSaltIsDefined","process","env","API_TOKEN_SALT","emitWarning","set","Error","list","tokens","findMany","orderBy","name","revoke","delete","getById","getByName","originalToken","changingTypeToCustom","updatedToken","currentPermissionsResult","newPermissions","actionsToDelete","actionsToAdd","permissionsFromDb","p","undefined","count"],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var crypto = require('crypto');
|
|
4
|
+
|
|
5
|
+
const IV_LENGTH = 16; // 16 bytes for AES-GCM IV
|
|
6
|
+
const ENCRYPTION_VERSION = 'v1';
|
|
7
|
+
const getHashedKey = ()=>{
|
|
8
|
+
const rawKey = strapi.config.get('admin.secrets.encryptionKey');
|
|
9
|
+
if (!rawKey) {
|
|
10
|
+
strapi.log.warn('Encryption key is missing from config');
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return crypto.createHash('sha256').update(rawKey).digest(); // Always 32 bytes
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Encrypts a value string using AES-256-GCM.
|
|
17
|
+
* Returns a string prefixed with the encryption version and includes IV, encrypted content, and auth tag (all hex-encoded).
|
|
18
|
+
*/ const encrypt = (value)=>{
|
|
19
|
+
const key = getHashedKey();
|
|
20
|
+
if (!key) return null;
|
|
21
|
+
const iv = crypto.randomBytes(IV_LENGTH);
|
|
22
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
|
|
23
|
+
let encrypted = cipher.update(value, 'utf8', 'hex');
|
|
24
|
+
encrypted += cipher.final('hex');
|
|
25
|
+
const authTag = cipher.getAuthTag();
|
|
26
|
+
return `${ENCRYPTION_VERSION}:${iv.toString('hex')}:${encrypted}:${authTag.toString('hex')}`;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Decrypts a value encrypted by encrypt().
|
|
30
|
+
* Supports versioned formats like v1:iv:encrypted:authTag
|
|
31
|
+
*/ const decrypt = (encryptedValue)=>{
|
|
32
|
+
const [version, ...rest] = encryptedValue.split(':');
|
|
33
|
+
if (version !== ENCRYPTION_VERSION) {
|
|
34
|
+
throw new Error(`Unsupported encryption version: ${version}`);
|
|
35
|
+
}
|
|
36
|
+
const [ivHex, encryptedHex, tagHex] = rest;
|
|
37
|
+
if (!ivHex || !encryptedHex || !tagHex) {
|
|
38
|
+
throw new Error('Invalid encrypted value format');
|
|
39
|
+
}
|
|
40
|
+
const key = getHashedKey();
|
|
41
|
+
if (!key) return null;
|
|
42
|
+
const iv = Buffer.from(ivHex, 'hex');
|
|
43
|
+
const encryptedText = Buffer.from(encryptedHex, 'hex');
|
|
44
|
+
const authTag = Buffer.from(tagHex, 'hex');
|
|
45
|
+
try {
|
|
46
|
+
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
|
|
47
|
+
decipher.setAuthTag(authTag);
|
|
48
|
+
let decrypted = decipher.update(encryptedText, undefined, 'utf8');
|
|
49
|
+
decrypted += decipher.final('utf8');
|
|
50
|
+
return decrypted;
|
|
51
|
+
} catch (err) {
|
|
52
|
+
strapi.log.warn('[decrypt] Unable to decrypt value — encryption key may have changed or data is corrupted.');
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var encryption = {
|
|
57
|
+
encrypt,
|
|
58
|
+
decrypt
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
module.exports = encryption;
|
|
62
|
+
//# sourceMappingURL=encryption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.js","sources":["../../../../../server/src/services/encryption.ts"],"sourcesContent":["import crypto from 'crypto';\n\nconst IV_LENGTH = 16; // 16 bytes for AES-GCM IV\nconst ENCRYPTION_VERSION = 'v1';\n\nconst getHashedKey = (): Buffer | null => {\n const rawKey: string = strapi.config.get('admin.secrets.encryptionKey');\n if (!rawKey) {\n strapi.log.warn('Encryption key is missing from config');\n return null;\n }\n\n return crypto.createHash('sha256').update(rawKey).digest(); // Always 32 bytes\n};\n\n/**\n * Encrypts a value string using AES-256-GCM.\n * Returns a string prefixed with the encryption version and includes IV, encrypted content, and auth tag (all hex-encoded).\n */\nconst encrypt = (value: string) => {\n const key = getHashedKey();\n if (!key) return null;\n\n const iv = crypto.randomBytes(IV_LENGTH);\n const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);\n\n let encrypted = cipher.update(value, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n\n const authTag = cipher.getAuthTag();\n\n return `${ENCRYPTION_VERSION}:${iv.toString('hex')}:${encrypted}:${authTag.toString('hex')}`;\n};\n\n/**\n * Decrypts a value encrypted by encrypt().\n * Supports versioned formats like v1:iv:encrypted:authTag\n */\nconst decrypt = (encryptedValue: string) => {\n const [version, ...rest] = encryptedValue.split(':');\n\n if (version !== ENCRYPTION_VERSION) {\n throw new Error(`Unsupported encryption version: ${version}`);\n }\n\n const [ivHex, encryptedHex, tagHex] = rest;\n if (!ivHex || !encryptedHex || !tagHex) {\n throw new Error('Invalid encrypted value format');\n }\n\n const key = getHashedKey();\n if (!key) return null;\n\n const iv = Buffer.from(ivHex, 'hex');\n const encryptedText = Buffer.from(encryptedHex, 'hex');\n const authTag = Buffer.from(tagHex, 'hex');\n\n try {\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);\n decipher.setAuthTag(authTag);\n\n let decrypted = decipher.update(encryptedText, undefined, 'utf8');\n decrypted += decipher.final('utf8');\n\n return decrypted;\n } catch (err) {\n strapi.log.warn(\n '[decrypt] Unable to decrypt value — encryption key may have changed or data is corrupted.'\n );\n return null;\n }\n};\n\nexport default {\n encrypt,\n decrypt,\n};\n"],"names":["IV_LENGTH","ENCRYPTION_VERSION","getHashedKey","rawKey","strapi","config","get","log","warn","crypto","createHash","update","digest","encrypt","value","key","iv","randomBytes","cipher","createCipheriv","encrypted","final","authTag","getAuthTag","toString","decrypt","encryptedValue","version","rest","split","Error","ivHex","encryptedHex","tagHex","Buffer","from","encryptedText","decipher","createDecipheriv","setAuthTag","decrypted","undefined","err"],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
|
|
3
|
+
const IV_LENGTH = 16; // 16 bytes for AES-GCM IV
|
|
4
|
+
const ENCRYPTION_VERSION = 'v1';
|
|
5
|
+
const getHashedKey = ()=>{
|
|
6
|
+
const rawKey = strapi.config.get('admin.secrets.encryptionKey');
|
|
7
|
+
if (!rawKey) {
|
|
8
|
+
strapi.log.warn('Encryption key is missing from config');
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return crypto.createHash('sha256').update(rawKey).digest(); // Always 32 bytes
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Encrypts a value string using AES-256-GCM.
|
|
15
|
+
* Returns a string prefixed with the encryption version and includes IV, encrypted content, and auth tag (all hex-encoded).
|
|
16
|
+
*/ const encrypt = (value)=>{
|
|
17
|
+
const key = getHashedKey();
|
|
18
|
+
if (!key) return null;
|
|
19
|
+
const iv = crypto.randomBytes(IV_LENGTH);
|
|
20
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
|
|
21
|
+
let encrypted = cipher.update(value, 'utf8', 'hex');
|
|
22
|
+
encrypted += cipher.final('hex');
|
|
23
|
+
const authTag = cipher.getAuthTag();
|
|
24
|
+
return `${ENCRYPTION_VERSION}:${iv.toString('hex')}:${encrypted}:${authTag.toString('hex')}`;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Decrypts a value encrypted by encrypt().
|
|
28
|
+
* Supports versioned formats like v1:iv:encrypted:authTag
|
|
29
|
+
*/ const decrypt = (encryptedValue)=>{
|
|
30
|
+
const [version, ...rest] = encryptedValue.split(':');
|
|
31
|
+
if (version !== ENCRYPTION_VERSION) {
|
|
32
|
+
throw new Error(`Unsupported encryption version: ${version}`);
|
|
33
|
+
}
|
|
34
|
+
const [ivHex, encryptedHex, tagHex] = rest;
|
|
35
|
+
if (!ivHex || !encryptedHex || !tagHex) {
|
|
36
|
+
throw new Error('Invalid encrypted value format');
|
|
37
|
+
}
|
|
38
|
+
const key = getHashedKey();
|
|
39
|
+
if (!key) return null;
|
|
40
|
+
const iv = Buffer.from(ivHex, 'hex');
|
|
41
|
+
const encryptedText = Buffer.from(encryptedHex, 'hex');
|
|
42
|
+
const authTag = Buffer.from(tagHex, 'hex');
|
|
43
|
+
try {
|
|
44
|
+
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
|
|
45
|
+
decipher.setAuthTag(authTag);
|
|
46
|
+
let decrypted = decipher.update(encryptedText, undefined, 'utf8');
|
|
47
|
+
decrypted += decipher.final('utf8');
|
|
48
|
+
return decrypted;
|
|
49
|
+
} catch (err) {
|
|
50
|
+
strapi.log.warn('[decrypt] Unable to decrypt value — encryption key may have changed or data is corrupted.');
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
var encryption = {
|
|
55
|
+
encrypt,
|
|
56
|
+
decrypt
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export { encryption as default };
|
|
60
|
+
//# sourceMappingURL=encryption.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.mjs","sources":["../../../../../server/src/services/encryption.ts"],"sourcesContent":["import crypto from 'crypto';\n\nconst IV_LENGTH = 16; // 16 bytes for AES-GCM IV\nconst ENCRYPTION_VERSION = 'v1';\n\nconst getHashedKey = (): Buffer | null => {\n const rawKey: string = strapi.config.get('admin.secrets.encryptionKey');\n if (!rawKey) {\n strapi.log.warn('Encryption key is missing from config');\n return null;\n }\n\n return crypto.createHash('sha256').update(rawKey).digest(); // Always 32 bytes\n};\n\n/**\n * Encrypts a value string using AES-256-GCM.\n * Returns a string prefixed with the encryption version and includes IV, encrypted content, and auth tag (all hex-encoded).\n */\nconst encrypt = (value: string) => {\n const key = getHashedKey();\n if (!key) return null;\n\n const iv = crypto.randomBytes(IV_LENGTH);\n const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);\n\n let encrypted = cipher.update(value, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n\n const authTag = cipher.getAuthTag();\n\n return `${ENCRYPTION_VERSION}:${iv.toString('hex')}:${encrypted}:${authTag.toString('hex')}`;\n};\n\n/**\n * Decrypts a value encrypted by encrypt().\n * Supports versioned formats like v1:iv:encrypted:authTag\n */\nconst decrypt = (encryptedValue: string) => {\n const [version, ...rest] = encryptedValue.split(':');\n\n if (version !== ENCRYPTION_VERSION) {\n throw new Error(`Unsupported encryption version: ${version}`);\n }\n\n const [ivHex, encryptedHex, tagHex] = rest;\n if (!ivHex || !encryptedHex || !tagHex) {\n throw new Error('Invalid encrypted value format');\n }\n\n const key = getHashedKey();\n if (!key) return null;\n\n const iv = Buffer.from(ivHex, 'hex');\n const encryptedText = Buffer.from(encryptedHex, 'hex');\n const authTag = Buffer.from(tagHex, 'hex');\n\n try {\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);\n decipher.setAuthTag(authTag);\n\n let decrypted = decipher.update(encryptedText, undefined, 'utf8');\n decrypted += decipher.final('utf8');\n\n return decrypted;\n } catch (err) {\n strapi.log.warn(\n '[decrypt] Unable to decrypt value — encryption key may have changed or data is corrupted.'\n );\n return null;\n }\n};\n\nexport default {\n encrypt,\n decrypt,\n};\n"],"names":["IV_LENGTH","ENCRYPTION_VERSION","getHashedKey","rawKey","strapi","config","get","log","warn","crypto","createHash","update","digest","encrypt","value","key","iv","randomBytes","cipher","createCipheriv","encrypted","final","authTag","getAuthTag","toString","decrypt","encryptedValue","version","rest","split","Error","ivHex","encryptedHex","tagHex","Buffer","from","encryptedText","decipher","createDecipheriv","setAuthTag","decrypted","undefined","err"],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ var user = require('./user.js');
|
|
|
5
5
|
var role = require('./role.js');
|
|
6
6
|
var passport = require('./passport.js');
|
|
7
7
|
var metrics = require('./metrics.js');
|
|
8
|
+
var encryption = require('./encryption.js');
|
|
8
9
|
var token = require('./token.js');
|
|
9
10
|
var permission = require('./permission.js');
|
|
10
11
|
var contentType = require('./content-type.js');
|
|
@@ -35,7 +36,8 @@ var services = {
|
|
|
35
36
|
action,
|
|
36
37
|
'api-token': apiToken,
|
|
37
38
|
transfer: index,
|
|
38
|
-
'project-settings': projectSettings
|
|
39
|
+
'project-settings': projectSettings,
|
|
40
|
+
encryption
|
|
39
41
|
};
|
|
40
42
|
|
|
41
43
|
module.exports = services;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../server/src/services/index.ts"],"sourcesContent":["// NOTE: Make sure to use default export for services overwritten in EE\nimport auth from './auth';\nimport user from './user';\nimport role from './role';\nimport passport from './passport';\nimport metrics from './metrics';\nimport * as token from './token';\nimport * as permission from './permission';\nimport * as contentType from './content-type';\nimport * as constants from './constants';\nimport * as condition from './condition';\nimport * as action from './action';\nimport * as apiToken from './api-token';\nimport * as transfer from './transfer';\nimport * as projectSettings from './project-settings';\n\n// TODO: TS - Export services one by one as this export is cjs\nexport default {\n auth,\n user,\n role,\n passport,\n token,\n permission,\n metrics,\n 'content-type': contentType,\n constants,\n condition,\n action,\n 'api-token': apiToken,\n transfer,\n 'project-settings': projectSettings,\n};\n"],"names":["auth","user","role","passport","token","permission","metrics","contentType","constants","condition","action","apiToken","transfer","projectSettings"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../server/src/services/index.ts"],"sourcesContent":["// NOTE: Make sure to use default export for services overwritten in EE\nimport auth from './auth';\nimport user from './user';\nimport role from './role';\nimport passport from './passport';\nimport metrics from './metrics';\nimport encryption from './encryption';\nimport * as token from './token';\nimport * as permission from './permission';\nimport * as contentType from './content-type';\nimport * as constants from './constants';\nimport * as condition from './condition';\nimport * as action from './action';\nimport * as apiToken from './api-token';\nimport * as transfer from './transfer';\nimport * as projectSettings from './project-settings';\n\n// TODO: TS - Export services one by one as this export is cjs\nexport default {\n auth,\n user,\n role,\n passport,\n token,\n permission,\n metrics,\n 'content-type': contentType,\n constants,\n condition,\n action,\n 'api-token': apiToken,\n transfer,\n 'project-settings': projectSettings,\n encryption,\n};\n"],"names":["auth","user","role","passport","token","permission","metrics","contentType","constants","condition","action","apiToken","transfer","projectSettings","encryption"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAiBA;AACA,eAAe;AACbA,IAAAA,IAAAA;AACAC,IAAAA,IAAAA;AACAC,IAAAA,IAAAA;AACAC,IAAAA,QAAAA;AACAC,IAAAA,KAAAA;AACAC,IAAAA,UAAAA;AACAC,IAAAA,OAAAA;IACA,cAAgBC,EAAAA,WAAAA;AAChBC,eAAAA,oBAAAA;AACAC,IAAAA,SAAAA;AACAC,IAAAA,MAAAA;IACA,WAAaC,EAAAA,QAAAA;AACbC,cAAAA,KAAAA;IACA,kBAAoBC,EAAAA,eAAAA;AACpBC,IAAAA;AACF,CAAE;;;;"}
|
|
@@ -3,6 +3,7 @@ import user from './user.mjs';
|
|
|
3
3
|
import role from './role.mjs';
|
|
4
4
|
import passport from './passport.mjs';
|
|
5
5
|
import metrics from './metrics.mjs';
|
|
6
|
+
import encryption from './encryption.mjs';
|
|
6
7
|
import * as token from './token.mjs';
|
|
7
8
|
import * as permission from './permission.mjs';
|
|
8
9
|
import * as contentType from './content-type.mjs';
|
|
@@ -29,7 +30,8 @@ var services = {
|
|
|
29
30
|
action,
|
|
30
31
|
'api-token': apiToken,
|
|
31
32
|
transfer: index,
|
|
32
|
-
'project-settings': projectSettings
|
|
33
|
+
'project-settings': projectSettings,
|
|
34
|
+
encryption
|
|
33
35
|
};
|
|
34
36
|
|
|
35
37
|
export { services as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../../../server/src/services/index.ts"],"sourcesContent":["// NOTE: Make sure to use default export for services overwritten in EE\nimport auth from './auth';\nimport user from './user';\nimport role from './role';\nimport passport from './passport';\nimport metrics from './metrics';\nimport * as token from './token';\nimport * as permission from './permission';\nimport * as contentType from './content-type';\nimport * as constants from './constants';\nimport * as condition from './condition';\nimport * as action from './action';\nimport * as apiToken from './api-token';\nimport * as transfer from './transfer';\nimport * as projectSettings from './project-settings';\n\n// TODO: TS - Export services one by one as this export is cjs\nexport default {\n auth,\n user,\n role,\n passport,\n token,\n permission,\n metrics,\n 'content-type': contentType,\n constants,\n condition,\n action,\n 'api-token': apiToken,\n transfer,\n 'project-settings': projectSettings,\n};\n"],"names":["auth","user","role","passport","token","permission","metrics","contentType","constants","condition","action","apiToken","transfer","projectSettings"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../../server/src/services/index.ts"],"sourcesContent":["// NOTE: Make sure to use default export for services overwritten in EE\nimport auth from './auth';\nimport user from './user';\nimport role from './role';\nimport passport from './passport';\nimport metrics from './metrics';\nimport encryption from './encryption';\nimport * as token from './token';\nimport * as permission from './permission';\nimport * as contentType from './content-type';\nimport * as constants from './constants';\nimport * as condition from './condition';\nimport * as action from './action';\nimport * as apiToken from './api-token';\nimport * as transfer from './transfer';\nimport * as projectSettings from './project-settings';\n\n// TODO: TS - Export services one by one as this export is cjs\nexport default {\n auth,\n user,\n role,\n passport,\n token,\n permission,\n metrics,\n 'content-type': contentType,\n constants,\n condition,\n action,\n 'api-token': apiToken,\n transfer,\n 'project-settings': projectSettings,\n encryption,\n};\n"],"names":["auth","user","role","passport","token","permission","metrics","contentType","constants","condition","action","apiToken","transfer","projectSettings","encryption"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAiBA;AACA,eAAe;AACbA,IAAAA,IAAAA;AACAC,IAAAA,IAAAA;AACAC,IAAAA,IAAAA;AACAC,IAAAA,QAAAA;AACAC,IAAAA,KAAAA;AACAC,IAAAA,UAAAA;AACAC,IAAAA,OAAAA;IACA,cAAgBC,EAAAA,WAAAA;AAChBC,IAAAA,SAAAA;AACAC,IAAAA,SAAAA;AACAC,IAAAA,MAAAA;IACA,WAAaC,EAAAA,QAAAA;AACbC,cAAAA,KAAAA;IACA,kBAAoBC,EAAAA,eAAAA;AACpBC,IAAAA;AACF,CAAE;;;;"}
|
|
@@ -45,6 +45,13 @@ declare const _default: {
|
|
|
45
45
|
required: boolean;
|
|
46
46
|
searchable: boolean;
|
|
47
47
|
};
|
|
48
|
+
encryptedKey: {
|
|
49
|
+
type: string;
|
|
50
|
+
minLength: number;
|
|
51
|
+
configurable: boolean;
|
|
52
|
+
required: boolean;
|
|
53
|
+
searchable: boolean;
|
|
54
|
+
};
|
|
48
55
|
lastUsedAt: {
|
|
49
56
|
type: string;
|
|
50
57
|
configurable: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../../../server/src/content-types/api-token.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../../../server/src/content-types/api-token.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,wBA8EE"}
|
|
@@ -269,6 +269,13 @@ declare const _default: {
|
|
|
269
269
|
required: boolean;
|
|
270
270
|
searchable: boolean;
|
|
271
271
|
};
|
|
272
|
+
encryptedKey: {
|
|
273
|
+
type: string;
|
|
274
|
+
minLength: number;
|
|
275
|
+
configurable: boolean;
|
|
276
|
+
required: boolean;
|
|
277
|
+
searchable: boolean;
|
|
278
|
+
};
|
|
272
279
|
lastUsedAt: {
|
|
273
280
|
type: string;
|
|
274
281
|
configurable: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/src/content-types/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/src/content-types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,wBAQE"}
|
|
@@ -185,6 +185,10 @@ declare let admin: {
|
|
|
185
185
|
'api-token': typeof import("./services/api-token");
|
|
186
186
|
transfer: typeof import("./services/transfer");
|
|
187
187
|
'project-settings': typeof import("./services/project-settings");
|
|
188
|
+
encryption: {
|
|
189
|
+
encrypt: (value: string) => string | null;
|
|
190
|
+
decrypt: (encryptedValue: string) => string | null;
|
|
191
|
+
};
|
|
188
192
|
};
|
|
189
193
|
controllers: {
|
|
190
194
|
admin: {
|
|
@@ -563,6 +567,13 @@ declare let admin: {
|
|
|
563
567
|
required: boolean;
|
|
564
568
|
searchable: boolean;
|
|
565
569
|
};
|
|
570
|
+
encryptedKey: {
|
|
571
|
+
type: string;
|
|
572
|
+
minLength: number;
|
|
573
|
+
configurable: boolean;
|
|
574
|
+
required: boolean;
|
|
575
|
+
searchable: boolean;
|
|
576
|
+
};
|
|
566
577
|
lastUsedAt: {
|
|
567
578
|
type: string;
|
|
568
579
|
configurable: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../server/src/index.ts"],"names":[],"mappings":";AAeA,QAAA,IAAI,KAAK
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../server/src/index.ts"],"names":[],"mappings":";AAeA,QAAA,IAAI,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAWR,CAAC;AAUF,eAAe,KAAK,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../../../server/src/services/api-token.ts"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../../../server/src/services/api-token.ts"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAqG1F,KAAK,WAAW,GAAG;IACjB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,KAAK,iBAAuB,WAAW,KAAQ,QAAQ,QAAQ,GAAG,IAAI,CA2B3E,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,MAAM,iBAAuB,WAAW,KAAQ,QAAQ,OAAO,CAIpE,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,IAAI,cAAe,MAAM,WAK9B,CAAC;AAeF;;GAEG;AACH,QAAA,MAAM,MAAM,eAAsB,YAAY,KAAG,QAAQ,QAAQ,CA+ChE,CAAC;AAEF,QAAA,MAAM,UAAU,OAAc,MAAM,GAAG,MAAM,KAAG,QAAQ,QAAQ,CAsB/D,CAAC;AAEF,QAAA,MAAM,kBAAkB,YAevB,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,IAAI,QAAa,QAAQ,MAAM,QAAQ,CAAC,CAY7C,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,MAAM,OAAc,MAAM,GAAG,MAAM,KAAG,QAAQ,QAAQ,CAI3D,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,OAAO,OAAc,MAAM,GAAG,MAAM,6BAEzC,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,SAAS,SAAgB,MAAM,6BAEpC,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,MAAM,OACN,MAAM,GAAG,MAAM,cACP,cAAc,CAAC,MAAM,CAAC,KACjC,QAAQ,QAAQ,CA+ElB,CAAC;AAEF,QAAA,MAAM,KAAK,kBAAuB,QAAQ,MAAM,CAE/C,CAAC;AAEF,OAAO,EACL,MAAM,EACN,KAAK,EACL,UAAU,EACV,MAAM,EACN,kBAAkB,EAClB,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,OAAO,EACP,MAAM,EACN,SAAS,EACT,KAAK,GACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../../../server/src/services/encryption.ts"],"names":[],"mappings":";;;;AAyEA,wBAGE"}
|
|
@@ -107,6 +107,10 @@ declare const _default: {
|
|
|
107
107
|
'api-token': typeof apiToken;
|
|
108
108
|
transfer: typeof transfer;
|
|
109
109
|
'project-settings': typeof projectSettings;
|
|
110
|
+
encryption: {
|
|
111
|
+
encrypt: (value: string) => string | null;
|
|
112
|
+
decrypt: (encryptedValue: string) => string | null;
|
|
113
|
+
};
|
|
110
114
|
};
|
|
111
115
|
export default _default;
|
|
112
116
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/src/services/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/src/services/index.ts"],"names":[],"mappings":";AAOA,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,WAAW,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,eAAe,MAAM,oBAAoB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGtD,wBAgBE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../../shared/contracts/api-token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,MAAM,QAAQ,GAAG;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;IACZ,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,QAAQ,GAAG,aAAa,GAAG,WAAW,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAAC;IAC1E,QAAQ,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IAC7C,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC;IAC9B,UAAiB,OAAO;QACtB,IAAI,EAAE,YAAY,CAAC;QACnB,KAAK,EAAE,EAAE,CAAC;KACX;IAED,UAAiB,QAAQ;QACvB,IAAI,EAAE,QAAQ,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC;KAC7D;CACF;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,WAAW,IAAI,CAAC;IAC5B,UAAiB,OAAO;QACtB,IAAI,EAAE,EAAE,CAAC;QACT,KAAK,EAAE,EAAE,CAAC;KACX;IAED,UAAiB,QAAQ;QACvB,IAAI,EAAE,QAAQ,EAAE,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC,gBAAgB,CAAC;KACjC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC;IAC9B,UAAiB,OAAO;QACtB,IAAI,EAAE,EAAE,CAAC;QACT,KAAK,EAAE,EAAE,CAAC;KACX;IAED,UAAiB,MAAM;QACrB,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;KACb;IAED,UAAiB,QAAQ;QACvB,IAAI,EAAE,QAAQ,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC,gBAAgB,CAAC;KACjC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,WAAW,GAAG,CAAC;IAC3B,UAAiB,OAAO;QACtB,IAAI,EAAE,EAAE,CAAC;QACT,KAAK,EAAE,EAAE,CAAC;KACX;IAED,UAAiB,MAAM;QACrB,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;KACb;IAED,UAAiB,QAAQ;QACvB,IAAI,EAAE,QAAQ,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC,gBAAgB,CAAC;KACjC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC;IAC9B,UAAiB,OAAO;QACtB,IAAI,EAAE,YAAY,CAAC;QACnB,KAAK,EAAE,EAAE,CAAC;KACX;IAED,UAAiB,MAAM;QACrB,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;KACb;IAED,UAAiB,QAAQ;QACvB,IAAI,EAAE,QAAQ,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC;KAC7D;CACF"}
|
|
1
|
+
{"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../../shared/contracts/api-token.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/admin",
|
|
3
|
-
"version": "5.13.0
|
|
3
|
+
"version": "5.13.0",
|
|
4
4
|
"description": "Strapi Admin",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -86,10 +86,10 @@
|
|
|
86
86
|
"@reduxjs/toolkit": "1.9.7",
|
|
87
87
|
"@strapi/design-system": "2.0.0-rc.23",
|
|
88
88
|
"@strapi/icons": "2.0.0-rc.23",
|
|
89
|
-
"@strapi/permissions": "5.13.0
|
|
90
|
-
"@strapi/types": "5.13.0
|
|
91
|
-
"@strapi/typescript-utils": "5.13.0
|
|
92
|
-
"@strapi/utils": "5.13.0
|
|
89
|
+
"@strapi/permissions": "5.13.0",
|
|
90
|
+
"@strapi/types": "5.13.0",
|
|
91
|
+
"@strapi/typescript-utils": "5.13.0",
|
|
92
|
+
"@strapi/utils": "5.13.0",
|
|
93
93
|
"@testing-library/dom": "10.1.0",
|
|
94
94
|
"@testing-library/react": "15.0.7",
|
|
95
95
|
"@testing-library/user-event": "14.5.2",
|
|
@@ -143,8 +143,8 @@
|
|
|
143
143
|
"zod": "^3.22.4"
|
|
144
144
|
},
|
|
145
145
|
"devDependencies": {
|
|
146
|
-
"@strapi/admin-test-utils": "5.13.0
|
|
147
|
-
"@strapi/data-transfer": "5.13.0
|
|
146
|
+
"@strapi/admin-test-utils": "5.13.0",
|
|
147
|
+
"@strapi/data-transfer": "5.13.0",
|
|
148
148
|
"@types/codemirror5": "npm:@types/codemirror@^5.60.15",
|
|
149
149
|
"@types/fs-extra": "11.0.4",
|
|
150
150
|
"@types/invariant": "2.2.36",
|