@strapi/admin 5.50.1 → 5.51.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.
Files changed (174) hide show
  1. package/dist/admin/admin/src/components/NpsSurvey.js.map +1 -1
  2. package/dist/admin/admin/src/components/NpsSurvey.mjs.map +1 -1
  3. package/dist/admin/admin/src/hooks/useMenu.js +1 -1
  4. package/dist/admin/admin/src/hooks/useMenu.js.map +1 -1
  5. package/dist/admin/admin/src/hooks/useMenu.mjs +1 -1
  6. package/dist/admin/admin/src/hooks/useMenu.mjs.map +1 -1
  7. package/dist/admin/admin/src/hooks/useRBAC.js +1 -1
  8. package/dist/admin/admin/src/hooks/useRBAC.js.map +1 -1
  9. package/dist/admin/admin/src/hooks/useRBAC.mjs +1 -1
  10. package/dist/admin/admin/src/hooks/useRBAC.mjs.map +1 -1
  11. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js +3 -9
  12. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js.map +1 -1
  13. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs +3 -9
  14. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs.map +1 -1
  15. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js +14 -6
  16. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js.map +1 -1
  17. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs +14 -6
  18. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs.map +1 -1
  19. package/dist/admin/admin/src/reducer.js +3 -3
  20. package/dist/admin/admin/src/reducer.js.map +1 -1
  21. package/dist/admin/admin/src/reducer.mjs +4 -4
  22. package/dist/admin/admin/src/reducer.mjs.map +1 -1
  23. package/dist/admin/admin/src/render.js +6 -2
  24. package/dist/admin/admin/src/render.js.map +1 -1
  25. package/dist/admin/admin/src/render.mjs +6 -2
  26. package/dist/admin/admin/src/render.mjs.map +1 -1
  27. package/dist/admin/admin/src/translations/en.json.js +1 -2
  28. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  29. package/dist/admin/admin/src/translations/en.json.mjs +1 -2
  30. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  31. package/dist/admin/admin/src/translations/ko.json.js +157 -1
  32. package/dist/admin/admin/src/translations/ko.json.js.map +1 -1
  33. package/dist/admin/admin/src/translations/ko.json.mjs +157 -1
  34. package/dist/admin/admin/src/translations/ko.json.mjs.map +1 -1
  35. package/dist/admin/admin/src/utils/cookies.js +84 -2
  36. package/dist/admin/admin/src/utils/cookies.js.map +1 -1
  37. package/dist/admin/admin/src/utils/cookies.mjs +82 -3
  38. package/dist/admin/admin/src/utils/cookies.mjs.map +1 -1
  39. package/dist/admin/admin/src/utils/getFetchClient.js +2 -2
  40. package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
  41. package/dist/admin/admin/src/utils/getFetchClient.mjs +3 -3
  42. package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
  43. package/dist/admin/admin/src/utils/getProjectType.js +22 -0
  44. package/dist/admin/admin/src/utils/getProjectType.js.map +1 -0
  45. package/dist/admin/admin/src/utils/getProjectType.mjs +20 -0
  46. package/dist/admin/admin/src/utils/getProjectType.mjs.map +1 -0
  47. package/dist/admin/ee/admin/src/pages/AuthResponse.js +1 -1
  48. package/dist/admin/ee/admin/src/pages/AuthResponse.js.map +1 -1
  49. package/dist/admin/ee/admin/src/pages/AuthResponse.mjs +2 -2
  50. package/dist/admin/ee/admin/src/pages/AuthResponse.mjs.map +1 -1
  51. package/dist/admin/shared/utils/auth-cookie-domain.js +41 -0
  52. package/dist/admin/shared/utils/auth-cookie-domain.js.map +1 -0
  53. package/dist/admin/shared/utils/auth-cookie-domain.mjs +38 -0
  54. package/dist/admin/shared/utils/auth-cookie-domain.mjs.map +1 -0
  55. package/dist/admin/shared/utils/auth-cookie-name.js +31 -0
  56. package/dist/admin/shared/utils/auth-cookie-name.js.map +1 -0
  57. package/dist/admin/shared/utils/auth-cookie-name.mjs +28 -0
  58. package/dist/admin/shared/utils/auth-cookie-name.mjs.map +1 -0
  59. package/dist/admin/shared/utils/auth-cookie-path.js +39 -0
  60. package/dist/admin/shared/utils/auth-cookie-path.js.map +1 -0
  61. package/dist/admin/shared/utils/auth-cookie-path.mjs +36 -0
  62. package/dist/admin/shared/utils/auth-cookie-path.mjs.map +1 -0
  63. package/dist/admin/src/pages/Settings/pages/Webhooks/hooks/useWebhooks.d.ts +3 -3
  64. package/dist/admin/src/services/apiTokens.d.ts +2 -2
  65. package/dist/admin/src/services/webhooks.d.ts +2 -2
  66. package/dist/admin/src/utils/cookies.d.ts +26 -0
  67. package/dist/admin/src/utils/getProjectType.d.ts +16 -0
  68. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useAuditLogsData.d.ts +1 -1
  69. package/dist/ee/admin/src/services/ai.d.ts +3 -3
  70. package/dist/ee/admin/src/services/auditLogs.d.ts +1 -1
  71. package/dist/ee/server/src/audit-logs/routes/audit-logs.d.ts +1 -1
  72. package/dist/ee/server/src/controllers/admin.d.ts +2 -0
  73. package/dist/ee/server/src/controllers/admin.d.ts.map +1 -1
  74. package/dist/ee/server/src/controllers/authentication-utils/middlewares.d.ts.map +1 -1
  75. package/dist/ee/server/src/controllers/index.d.ts +2 -0
  76. package/dist/ee/server/src/controllers/index.d.ts.map +1 -1
  77. package/dist/ee/server/src/index.d.ts +2 -0
  78. package/dist/ee/server/src/index.d.ts.map +1 -1
  79. package/dist/ee/server/src/routes/index.d.ts +2 -2
  80. package/dist/ee/server/src/routes/sso.d.ts +2 -2
  81. package/dist/ee/server/src/services/auth.d.ts.map +1 -1
  82. package/dist/ee/server/src/services/index.d.ts +2 -2
  83. package/dist/ee/server/src/services/user.d.ts.map +1 -1
  84. package/dist/server/ee/server/src/controllers/admin.js +1 -0
  85. package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
  86. package/dist/server/ee/server/src/controllers/admin.mjs +1 -0
  87. package/dist/server/ee/server/src/controllers/admin.mjs.map +1 -1
  88. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js +10 -4
  89. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js.map +1 -1
  90. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs +11 -5
  91. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs.map +1 -1
  92. package/dist/server/ee/server/src/services/auth.js +5 -5
  93. package/dist/server/ee/server/src/services/auth.js.map +1 -1
  94. package/dist/server/ee/server/src/services/auth.mjs +5 -5
  95. package/dist/server/ee/server/src/services/auth.mjs.map +1 -1
  96. package/dist/server/ee/server/src/services/user.js +1 -0
  97. package/dist/server/ee/server/src/services/user.js.map +1 -1
  98. package/dist/server/ee/server/src/services/user.mjs +1 -0
  99. package/dist/server/ee/server/src/services/user.mjs.map +1 -1
  100. package/dist/server/server/src/content-types/User.js +6 -0
  101. package/dist/server/server/src/content-types/User.js.map +1 -1
  102. package/dist/server/server/src/content-types/User.mjs +6 -0
  103. package/dist/server/server/src/content-types/User.mjs.map +1 -1
  104. package/dist/server/server/src/controllers/authentication.js +12 -10
  105. package/dist/server/server/src/controllers/authentication.js.map +1 -1
  106. package/dist/server/server/src/controllers/authentication.mjs +10 -8
  107. package/dist/server/server/src/controllers/authentication.mjs.map +1 -1
  108. package/dist/server/server/src/routes/serve-admin-panel.js +17 -4
  109. package/dist/server/server/src/routes/serve-admin-panel.js.map +1 -1
  110. package/dist/server/server/src/routes/serve-admin-panel.mjs +17 -4
  111. package/dist/server/server/src/routes/serve-admin-panel.mjs.map +1 -1
  112. package/dist/server/server/src/services/auth.js +51 -6
  113. package/dist/server/server/src/services/auth.js.map +1 -1
  114. package/dist/server/server/src/services/auth.mjs +46 -6
  115. package/dist/server/server/src/services/auth.mjs.map +1 -1
  116. package/dist/server/server/src/services/index.js +1 -1
  117. package/dist/server/server/src/services/index.js.map +1 -1
  118. package/dist/server/server/src/services/user.js +1 -0
  119. package/dist/server/server/src/services/user.js.map +1 -1
  120. package/dist/server/server/src/services/user.mjs +1 -0
  121. package/dist/server/server/src/services/user.mjs.map +1 -1
  122. package/dist/server/shared/utils/auth-cookie-domain.js +41 -0
  123. package/dist/server/shared/utils/auth-cookie-domain.js.map +1 -0
  124. package/dist/server/shared/utils/auth-cookie-domain.mjs +38 -0
  125. package/dist/server/shared/utils/auth-cookie-domain.mjs.map +1 -0
  126. package/dist/server/shared/utils/auth-cookie-name.js +31 -0
  127. package/dist/server/shared/utils/auth-cookie-name.js.map +1 -0
  128. package/dist/server/shared/utils/auth-cookie-name.mjs +28 -0
  129. package/dist/server/shared/utils/auth-cookie-name.mjs.map +1 -0
  130. package/dist/server/shared/utils/auth-cookie-path.js +39 -0
  131. package/dist/server/shared/utils/auth-cookie-path.js.map +1 -0
  132. package/dist/server/shared/utils/auth-cookie-path.mjs +36 -0
  133. package/dist/server/shared/utils/auth-cookie-path.mjs.map +1 -0
  134. package/dist/server/shared/utils/session-auth.js +59 -2
  135. package/dist/server/shared/utils/session-auth.js.map +1 -1
  136. package/dist/server/shared/utils/session-auth.mjs +55 -3
  137. package/dist/server/shared/utils/session-auth.mjs.map +1 -1
  138. package/dist/server/src/content-types/User.d.ts +6 -0
  139. package/dist/server/src/content-types/User.d.ts.map +1 -1
  140. package/dist/server/src/content-types/index.d.ts +6 -0
  141. package/dist/server/src/content-types/index.d.ts.map +1 -1
  142. package/dist/server/src/controllers/admin.d.ts +3 -3
  143. package/dist/server/src/controllers/authentication.d.ts.map +1 -1
  144. package/dist/server/src/controllers/index.d.ts +3 -3
  145. package/dist/server/src/domain/user.d.ts +2 -1
  146. package/dist/server/src/domain/user.d.ts.map +1 -1
  147. package/dist/server/src/index.d.ts +25 -19
  148. package/dist/server/src/index.d.ts.map +1 -1
  149. package/dist/server/src/middlewares/index.d.ts +1 -1
  150. package/dist/server/src/routes/serve-admin-panel.d.ts.map +1 -1
  151. package/dist/server/src/services/auth.d.ts +18 -0
  152. package/dist/server/src/services/auth.d.ts.map +1 -1
  153. package/dist/server/src/services/index.d.ts +13 -13
  154. package/dist/server/src/services/index.d.ts.map +1 -1
  155. package/dist/server/src/services/user.d.ts.map +1 -1
  156. package/dist/shared/contracts/shared.d.ts +2 -1
  157. package/dist/shared/contracts/shared.d.ts.map +1 -1
  158. package/dist/shared/utils/__tests__/auth-cookie-domain.test.d.ts +1 -0
  159. package/dist/shared/utils/__tests__/auth-cookie-domain.test.d.ts.map +1 -0
  160. package/dist/shared/utils/__tests__/auth-cookie-name.test.d.ts +1 -0
  161. package/dist/shared/utils/__tests__/auth-cookie-name.test.d.ts.map +1 -0
  162. package/dist/shared/utils/__tests__/auth-cookie-path.test.d.ts +1 -0
  163. package/dist/shared/utils/__tests__/auth-cookie-path.test.d.ts.map +1 -0
  164. package/dist/shared/utils/__tests__/session-auth.test.d.ts +1 -0
  165. package/dist/shared/utils/__tests__/session-auth.test.d.ts.map +1 -0
  166. package/dist/shared/utils/auth-cookie-domain.d.ts +21 -0
  167. package/dist/shared/utils/auth-cookie-domain.d.ts.map +1 -0
  168. package/dist/shared/utils/auth-cookie-name.d.ts +14 -0
  169. package/dist/shared/utils/auth-cookie-name.d.ts.map +1 -0
  170. package/dist/shared/utils/auth-cookie-path.d.ts +17 -0
  171. package/dist/shared/utils/auth-cookie-path.d.ts.map +1 -0
  172. package/dist/shared/utils/session-auth.d.ts +16 -0
  173. package/dist/shared/utils/session-auth.d.ts.map +1 -1
  174. package/package.json +20 -17
@@ -1 +1 @@
1
- {"version":3,"file":"user.mjs","sources":["../../../../../server/src/services/user.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport _ from 'lodash';\nimport { defaults } from 'lodash/fp';\nimport { arrays, errors } from '@strapi/utils';\nimport type { Data } from '@strapi/types';\nimport { createUser, hasSuperAdminRole } from '../domain/user';\nimport type {\n AdminUser,\n AdminRole,\n AdminUserCreationPayload,\n SanitizedAdminUser,\n SanitizedAdminRole,\n AdminUserUpdatePayload,\n // eslint-disable-next-line node/no-unpublished-import\n} from '../../../shared/contracts/shared';\nimport { password as passwordValidator } from '../validation/common-validators';\nimport { getService } from '../utils';\nimport constants from './constants';\n\nconst { SUPER_ADMIN_CODE } = constants;\n\nconst { ApplicationError, ValidationError } = errors;\nconst sanitizeUserRoles = (role: AdminRole): SanitizedAdminRole =>\n _.pick(role, ['id', 'name', 'description', 'code']);\n\nconst getSessionManager = () => {\n const manager = strapi.sessionManager;\n return manager ?? null;\n};\n\n/**\n * Remove private user fields\n * @param user - user to sanitize\n */\nconst sanitizeUser = (user: AdminUser): SanitizedAdminUser => {\n return {\n ..._.omit(user, ['password', 'resetPasswordToken', 'registrationToken', 'roles']),\n roles: user.roles && user.roles.map(sanitizeUserRoles),\n };\n};\n\n/**\n * Create and save a user in database\n * @param attributes A partial user object\n */\nconst createUserInDatabase = async (\n // isActive is added in the controller, it's not sent by the API.\n attributes: Partial<AdminUserCreationPayload> & { isActive?: true }\n): Promise<AdminUser> => {\n const userInfo = {\n registrationToken: getService('token').createToken(),\n ...attributes,\n };\n\n if (_.has(attributes, 'password')) {\n userInfo.password = await getService('auth').hashPassword(attributes.password!);\n }\n\n const user = createUser(userInfo);\n\n const createdUser = await strapi.db\n .query('admin::user')\n .create({ data: user, populate: ['roles'] });\n\n return createdUser;\n};\n\nconst emitUserCreated = (user: AdminUser) => {\n getService('metrics').sendDidInviteUser();\n\n strapi.eventHub.emit('user.create', { user: sanitizeUser(user) });\n};\n\nconst create = async (\n // isActive is added in the controller, it's not sent by the API.\n attributes: Partial<AdminUserCreationPayload> & { isActive?: true }\n): Promise<AdminUser> => {\n const createdUser = await createUserInDatabase(attributes);\n\n emitUserCreated(createdUser);\n\n return createdUser;\n};\n\nconst createFirstAdmin = async (\n attributes: Omit<Partial<AdminUserCreationPayload>, 'registrationToken' | 'isActive' | 'roles'>\n): Promise<AdminUser> => {\n const createdUser = await strapi.db.transaction(async ({ trx }) => {\n // Serialize first-admin creation across processes by locking a stable role row.\n // SQLite ignores FOR UPDATE, but falls back to its single-writer transaction behavior.\n const superAdminRole = await strapi.db\n .queryBuilder('admin::role')\n .select(['id'])\n .where({ code: SUPER_ADMIN_CODE })\n .first()\n .transacting(trx)\n .forUpdate()\n .execute<AdminRole | undefined>();\n\n if (!superAdminRole) {\n throw new ApplicationError(\n \"Cannot register the first admin because the super admin role doesn't exist.\"\n );\n }\n\n const hasAdmin = await exists();\n\n if (hasAdmin) {\n throw new ApplicationError('You cannot register a new super admin');\n }\n\n return createUserInDatabase({\n ...attributes,\n registrationToken: null,\n isActive: true,\n roles: [superAdminRole.id],\n });\n });\n\n emitUserCreated(createdUser);\n\n return createdUser;\n};\n\n/**\n * Update a user in database\n * @param id query params to find the user to update\n * @param attributes A partial user object\n */\nconst updateById = async (\n id: Data.ID,\n attributes: Partial<AdminUserUpdatePayload>\n): Promise<AdminUser> => {\n // Check at least one super admin remains\n if (_.has(attributes, 'roles')) {\n const lastAdminUser = await isLastSuperAdminUser(id);\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n const willRemoveSuperAdminRole = !arrays.includesString(attributes.roles!, superAdminRole.id);\n\n if (lastAdminUser && willRemoveSuperAdminRole) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n\n // cannot disable last super admin\n if (attributes.isActive === false) {\n const lastAdminUser = await isLastSuperAdminUser(id);\n if (lastAdminUser) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n\n // hash password if a new one is sent\n if (_.has(attributes, 'password')) {\n const hashedPassword = await getService('auth').hashPassword(attributes.password!);\n\n const updatedUser = await strapi.db.query('admin::user').update({\n where: { id },\n data: {\n ...attributes,\n password: hashedPassword,\n },\n populate: ['roles'],\n });\n\n strapi.eventHub.emit('user.update', { user: sanitizeUser(updatedUser) });\n\n return updatedUser;\n }\n\n const updatedUser = await strapi.db.query('admin::user').update({\n where: { id },\n data: attributes,\n populate: ['roles'],\n });\n\n if (updatedUser) {\n strapi.eventHub.emit('user.update', { user: sanitizeUser(updatedUser) });\n }\n\n return updatedUser;\n};\n\n/**\n * Reset a user password by email. (Used in admin:reset CLI)\n * @param email - user email\n * @param password - new password\n */\nconst resetPasswordByEmail = async (email: string, password: string) => {\n const user = await strapi.db\n .query('admin::user')\n .findOne({ where: { email }, populate: ['roles'] });\n\n if (!user) {\n throw new Error(`User not found for email: ${email}`);\n }\n\n try {\n await passwordValidator.validate(password);\n } catch (error) {\n throw new ValidationError(\n 'Invalid password. Expected a minimum of 8 characters with at least one number and one uppercase letter'\n );\n }\n\n await updateById(user.id, { password });\n};\n\n/**\n * Check if a user is the last super admin\n * @param userId user's id to look for\n */\nconst isLastSuperAdminUser = async (userId: Data.ID): Promise<boolean> => {\n const user = (await findOne(userId)) as AdminUser | null;\n if (!user) return false;\n\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n\n return superAdminRole.usersCount === 1 && hasSuperAdminRole(user);\n};\n\n/**\n * Check if a user is the first super admin\n * @param userId user's id to look for\n */\nconst isFirstSuperAdminUser = async (userId: Data.ID): Promise<boolean> => {\n const currentUser = (await findOne(userId)) as AdminUser | null;\n\n if (!currentUser || !hasSuperAdminRole(currentUser)) return false;\n\n const [oldestUser] = await strapi.db.query('admin::user').findMany({\n populate: {\n roles: {\n where: {\n code: { $eq: SUPER_ADMIN_CODE },\n },\n },\n },\n orderBy: { createdAt: 'asc' },\n limit: 1,\n select: ['id'],\n });\n\n return oldestUser.id === currentUser.id;\n};\n\n/**\n * Check if a user with specific attributes exists in the database\n * @param attributes A partial user object\n */\nconst exists = async (attributes = {} as unknown): Promise<boolean> => {\n return (await strapi.db.query('admin::user').count({ where: attributes })) > 0;\n};\n\n/**\n * Returns a user registration info\n * @param registrationToken - a user registration token\n * @returns - Returns user email, firstname and lastname\n */\nconst findRegistrationInfo = async (\n registrationToken: string\n): Promise<Pick<AdminUser, 'email' | 'firstname' | 'lastname'> | undefined> => {\n const user = await strapi.db.query('admin::user').findOne({ where: { registrationToken } });\n\n if (!user) {\n return undefined;\n }\n\n return _.pick(user, ['email', 'firstname', 'lastname']);\n};\n\n/**\n * Registers a user based on a registrationToken and some informations to update\n * @param params\n * @param params.registrationToken registration token\n * @param params.userInfo user info\n */\nconst register = async ({\n registrationToken,\n userInfo,\n}: {\n registrationToken: string;\n userInfo: Partial<AdminUser>;\n}) => {\n const matchingUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { registrationToken } });\n\n if (!matchingUser) {\n throw new ValidationError('Invalid registration info');\n }\n\n return getService('user').updateById(matchingUser.id, {\n password: userInfo.password,\n firstname: userInfo.firstname,\n lastname: userInfo.lastname,\n registrationToken: null,\n isActive: true,\n });\n};\n\n/**\n * Find one user\n */\nconst findOne = async (id: Data.ID, populate = ['roles']) => {\n return strapi.db.query('admin::user').findOne({ where: { id }, populate });\n};\n\n/**\n * Find one user by its email\n * @param email\n * @param populate\n * @returns\n */\nconst findOneByEmail = async (email: string, populate = []) => {\n return strapi.db.query('admin::user').findOne({\n where: { email: { $eqi: email } },\n populate,\n });\n};\n\n/** Find many users (paginated)\n * @param params\n */\nconst findPage = async (params = {}): Promise<unknown> => {\n const query = strapi\n .get('query-params')\n .transform('admin::user', defaults({ populate: ['roles'] }, params));\n\n return strapi.db.query('admin::user').findPage(query);\n};\n\n/** Delete a user\n * @param id id of the user to delete\n */\nconst deleteById = async (id: Data.ID): Promise<AdminUser | null> => {\n // Check at least one super admin remains\n const userToDelete: AdminUser | null = await strapi.db.query('admin::user').findOne({\n where: { id },\n populate: ['roles'],\n });\n\n if (!userToDelete) {\n return null;\n }\n\n if (userToDelete) {\n if (userToDelete.roles.some((r) => r.code === SUPER_ADMIN_CODE)) {\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n if (superAdminRole.usersCount === 1) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n }\n\n const deletedUser = await strapi.db\n .query('admin::user')\n .delete({ where: { id }, populate: ['roles'] });\n\n // Invalidate all sessions for the deleted user\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('admin')) {\n await sessionManager('admin').invalidateRefreshToken(String(id));\n }\n\n strapi.eventHub.emit('user.delete', { user: sanitizeUser(deletedUser) });\n\n return deletedUser;\n};\n\n/** Delete a user\n * @param ids ids of the users to delete\n */\nconst deleteByIds = async (ids: (string | number)[]): Promise<AdminUser[]> => {\n // Check at least one super admin remains\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n const nbOfSuperAdminToDelete = await strapi.db.query('admin::user').count({\n where: {\n id: ids,\n roles: { id: superAdminRole.id },\n },\n });\n\n if (superAdminRole.usersCount === nbOfSuperAdminToDelete) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n\n const deletedUsers = [] as AdminUser[];\n for (const id of ids) {\n const deletedUser = await strapi.db.query('admin::user').delete({\n where: { id },\n populate: ['roles'],\n });\n\n // Invalidate all sessions for the deleted user\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('admin')) {\n await sessionManager('admin').invalidateRefreshToken(String(id));\n }\n\n deletedUsers.push(deletedUser);\n }\n\n strapi.eventHub.emit('user.delete', {\n users: deletedUsers.map((deletedUser) => sanitizeUser(deletedUser)),\n });\n\n return deletedUsers;\n};\n\n/** Count the users that don't have any associated roles\n */\nconst countUsersWithoutRole = async (): Promise<number> => {\n return strapi.db.query('admin::user').count({\n where: {\n roles: {\n id: { $null: true },\n },\n },\n });\n};\n\n/**\n * Count the number of users based on search params\n * @param params params used for the query\n */\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::user').count({ where });\n};\n\n/**\n * Assign some roles to several users\n */\nconst assignARoleToAll = async (roleId: Data.ID): Promise<void> => {\n const users = await strapi.db.query('admin::user').findMany({\n select: ['id'],\n where: {\n roles: { id: { $null: true } },\n },\n });\n\n await Promise.all(\n users.map((user) => {\n return strapi.db.query('admin::user').update({\n where: { id: user.id },\n data: { roles: [roleId] },\n });\n })\n );\n};\n\n/** Display a warning if some users don't have at least one role\n */\nconst displayWarningIfUsersDontHaveRole = async (): Promise<void> => {\n const count = await countUsersWithoutRole();\n\n if (count > 0) {\n strapi.log.warn(`Some users (${count}) don't have any role.`);\n }\n};\n\n/** Returns an array of interface languages currently used by users\n */\nconst getLanguagesInUse = async (): Promise<string[]> => {\n const users = await strapi.db.query('admin::user').findMany({ select: ['preferedLanguage'] });\n\n return users.map((user) => user.preferedLanguage || 'en');\n};\nexport default {\n create,\n createFirstAdmin,\n updateById,\n exists,\n findRegistrationInfo,\n register,\n sanitizeUser,\n findOne,\n findOneByEmail,\n findPage,\n deleteById,\n deleteByIds,\n countUsersWithoutRole,\n count,\n assignARoleToAll,\n displayWarningIfUsersDontHaveRole,\n resetPasswordByEmail,\n getLanguagesInUse,\n isFirstSuperAdminUser,\n};\n"],"names":["SUPER_ADMIN_CODE","constants","ApplicationError","ValidationError","errors","sanitizeUserRoles","role","_","pick","getSessionManager","manager","strapi","sessionManager","sanitizeUser","user","omit","roles","map","createUserInDatabase","attributes","userInfo","registrationToken","getService","createToken","has","password","hashPassword","createUser","createdUser","db","query","create","data","populate","emitUserCreated","sendDidInviteUser","eventHub","emit","createFirstAdmin","transaction","trx","superAdminRole","queryBuilder","select","where","code","first","transacting","forUpdate","execute","hasAdmin","exists","isActive","id","updateById","lastAdminUser","isLastSuperAdminUser","getSuperAdminWithUsersCount","willRemoveSuperAdminRole","arrays","includesString","hashedPassword","updatedUser","update","resetPasswordByEmail","email","findOne","Error","passwordValidator","validate","error","userId","usersCount","hasSuperAdminRole","isFirstSuperAdminUser","currentUser","oldestUser","findMany","$eq","orderBy","createdAt","limit","count","findRegistrationInfo","undefined","register","matchingUser","firstname","lastname","findOneByEmail","$eqi","findPage","params","get","transform","defaults","deleteById","userToDelete","some","r","deletedUser","delete","hasOrigin","invalidateRefreshToken","String","deleteByIds","ids","nbOfSuperAdminToDelete","deletedUsers","push","users","countUsersWithoutRole","$null","assignARoleToAll","roleId","Promise","all","displayWarningIfUsersDontHaveRole","log","warn","getLanguagesInUse","preferedLanguage"],"mappings":"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"}
1
+ {"version":3,"file":"user.mjs","sources":["../../../../../server/src/services/user.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport _ from 'lodash';\nimport { defaults } from 'lodash/fp';\nimport { arrays, errors } from '@strapi/utils';\nimport type { Data } from '@strapi/types';\nimport { createUser, hasSuperAdminRole } from '../domain/user';\nimport type {\n AdminUser,\n AdminRole,\n AdminUserCreationPayload,\n SanitizedAdminUser,\n SanitizedAdminRole,\n AdminUserUpdatePayload,\n // eslint-disable-next-line node/no-unpublished-import\n} from '../../../shared/contracts/shared';\nimport { password as passwordValidator } from '../validation/common-validators';\nimport { getService } from '../utils';\nimport constants from './constants';\n\nconst { SUPER_ADMIN_CODE } = constants;\n\nconst { ApplicationError, ValidationError } = errors;\nconst sanitizeUserRoles = (role: AdminRole): SanitizedAdminRole =>\n _.pick(role, ['id', 'name', 'description', 'code']);\n\nconst getSessionManager = () => {\n const manager = strapi.sessionManager;\n return manager ?? null;\n};\n\n/**\n * Remove private user fields\n * @param user - user to sanitize\n */\nconst sanitizeUser = (user: AdminUser): SanitizedAdminUser => {\n return {\n ..._.omit(user, [\n 'password',\n 'resetPasswordToken',\n 'resetPasswordTokenExpiresAt',\n 'registrationToken',\n 'roles',\n ]),\n roles: user.roles && user.roles.map(sanitizeUserRoles),\n };\n};\n\n/**\n * Create and save a user in database\n * @param attributes A partial user object\n */\nconst createUserInDatabase = async (\n // isActive is added in the controller, it's not sent by the API.\n attributes: Partial<AdminUserCreationPayload> & { isActive?: true }\n): Promise<AdminUser> => {\n const userInfo = {\n registrationToken: getService('token').createToken(),\n ...attributes,\n };\n\n if (_.has(attributes, 'password')) {\n userInfo.password = await getService('auth').hashPassword(attributes.password!);\n }\n\n const user = createUser(userInfo);\n\n const createdUser = await strapi.db\n .query('admin::user')\n .create({ data: user, populate: ['roles'] });\n\n return createdUser;\n};\n\nconst emitUserCreated = (user: AdminUser) => {\n getService('metrics').sendDidInviteUser();\n\n strapi.eventHub.emit('user.create', { user: sanitizeUser(user) });\n};\n\nconst create = async (\n // isActive is added in the controller, it's not sent by the API.\n attributes: Partial<AdminUserCreationPayload> & { isActive?: true }\n): Promise<AdminUser> => {\n const createdUser = await createUserInDatabase(attributes);\n\n emitUserCreated(createdUser);\n\n return createdUser;\n};\n\nconst createFirstAdmin = async (\n attributes: Omit<Partial<AdminUserCreationPayload>, 'registrationToken' | 'isActive' | 'roles'>\n): Promise<AdminUser> => {\n const createdUser = await strapi.db.transaction(async ({ trx }) => {\n // Serialize first-admin creation across processes by locking a stable role row.\n // SQLite ignores FOR UPDATE, but falls back to its single-writer transaction behavior.\n const superAdminRole = await strapi.db\n .queryBuilder('admin::role')\n .select(['id'])\n .where({ code: SUPER_ADMIN_CODE })\n .first()\n .transacting(trx)\n .forUpdate()\n .execute<AdminRole | undefined>();\n\n if (!superAdminRole) {\n throw new ApplicationError(\n \"Cannot register the first admin because the super admin role doesn't exist.\"\n );\n }\n\n const hasAdmin = await exists();\n\n if (hasAdmin) {\n throw new ApplicationError('You cannot register a new super admin');\n }\n\n return createUserInDatabase({\n ...attributes,\n registrationToken: null,\n isActive: true,\n roles: [superAdminRole.id],\n });\n });\n\n emitUserCreated(createdUser);\n\n return createdUser;\n};\n\n/**\n * Update a user in database\n * @param id query params to find the user to update\n * @param attributes A partial user object\n */\nconst updateById = async (\n id: Data.ID,\n attributes: Partial<AdminUserUpdatePayload>\n): Promise<AdminUser> => {\n // Check at least one super admin remains\n if (_.has(attributes, 'roles')) {\n const lastAdminUser = await isLastSuperAdminUser(id);\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n const willRemoveSuperAdminRole = !arrays.includesString(attributes.roles!, superAdminRole.id);\n\n if (lastAdminUser && willRemoveSuperAdminRole) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n\n // cannot disable last super admin\n if (attributes.isActive === false) {\n const lastAdminUser = await isLastSuperAdminUser(id);\n if (lastAdminUser) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n\n // hash password if a new one is sent\n if (_.has(attributes, 'password')) {\n const hashedPassword = await getService('auth').hashPassword(attributes.password!);\n\n const updatedUser = await strapi.db.query('admin::user').update({\n where: { id },\n data: {\n ...attributes,\n password: hashedPassword,\n },\n populate: ['roles'],\n });\n\n strapi.eventHub.emit('user.update', { user: sanitizeUser(updatedUser) });\n\n return updatedUser;\n }\n\n const updatedUser = await strapi.db.query('admin::user').update({\n where: { id },\n data: attributes,\n populate: ['roles'],\n });\n\n if (updatedUser) {\n strapi.eventHub.emit('user.update', { user: sanitizeUser(updatedUser) });\n }\n\n return updatedUser;\n};\n\n/**\n * Reset a user password by email. (Used in admin:reset CLI)\n * @param email - user email\n * @param password - new password\n */\nconst resetPasswordByEmail = async (email: string, password: string) => {\n const user = await strapi.db\n .query('admin::user')\n .findOne({ where: { email }, populate: ['roles'] });\n\n if (!user) {\n throw new Error(`User not found for email: ${email}`);\n }\n\n try {\n await passwordValidator.validate(password);\n } catch (error) {\n throw new ValidationError(\n 'Invalid password. Expected a minimum of 8 characters with at least one number and one uppercase letter'\n );\n }\n\n await updateById(user.id, { password });\n};\n\n/**\n * Check if a user is the last super admin\n * @param userId user's id to look for\n */\nconst isLastSuperAdminUser = async (userId: Data.ID): Promise<boolean> => {\n const user = (await findOne(userId)) as AdminUser | null;\n if (!user) return false;\n\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n\n return superAdminRole.usersCount === 1 && hasSuperAdminRole(user);\n};\n\n/**\n * Check if a user is the first super admin\n * @param userId user's id to look for\n */\nconst isFirstSuperAdminUser = async (userId: Data.ID): Promise<boolean> => {\n const currentUser = (await findOne(userId)) as AdminUser | null;\n\n if (!currentUser || !hasSuperAdminRole(currentUser)) return false;\n\n const [oldestUser] = await strapi.db.query('admin::user').findMany({\n populate: {\n roles: {\n where: {\n code: { $eq: SUPER_ADMIN_CODE },\n },\n },\n },\n orderBy: { createdAt: 'asc' },\n limit: 1,\n select: ['id'],\n });\n\n return oldestUser.id === currentUser.id;\n};\n\n/**\n * Check if a user with specific attributes exists in the database\n * @param attributes A partial user object\n */\nconst exists = async (attributes = {} as unknown): Promise<boolean> => {\n return (await strapi.db.query('admin::user').count({ where: attributes })) > 0;\n};\n\n/**\n * Returns a user registration info\n * @param registrationToken - a user registration token\n * @returns - Returns user email, firstname and lastname\n */\nconst findRegistrationInfo = async (\n registrationToken: string\n): Promise<Pick<AdminUser, 'email' | 'firstname' | 'lastname'> | undefined> => {\n const user = await strapi.db.query('admin::user').findOne({ where: { registrationToken } });\n\n if (!user) {\n return undefined;\n }\n\n return _.pick(user, ['email', 'firstname', 'lastname']);\n};\n\n/**\n * Registers a user based on a registrationToken and some informations to update\n * @param params\n * @param params.registrationToken registration token\n * @param params.userInfo user info\n */\nconst register = async ({\n registrationToken,\n userInfo,\n}: {\n registrationToken: string;\n userInfo: Partial<AdminUser>;\n}) => {\n const matchingUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { registrationToken } });\n\n if (!matchingUser) {\n throw new ValidationError('Invalid registration info');\n }\n\n return getService('user').updateById(matchingUser.id, {\n password: userInfo.password,\n firstname: userInfo.firstname,\n lastname: userInfo.lastname,\n registrationToken: null,\n isActive: true,\n });\n};\n\n/**\n * Find one user\n */\nconst findOne = async (id: Data.ID, populate = ['roles']) => {\n return strapi.db.query('admin::user').findOne({ where: { id }, populate });\n};\n\n/**\n * Find one user by its email\n * @param email\n * @param populate\n * @returns\n */\nconst findOneByEmail = async (email: string, populate = []) => {\n return strapi.db.query('admin::user').findOne({\n where: { email: { $eqi: email } },\n populate,\n });\n};\n\n/** Find many users (paginated)\n * @param params\n */\nconst findPage = async (params = {}): Promise<unknown> => {\n const query = strapi\n .get('query-params')\n .transform('admin::user', defaults({ populate: ['roles'] }, params));\n\n return strapi.db.query('admin::user').findPage(query);\n};\n\n/** Delete a user\n * @param id id of the user to delete\n */\nconst deleteById = async (id: Data.ID): Promise<AdminUser | null> => {\n // Check at least one super admin remains\n const userToDelete: AdminUser | null = await strapi.db.query('admin::user').findOne({\n where: { id },\n populate: ['roles'],\n });\n\n if (!userToDelete) {\n return null;\n }\n\n if (userToDelete) {\n if (userToDelete.roles.some((r) => r.code === SUPER_ADMIN_CODE)) {\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n if (superAdminRole.usersCount === 1) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n }\n\n const deletedUser = await strapi.db\n .query('admin::user')\n .delete({ where: { id }, populate: ['roles'] });\n\n // Invalidate all sessions for the deleted user\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('admin')) {\n await sessionManager('admin').invalidateRefreshToken(String(id));\n }\n\n strapi.eventHub.emit('user.delete', { user: sanitizeUser(deletedUser) });\n\n return deletedUser;\n};\n\n/** Delete a user\n * @param ids ids of the users to delete\n */\nconst deleteByIds = async (ids: (string | number)[]): Promise<AdminUser[]> => {\n // Check at least one super admin remains\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n const nbOfSuperAdminToDelete = await strapi.db.query('admin::user').count({\n where: {\n id: ids,\n roles: { id: superAdminRole.id },\n },\n });\n\n if (superAdminRole.usersCount === nbOfSuperAdminToDelete) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n\n const deletedUsers = [] as AdminUser[];\n for (const id of ids) {\n const deletedUser = await strapi.db.query('admin::user').delete({\n where: { id },\n populate: ['roles'],\n });\n\n // Invalidate all sessions for the deleted user\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('admin')) {\n await sessionManager('admin').invalidateRefreshToken(String(id));\n }\n\n deletedUsers.push(deletedUser);\n }\n\n strapi.eventHub.emit('user.delete', {\n users: deletedUsers.map((deletedUser) => sanitizeUser(deletedUser)),\n });\n\n return deletedUsers;\n};\n\n/** Count the users that don't have any associated roles\n */\nconst countUsersWithoutRole = async (): Promise<number> => {\n return strapi.db.query('admin::user').count({\n where: {\n roles: {\n id: { $null: true },\n },\n },\n });\n};\n\n/**\n * Count the number of users based on search params\n * @param params params used for the query\n */\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::user').count({ where });\n};\n\n/**\n * Assign some roles to several users\n */\nconst assignARoleToAll = async (roleId: Data.ID): Promise<void> => {\n const users = await strapi.db.query('admin::user').findMany({\n select: ['id'],\n where: {\n roles: { id: { $null: true } },\n },\n });\n\n await Promise.all(\n users.map((user) => {\n return strapi.db.query('admin::user').update({\n where: { id: user.id },\n data: { roles: [roleId] },\n });\n })\n );\n};\n\n/** Display a warning if some users don't have at least one role\n */\nconst displayWarningIfUsersDontHaveRole = async (): Promise<void> => {\n const count = await countUsersWithoutRole();\n\n if (count > 0) {\n strapi.log.warn(`Some users (${count}) don't have any role.`);\n }\n};\n\n/** Returns an array of interface languages currently used by users\n */\nconst getLanguagesInUse = async (): Promise<string[]> => {\n const users = await strapi.db.query('admin::user').findMany({ select: ['preferedLanguage'] });\n\n return users.map((user) => user.preferedLanguage || 'en');\n};\nexport default {\n create,\n createFirstAdmin,\n updateById,\n exists,\n findRegistrationInfo,\n register,\n sanitizeUser,\n findOne,\n findOneByEmail,\n findPage,\n deleteById,\n deleteByIds,\n countUsersWithoutRole,\n count,\n assignARoleToAll,\n displayWarningIfUsersDontHaveRole,\n resetPasswordByEmail,\n getLanguagesInUse,\n isFirstSuperAdminUser,\n};\n"],"names":["SUPER_ADMIN_CODE","constants","ApplicationError","ValidationError","errors","sanitizeUserRoles","role","_","pick","getSessionManager","manager","strapi","sessionManager","sanitizeUser","user","omit","roles","map","createUserInDatabase","attributes","userInfo","registrationToken","getService","createToken","has","password","hashPassword","createUser","createdUser","db","query","create","data","populate","emitUserCreated","sendDidInviteUser","eventHub","emit","createFirstAdmin","transaction","trx","superAdminRole","queryBuilder","select","where","code","first","transacting","forUpdate","execute","hasAdmin","exists","isActive","id","updateById","lastAdminUser","isLastSuperAdminUser","getSuperAdminWithUsersCount","willRemoveSuperAdminRole","arrays","includesString","hashedPassword","updatedUser","update","resetPasswordByEmail","email","findOne","Error","passwordValidator","validate","error","userId","usersCount","hasSuperAdminRole","isFirstSuperAdminUser","currentUser","oldestUser","findMany","$eq","orderBy","createdAt","limit","count","findRegistrationInfo","undefined","register","matchingUser","firstname","lastname","findOneByEmail","$eqi","findPage","params","get","transform","defaults","deleteById","userToDelete","some","r","deletedUser","delete","hasOrigin","invalidateRefreshToken","String","deleteByIds","ids","nbOfSuperAdminToDelete","deletedUsers","push","users","countUsersWithoutRole","$null","assignARoleToAll","roleId","Promise","all","displayWarningIfUsersDontHaveRole","log","warn","getLanguagesInUse","preferedLanguage"],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Domain attribute of the admin auth (access) token cookie, configurable
5
+ * through `admin.auth.cookie.domain` (falling back to `admin.auth.domain`) so
6
+ * multiple Strapi instances under the same parent domain share, or stay
7
+ * isolated to, the intended host.
8
+ *
9
+ * Browser-safe single source for both sides of the handoff: the admin panel
10
+ * cannot read server config, so the build transports the config value into
11
+ * the bundle through the internal `STRAPI_ADMIN_AUTH_COOKIE_DOMAIN` variable
12
+ * (see create-build-context.ts in @strapi/strapi); the server resolves the
13
+ * same config at runtime. Changing the domain requires an admin rebuild, like
14
+ * any other admin config change.
15
+ *
16
+ * Defaults to `undefined` (host-only cookie) to match the browser default and
17
+ * the refresh-cookie behaviour in `getRefreshCookieOptions` when no domain is
18
+ * configured. A host-only cookie and a `Domain`-scoped cookie are distinct
19
+ * entries in the browser cookie store, so set and delete must agree on the
20
+ * domain or logout leaves a colliding copy behind.
21
+ */ const DEFAULT_AUTH_COOKIE_DOMAIN = undefined;
22
+ const isValidCookieDomain = (domain)=>{
23
+ // RFC 6265 domain-av: a host name. No leading dot required, no scheme, no
24
+ // path, no port, and none of the control/attribute-separator characters.
25
+ return !/[\x00-\x1F\x7F;,\s/:]/.test(domain);
26
+ };
27
+ const resolveAuthCookieDomain = (configuredDomain, warn = console.warn)=>{
28
+ const cookieDomain = (configuredDomain || '').trim();
29
+ if (!cookieDomain) {
30
+ return DEFAULT_AUTH_COOKIE_DOMAIN;
31
+ }
32
+ if (!isValidCookieDomain(cookieDomain)) {
33
+ warn(`Ignoring invalid admin auth cookie domain "${cookieDomain}" (must be a bare host name); using a host-only cookie instead.`);
34
+ return DEFAULT_AUTH_COOKIE_DOMAIN;
35
+ }
36
+ return cookieDomain;
37
+ };
38
+
39
+ exports.DEFAULT_AUTH_COOKIE_DOMAIN = DEFAULT_AUTH_COOKIE_DOMAIN;
40
+ exports.resolveAuthCookieDomain = resolveAuthCookieDomain;
41
+ //# sourceMappingURL=auth-cookie-domain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-cookie-domain.js","sources":["../../../../shared/utils/auth-cookie-domain.ts"],"sourcesContent":["/**\n * Domain attribute of the admin auth (access) token cookie, configurable\n * through `admin.auth.cookie.domain` (falling back to `admin.auth.domain`) so\n * multiple Strapi instances under the same parent domain share, or stay\n * isolated to, the intended host.\n *\n * Browser-safe single source for both sides of the handoff: the admin panel\n * cannot read server config, so the build transports the config value into\n * the bundle through the internal `STRAPI_ADMIN_AUTH_COOKIE_DOMAIN` variable\n * (see create-build-context.ts in @strapi/strapi); the server resolves the\n * same config at runtime. Changing the domain requires an admin rebuild, like\n * any other admin config change.\n *\n * Defaults to `undefined` (host-only cookie) to match the browser default and\n * the refresh-cookie behaviour in `getRefreshCookieOptions` when no domain is\n * configured. A host-only cookie and a `Domain`-scoped cookie are distinct\n * entries in the browser cookie store, so set and delete must agree on the\n * domain or logout leaves a colliding copy behind.\n */\nexport const DEFAULT_AUTH_COOKIE_DOMAIN = undefined;\n\nconst isValidCookieDomain = (domain: string): boolean => {\n // RFC 6265 domain-av: a host name. No leading dot required, no scheme, no\n // path, no port, and none of the control/attribute-separator characters.\n return !/[\\x00-\\x1F\\x7F;,\\s/:]/.test(domain);\n};\n\nexport const resolveAuthCookieDomain = (\n configuredDomain?: string,\n warn: (message: string) => void = console.warn\n): string | undefined => {\n const cookieDomain = (configuredDomain || '').trim();\n\n if (!cookieDomain) {\n return DEFAULT_AUTH_COOKIE_DOMAIN;\n }\n\n if (!isValidCookieDomain(cookieDomain)) {\n warn(\n `Ignoring invalid admin auth cookie domain \"${cookieDomain}\" (must be a bare host name); using a host-only cookie instead.`\n );\n return DEFAULT_AUTH_COOKIE_DOMAIN;\n }\n\n return cookieDomain;\n};\n"],"names":["DEFAULT_AUTH_COOKIE_DOMAIN","undefined","isValidCookieDomain","domain","test","resolveAuthCookieDomain","configuredDomain","warn","console","cookieDomain","trim"],"mappings":";;AAAA;;;;;;;;;;;;;;;;;;IAmBO,MAAMA,0BAAAA,GAA6BC;AAE1C,MAAMC,sBAAsB,CAACC,MAAAA,GAAAA;;;IAG3B,OAAO,CAAC,uBAAA,CAAwBC,IAAI,CAACD,MAAAA,CAAAA;AACvC,CAAA;MAEaE,uBAAAA,GAA0B,CACrCC,gBAAAA,EACAC,IAAAA,GAAkCC,QAAQD,IAAI,GAAA;AAE9C,IAAA,MAAME,eAAe,CAACH,gBAAAA,IAAoB,EAAC,EAAGI,IAAI,EAAA;AAElD,IAAA,IAAI,CAACD,YAAAA,EAAc;QACjB,OAAOT,0BAAAA;AACT,IAAA;IAEA,IAAI,CAACE,oBAAoBO,YAAAA,CAAAA,EAAe;AACtCF,QAAAA,IAAAA,CACE,CAAC,2CAA2C,EAAEE,YAAAA,CAAa,+DAA+D,CAAC,CAAA;QAE7H,OAAOT,0BAAAA;AACT,IAAA;IAEA,OAAOS,YAAAA;AACT;;;;;"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Domain attribute of the admin auth (access) token cookie, configurable
3
+ * through `admin.auth.cookie.domain` (falling back to `admin.auth.domain`) so
4
+ * multiple Strapi instances under the same parent domain share, or stay
5
+ * isolated to, the intended host.
6
+ *
7
+ * Browser-safe single source for both sides of the handoff: the admin panel
8
+ * cannot read server config, so the build transports the config value into
9
+ * the bundle through the internal `STRAPI_ADMIN_AUTH_COOKIE_DOMAIN` variable
10
+ * (see create-build-context.ts in @strapi/strapi); the server resolves the
11
+ * same config at runtime. Changing the domain requires an admin rebuild, like
12
+ * any other admin config change.
13
+ *
14
+ * Defaults to `undefined` (host-only cookie) to match the browser default and
15
+ * the refresh-cookie behaviour in `getRefreshCookieOptions` when no domain is
16
+ * configured. A host-only cookie and a `Domain`-scoped cookie are distinct
17
+ * entries in the browser cookie store, so set and delete must agree on the
18
+ * domain or logout leaves a colliding copy behind.
19
+ */ const DEFAULT_AUTH_COOKIE_DOMAIN = undefined;
20
+ const isValidCookieDomain = (domain)=>{
21
+ // RFC 6265 domain-av: a host name. No leading dot required, no scheme, no
22
+ // path, no port, and none of the control/attribute-separator characters.
23
+ return !/[\x00-\x1F\x7F;,\s/:]/.test(domain);
24
+ };
25
+ const resolveAuthCookieDomain = (configuredDomain, warn = console.warn)=>{
26
+ const cookieDomain = (configuredDomain || '').trim();
27
+ if (!cookieDomain) {
28
+ return DEFAULT_AUTH_COOKIE_DOMAIN;
29
+ }
30
+ if (!isValidCookieDomain(cookieDomain)) {
31
+ warn(`Ignoring invalid admin auth cookie domain "${cookieDomain}" (must be a bare host name); using a host-only cookie instead.`);
32
+ return DEFAULT_AUTH_COOKIE_DOMAIN;
33
+ }
34
+ return cookieDomain;
35
+ };
36
+
37
+ export { DEFAULT_AUTH_COOKIE_DOMAIN, resolveAuthCookieDomain };
38
+ //# sourceMappingURL=auth-cookie-domain.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-cookie-domain.mjs","sources":["../../../../shared/utils/auth-cookie-domain.ts"],"sourcesContent":["/**\n * Domain attribute of the admin auth (access) token cookie, configurable\n * through `admin.auth.cookie.domain` (falling back to `admin.auth.domain`) so\n * multiple Strapi instances under the same parent domain share, or stay\n * isolated to, the intended host.\n *\n * Browser-safe single source for both sides of the handoff: the admin panel\n * cannot read server config, so the build transports the config value into\n * the bundle through the internal `STRAPI_ADMIN_AUTH_COOKIE_DOMAIN` variable\n * (see create-build-context.ts in @strapi/strapi); the server resolves the\n * same config at runtime. Changing the domain requires an admin rebuild, like\n * any other admin config change.\n *\n * Defaults to `undefined` (host-only cookie) to match the browser default and\n * the refresh-cookie behaviour in `getRefreshCookieOptions` when no domain is\n * configured. A host-only cookie and a `Domain`-scoped cookie are distinct\n * entries in the browser cookie store, so set and delete must agree on the\n * domain or logout leaves a colliding copy behind.\n */\nexport const DEFAULT_AUTH_COOKIE_DOMAIN = undefined;\n\nconst isValidCookieDomain = (domain: string): boolean => {\n // RFC 6265 domain-av: a host name. No leading dot required, no scheme, no\n // path, no port, and none of the control/attribute-separator characters.\n return !/[\\x00-\\x1F\\x7F;,\\s/:]/.test(domain);\n};\n\nexport const resolveAuthCookieDomain = (\n configuredDomain?: string,\n warn: (message: string) => void = console.warn\n): string | undefined => {\n const cookieDomain = (configuredDomain || '').trim();\n\n if (!cookieDomain) {\n return DEFAULT_AUTH_COOKIE_DOMAIN;\n }\n\n if (!isValidCookieDomain(cookieDomain)) {\n warn(\n `Ignoring invalid admin auth cookie domain \"${cookieDomain}\" (must be a bare host name); using a host-only cookie instead.`\n );\n return DEFAULT_AUTH_COOKIE_DOMAIN;\n }\n\n return cookieDomain;\n};\n"],"names":["DEFAULT_AUTH_COOKIE_DOMAIN","undefined","isValidCookieDomain","domain","test","resolveAuthCookieDomain","configuredDomain","warn","console","cookieDomain","trim"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;IAmBO,MAAMA,0BAAAA,GAA6BC;AAE1C,MAAMC,sBAAsB,CAACC,MAAAA,GAAAA;;;IAG3B,OAAO,CAAC,uBAAA,CAAwBC,IAAI,CAACD,MAAAA,CAAAA;AACvC,CAAA;MAEaE,uBAAAA,GAA0B,CACrCC,gBAAAA,EACAC,IAAAA,GAAkCC,QAAQD,IAAI,GAAA;AAE9C,IAAA,MAAME,eAAe,CAACH,gBAAAA,IAAoB,EAAC,EAAGI,IAAI,EAAA;AAElD,IAAA,IAAI,CAACD,YAAAA,EAAc;QACjB,OAAOT,0BAAAA;AACT,IAAA;IAEA,IAAI,CAACE,oBAAoBO,YAAAA,CAAAA,EAAe;AACtCF,QAAAA,IAAAA,CACE,CAAC,2CAA2C,EAAEE,YAAAA,CAAa,+DAA+D,CAAC,CAAA;QAE7H,OAAOT,0BAAAA;AACT,IAAA;IAEA,OAAOS,YAAAA;AACT;;;;"}
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Name of the cookie holding the admin auth (access) token, configurable
5
+ * through `admin.auth.cookie.name` so it cannot collide with a same-named
6
+ * cookie set by another application on a shared parent domain.
7
+ *
8
+ * Browser-safe single source for both sides of the SSO handoff: the admin
9
+ * panel cannot read server config, so the build transports the config value
10
+ * into the bundle through the internal `STRAPI_ADMIN_AUTH_COOKIE_NAME`
11
+ * variable (see create-build-context.ts in @strapi/strapi); the server
12
+ * resolves the same config at runtime. Renaming the cookie requires an admin
13
+ * rebuild, like any other admin config change.
14
+ */ const DEFAULT_AUTH_COOKIE_NAME = 'jwtToken';
15
+ // RFC 6265 cookie-name token characters.
16
+ const VALID_COOKIE_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
17
+ const resolveAuthCookieName = (configuredName, warn = console.warn)=>{
18
+ const cookieName = (configuredName || '').trim();
19
+ if (!cookieName) {
20
+ return DEFAULT_AUTH_COOKIE_NAME;
21
+ }
22
+ if (!VALID_COOKIE_NAME.test(cookieName)) {
23
+ warn(`Ignoring invalid admin auth cookie name "${cookieName}" (must only contain RFC 6265 cookie-name characters); using "${DEFAULT_AUTH_COOKIE_NAME}" instead.`);
24
+ return DEFAULT_AUTH_COOKIE_NAME;
25
+ }
26
+ return cookieName;
27
+ };
28
+
29
+ exports.DEFAULT_AUTH_COOKIE_NAME = DEFAULT_AUTH_COOKIE_NAME;
30
+ exports.resolveAuthCookieName = resolveAuthCookieName;
31
+ //# sourceMappingURL=auth-cookie-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-cookie-name.js","sources":["../../../../shared/utils/auth-cookie-name.ts"],"sourcesContent":["/**\n * Name of the cookie holding the admin auth (access) token, configurable\n * through `admin.auth.cookie.name` so it cannot collide with a same-named\n * cookie set by another application on a shared parent domain.\n *\n * Browser-safe single source for both sides of the SSO handoff: the admin\n * panel cannot read server config, so the build transports the config value\n * into the bundle through the internal `STRAPI_ADMIN_AUTH_COOKIE_NAME`\n * variable (see create-build-context.ts in @strapi/strapi); the server\n * resolves the same config at runtime. Renaming the cookie requires an admin\n * rebuild, like any other admin config change.\n */\nexport const DEFAULT_AUTH_COOKIE_NAME = 'jwtToken';\n\n// RFC 6265 cookie-name token characters.\nconst VALID_COOKIE_NAME = /^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$/;\n\nexport const resolveAuthCookieName = (\n configuredName?: string,\n warn: (message: string) => void = console.warn\n): string => {\n const cookieName = (configuredName || '').trim();\n\n if (!cookieName) {\n return DEFAULT_AUTH_COOKIE_NAME;\n }\n\n if (!VALID_COOKIE_NAME.test(cookieName)) {\n warn(\n `Ignoring invalid admin auth cookie name \"${cookieName}\" (must only contain RFC 6265 cookie-name characters); using \"${DEFAULT_AUTH_COOKIE_NAME}\" instead.`\n );\n return DEFAULT_AUTH_COOKIE_NAME;\n }\n\n return cookieName;\n};\n"],"names":["DEFAULT_AUTH_COOKIE_NAME","VALID_COOKIE_NAME","resolveAuthCookieName","configuredName","warn","console","cookieName","trim","test"],"mappings":";;AAAA;;;;;;;;;;;IAYO,MAAMA,wBAAAA,GAA2B;AAExC;AACA,MAAMC,iBAAAA,GAAoB,gCAAA;MAEbC,qBAAAA,GAAwB,CACnCC,cAAAA,EACAC,IAAAA,GAAkCC,QAAQD,IAAI,GAAA;AAE9C,IAAA,MAAME,aAAa,CAACH,cAAAA,IAAkB,EAAC,EAAGI,IAAI,EAAA;AAE9C,IAAA,IAAI,CAACD,UAAAA,EAAY;QACf,OAAON,wBAAAA;AACT,IAAA;AAEA,IAAA,IAAI,CAACC,iBAAAA,CAAkBO,IAAI,CAACF,UAAAA,CAAAA,EAAa;QACvCF,IAAAA,CACE,CAAC,yCAAyC,EAAEE,UAAAA,CAAW,8DAA8D,EAAEN,wBAAAA,CAAyB,UAAU,CAAC,CAAA;QAE7J,OAAOA,wBAAAA;AACT,IAAA;IAEA,OAAOM,UAAAA;AACT;;;;;"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Name of the cookie holding the admin auth (access) token, configurable
3
+ * through `admin.auth.cookie.name` so it cannot collide with a same-named
4
+ * cookie set by another application on a shared parent domain.
5
+ *
6
+ * Browser-safe single source for both sides of the SSO handoff: the admin
7
+ * panel cannot read server config, so the build transports the config value
8
+ * into the bundle through the internal `STRAPI_ADMIN_AUTH_COOKIE_NAME`
9
+ * variable (see create-build-context.ts in @strapi/strapi); the server
10
+ * resolves the same config at runtime. Renaming the cookie requires an admin
11
+ * rebuild, like any other admin config change.
12
+ */ const DEFAULT_AUTH_COOKIE_NAME = 'jwtToken';
13
+ // RFC 6265 cookie-name token characters.
14
+ const VALID_COOKIE_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
15
+ const resolveAuthCookieName = (configuredName, warn = console.warn)=>{
16
+ const cookieName = (configuredName || '').trim();
17
+ if (!cookieName) {
18
+ return DEFAULT_AUTH_COOKIE_NAME;
19
+ }
20
+ if (!VALID_COOKIE_NAME.test(cookieName)) {
21
+ warn(`Ignoring invalid admin auth cookie name "${cookieName}" (must only contain RFC 6265 cookie-name characters); using "${DEFAULT_AUTH_COOKIE_NAME}" instead.`);
22
+ return DEFAULT_AUTH_COOKIE_NAME;
23
+ }
24
+ return cookieName;
25
+ };
26
+
27
+ export { DEFAULT_AUTH_COOKIE_NAME, resolveAuthCookieName };
28
+ //# sourceMappingURL=auth-cookie-name.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-cookie-name.mjs","sources":["../../../../shared/utils/auth-cookie-name.ts"],"sourcesContent":["/**\n * Name of the cookie holding the admin auth (access) token, configurable\n * through `admin.auth.cookie.name` so it cannot collide with a same-named\n * cookie set by another application on a shared parent domain.\n *\n * Browser-safe single source for both sides of the SSO handoff: the admin\n * panel cannot read server config, so the build transports the config value\n * into the bundle through the internal `STRAPI_ADMIN_AUTH_COOKIE_NAME`\n * variable (see create-build-context.ts in @strapi/strapi); the server\n * resolves the same config at runtime. Renaming the cookie requires an admin\n * rebuild, like any other admin config change.\n */\nexport const DEFAULT_AUTH_COOKIE_NAME = 'jwtToken';\n\n// RFC 6265 cookie-name token characters.\nconst VALID_COOKIE_NAME = /^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$/;\n\nexport const resolveAuthCookieName = (\n configuredName?: string,\n warn: (message: string) => void = console.warn\n): string => {\n const cookieName = (configuredName || '').trim();\n\n if (!cookieName) {\n return DEFAULT_AUTH_COOKIE_NAME;\n }\n\n if (!VALID_COOKIE_NAME.test(cookieName)) {\n warn(\n `Ignoring invalid admin auth cookie name \"${cookieName}\" (must only contain RFC 6265 cookie-name characters); using \"${DEFAULT_AUTH_COOKIE_NAME}\" instead.`\n );\n return DEFAULT_AUTH_COOKIE_NAME;\n }\n\n return cookieName;\n};\n"],"names":["DEFAULT_AUTH_COOKIE_NAME","VALID_COOKIE_NAME","resolveAuthCookieName","configuredName","warn","console","cookieName","trim","test"],"mappings":"AAAA;;;;;;;;;;;IAYO,MAAMA,wBAAAA,GAA2B;AAExC;AACA,MAAMC,iBAAAA,GAAoB,gCAAA;MAEbC,qBAAAA,GAAwB,CACnCC,cAAAA,EACAC,IAAAA,GAAkCC,QAAQD,IAAI,GAAA;AAE9C,IAAA,MAAME,aAAa,CAACH,cAAAA,IAAkB,EAAC,EAAGI,IAAI,EAAA;AAE9C,IAAA,IAAI,CAACD,UAAAA,EAAY;QACf,OAAON,wBAAAA;AACT,IAAA;AAEA,IAAA,IAAI,CAACC,iBAAAA,CAAkBO,IAAI,CAACF,UAAAA,CAAAA,EAAa;QACvCF,IAAAA,CACE,CAAC,yCAAyC,EAAEE,UAAAA,CAAW,8DAA8D,EAAEN,wBAAAA,CAAyB,UAAU,CAAC,CAAA;QAE7J,OAAOA,wBAAAA;AACT,IAAA;IAEA,OAAOM,UAAAA;AACT;;;;"}
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Path attribute of the admin auth (access) token cookie, configurable
5
+ * through `admin.auth.cookie.path` so multiple Strapi instances on the same
6
+ * parent domain can keep separate cookies (e.g. `/strapi-de/admin`).
7
+ *
8
+ * Browser-safe single source for both sides of the handoff: the admin panel
9
+ * cannot read server config, so the build transports the config value into
10
+ * the bundle through the internal `STRAPI_ADMIN_AUTH_COOKIE_PATH` variable
11
+ * (see create-build-context.ts in @strapi/strapi); the server resolves the
12
+ * same config at runtime. Changing the path requires an admin rebuild, like
13
+ * any other admin config change.
14
+ *
15
+ * Defaults to `/admin` to match the refresh-cookie path used by
16
+ * `getRefreshCookieOptions`.
17
+ */ const DEFAULT_AUTH_COOKIE_PATH = '/admin';
18
+ const isValidCookiePath = (path)=>{
19
+ if (!path.startsWith('/')) {
20
+ return false;
21
+ }
22
+ // RFC 6265 path-av: any CHAR except CTLs or ";".
23
+ return !/[\x00-\x1F\x7F;]/.test(path);
24
+ };
25
+ const resolveAuthCookiePath = (configuredPath, warn = console.warn)=>{
26
+ const cookiePath = (configuredPath || '').trim();
27
+ if (!cookiePath) {
28
+ return DEFAULT_AUTH_COOKIE_PATH;
29
+ }
30
+ if (!isValidCookiePath(cookiePath)) {
31
+ warn(`Ignoring invalid admin auth cookie path "${cookiePath}" (must be an absolute path without ";"); using "${DEFAULT_AUTH_COOKIE_PATH}" instead.`);
32
+ return DEFAULT_AUTH_COOKIE_PATH;
33
+ }
34
+ return cookiePath;
35
+ };
36
+
37
+ exports.DEFAULT_AUTH_COOKIE_PATH = DEFAULT_AUTH_COOKIE_PATH;
38
+ exports.resolveAuthCookiePath = resolveAuthCookiePath;
39
+ //# sourceMappingURL=auth-cookie-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-cookie-path.js","sources":["../../../../shared/utils/auth-cookie-path.ts"],"sourcesContent":["/**\n * Path attribute of the admin auth (access) token cookie, configurable\n * through `admin.auth.cookie.path` so multiple Strapi instances on the same\n * parent domain can keep separate cookies (e.g. `/strapi-de/admin`).\n *\n * Browser-safe single source for both sides of the handoff: the admin panel\n * cannot read server config, so the build transports the config value into\n * the bundle through the internal `STRAPI_ADMIN_AUTH_COOKIE_PATH` variable\n * (see create-build-context.ts in @strapi/strapi); the server resolves the\n * same config at runtime. Changing the path requires an admin rebuild, like\n * any other admin config change.\n *\n * Defaults to `/admin` to match the refresh-cookie path used by\n * `getRefreshCookieOptions`.\n */\nexport const DEFAULT_AUTH_COOKIE_PATH = '/admin';\n\nconst isValidCookiePath = (path: string): boolean => {\n if (!path.startsWith('/')) {\n return false;\n }\n\n // RFC 6265 path-av: any CHAR except CTLs or \";\".\n return !/[\\x00-\\x1F\\x7F;]/.test(path);\n};\n\nexport const resolveAuthCookiePath = (\n configuredPath?: string,\n warn: (message: string) => void = console.warn\n): string => {\n const cookiePath = (configuredPath || '').trim();\n\n if (!cookiePath) {\n return DEFAULT_AUTH_COOKIE_PATH;\n }\n\n if (!isValidCookiePath(cookiePath)) {\n warn(\n `Ignoring invalid admin auth cookie path \"${cookiePath}\" (must be an absolute path without \";\"); using \"${DEFAULT_AUTH_COOKIE_PATH}\" instead.`\n );\n return DEFAULT_AUTH_COOKIE_PATH;\n }\n\n return cookiePath;\n};\n"],"names":["DEFAULT_AUTH_COOKIE_PATH","isValidCookiePath","path","startsWith","test","resolveAuthCookiePath","configuredPath","warn","console","cookiePath","trim"],"mappings":";;AAAA;;;;;;;;;;;;;;IAeO,MAAMA,wBAAAA,GAA2B;AAExC,MAAMC,oBAAoB,CAACC,IAAAA,GAAAA;AACzB,IAAA,IAAI,CAACA,IAAAA,CAAKC,UAAU,CAAC,GAAA,CAAA,EAAM;QACzB,OAAO,KAAA;AACT,IAAA;;IAGA,OAAO,CAAC,kBAAA,CAAmBC,IAAI,CAACF,IAAAA,CAAAA;AAClC,CAAA;MAEaG,qBAAAA,GAAwB,CACnCC,cAAAA,EACAC,IAAAA,GAAkCC,QAAQD,IAAI,GAAA;AAE9C,IAAA,MAAME,aAAa,CAACH,cAAAA,IAAkB,EAAC,EAAGI,IAAI,EAAA;AAE9C,IAAA,IAAI,CAACD,UAAAA,EAAY;QACf,OAAOT,wBAAAA;AACT,IAAA;IAEA,IAAI,CAACC,kBAAkBQ,UAAAA,CAAAA,EAAa;QAClCF,IAAAA,CACE,CAAC,yCAAyC,EAAEE,UAAAA,CAAW,iDAAiD,EAAET,wBAAAA,CAAyB,UAAU,CAAC,CAAA;QAEhJ,OAAOA,wBAAAA;AACT,IAAA;IAEA,OAAOS,UAAAA;AACT;;;;;"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Path attribute of the admin auth (access) token cookie, configurable
3
+ * through `admin.auth.cookie.path` so multiple Strapi instances on the same
4
+ * parent domain can keep separate cookies (e.g. `/strapi-de/admin`).
5
+ *
6
+ * Browser-safe single source for both sides of the handoff: the admin panel
7
+ * cannot read server config, so the build transports the config value into
8
+ * the bundle through the internal `STRAPI_ADMIN_AUTH_COOKIE_PATH` variable
9
+ * (see create-build-context.ts in @strapi/strapi); the server resolves the
10
+ * same config at runtime. Changing the path requires an admin rebuild, like
11
+ * any other admin config change.
12
+ *
13
+ * Defaults to `/admin` to match the refresh-cookie path used by
14
+ * `getRefreshCookieOptions`.
15
+ */ const DEFAULT_AUTH_COOKIE_PATH = '/admin';
16
+ const isValidCookiePath = (path)=>{
17
+ if (!path.startsWith('/')) {
18
+ return false;
19
+ }
20
+ // RFC 6265 path-av: any CHAR except CTLs or ";".
21
+ return !/[\x00-\x1F\x7F;]/.test(path);
22
+ };
23
+ const resolveAuthCookiePath = (configuredPath, warn = console.warn)=>{
24
+ const cookiePath = (configuredPath || '').trim();
25
+ if (!cookiePath) {
26
+ return DEFAULT_AUTH_COOKIE_PATH;
27
+ }
28
+ if (!isValidCookiePath(cookiePath)) {
29
+ warn(`Ignoring invalid admin auth cookie path "${cookiePath}" (must be an absolute path without ";"); using "${DEFAULT_AUTH_COOKIE_PATH}" instead.`);
30
+ return DEFAULT_AUTH_COOKIE_PATH;
31
+ }
32
+ return cookiePath;
33
+ };
34
+
35
+ export { DEFAULT_AUTH_COOKIE_PATH, resolveAuthCookiePath };
36
+ //# sourceMappingURL=auth-cookie-path.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-cookie-path.mjs","sources":["../../../../shared/utils/auth-cookie-path.ts"],"sourcesContent":["/**\n * Path attribute of the admin auth (access) token cookie, configurable\n * through `admin.auth.cookie.path` so multiple Strapi instances on the same\n * parent domain can keep separate cookies (e.g. `/strapi-de/admin`).\n *\n * Browser-safe single source for both sides of the handoff: the admin panel\n * cannot read server config, so the build transports the config value into\n * the bundle through the internal `STRAPI_ADMIN_AUTH_COOKIE_PATH` variable\n * (see create-build-context.ts in @strapi/strapi); the server resolves the\n * same config at runtime. Changing the path requires an admin rebuild, like\n * any other admin config change.\n *\n * Defaults to `/admin` to match the refresh-cookie path used by\n * `getRefreshCookieOptions`.\n */\nexport const DEFAULT_AUTH_COOKIE_PATH = '/admin';\n\nconst isValidCookiePath = (path: string): boolean => {\n if (!path.startsWith('/')) {\n return false;\n }\n\n // RFC 6265 path-av: any CHAR except CTLs or \";\".\n return !/[\\x00-\\x1F\\x7F;]/.test(path);\n};\n\nexport const resolveAuthCookiePath = (\n configuredPath?: string,\n warn: (message: string) => void = console.warn\n): string => {\n const cookiePath = (configuredPath || '').trim();\n\n if (!cookiePath) {\n return DEFAULT_AUTH_COOKIE_PATH;\n }\n\n if (!isValidCookiePath(cookiePath)) {\n warn(\n `Ignoring invalid admin auth cookie path \"${cookiePath}\" (must be an absolute path without \";\"); using \"${DEFAULT_AUTH_COOKIE_PATH}\" instead.`\n );\n return DEFAULT_AUTH_COOKIE_PATH;\n }\n\n return cookiePath;\n};\n"],"names":["DEFAULT_AUTH_COOKIE_PATH","isValidCookiePath","path","startsWith","test","resolveAuthCookiePath","configuredPath","warn","console","cookiePath","trim"],"mappings":"AAAA;;;;;;;;;;;;;;IAeO,MAAMA,wBAAAA,GAA2B;AAExC,MAAMC,oBAAoB,CAACC,IAAAA,GAAAA;AACzB,IAAA,IAAI,CAACA,IAAAA,CAAKC,UAAU,CAAC,GAAA,CAAA,EAAM;QACzB,OAAO,KAAA;AACT,IAAA;;IAGA,OAAO,CAAC,kBAAA,CAAmBC,IAAI,CAACF,IAAAA,CAAAA;AAClC,CAAA;MAEaG,qBAAAA,GAAwB,CACnCC,cAAAA,EACAC,IAAAA,GAAkCC,QAAQD,IAAI,GAAA;AAE9C,IAAA,MAAME,aAAa,CAACH,cAAAA,IAAkB,EAAC,EAAGI,IAAI,EAAA;AAE9C,IAAA,IAAI,CAACD,UAAAA,EAAY;QACf,OAAOT,wBAAAA;AACT,IAAA;IAEA,IAAI,CAACC,kBAAkBQ,UAAAA,CAAAA,EAAa;QAClCF,IAAAA,CACE,CAAC,yCAAyC,EAAEE,UAAAA,CAAW,iDAAiD,EAAET,wBAAAA,CAAyB,UAAU,CAAC,CAAA;QAEhJ,OAAOA,wBAAAA;AACT,IAAA;IAEA,OAAOS,UAAAA;AACT;;;;"}
@@ -1,12 +1,36 @@
1
1
  'use strict';
2
2
 
3
3
  var crypto = require('crypto');
4
+ var utils = require('@strapi/utils');
5
+ var authCookieName = require('./auth-cookie-name.js');
6
+ var authCookiePath = require('./auth-cookie-path.js');
7
+ var authCookieDomain = require('./auth-cookie-domain.js');
4
8
 
5
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
10
 
7
11
  var crypto__default = /*#__PURE__*/_interopDefault(crypto);
8
12
 
13
+ const ADMIN_ORIGIN = 'admin';
14
+ const SESSION_CONTENT_TYPE = 'admin::session';
9
15
  const REFRESH_COOKIE_NAME = 'strapi_admin_refresh';
16
+ // The resolvers are browser-shared (also inlined into the admin bundle) so
17
+ // they default to console.warn; on the server, route their warnings through
18
+ // the Strapi logger instead.
19
+ const warnViaStrapiLog = (message)=>{
20
+ strapi.log.warn(message);
21
+ };
22
+ const getAccessCookieName = ()=>{
23
+ const configured = strapi.config.get('admin.auth.cookie.name');
24
+ return authCookieName.resolveAuthCookieName(configured, warnViaStrapiLog);
25
+ };
26
+ const getAccessCookiePath = ()=>{
27
+ const configured = strapi.config.get('admin.auth.cookie.path');
28
+ return authCookiePath.resolveAuthCookiePath(configured, warnViaStrapiLog);
29
+ };
30
+ const getAccessCookieDomain = ()=>{
31
+ const configured = strapi.config.get('admin.auth.cookie.domain') || strapi.config.get('admin.auth.domain');
32
+ return authCookieDomain.resolveAuthCookieDomain(configured, warnViaStrapiLog);
33
+ };
10
34
  const DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN = 30 * 24 * 60 * 60;
11
35
  const DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN = 14 * 24 * 60 * 60;
12
36
  const DEFAULT_MAX_SESSION_LIFESPAN = 1 * 24 * 60 * 60;
@@ -14,8 +38,8 @@ const DEFAULT_IDLE_SESSION_LIFESPAN = 2 * 60 * 60;
14
38
  const getRefreshCookieOptions = (secureRequest)=>{
15
39
  const configuredSecure = strapi.config.get('admin.auth.cookie.secure');
16
40
  const isProduction = process.env.NODE_ENV === 'production';
17
- const domain = strapi.config.get('admin.auth.cookie.domain') || strapi.config.get('admin.auth.domain');
18
- const path = strapi.config.get('admin.auth.cookie.path', '/admin');
41
+ const domain = getAccessCookieDomain();
42
+ const path = getAccessCookiePath();
19
43
  const sameSite = strapi.config.get('admin.auth.cookie.sameSite') ?? 'lax';
20
44
  let isSecure;
21
45
  if (typeof configuredSecure === 'boolean') {
@@ -75,6 +99,34 @@ const extractDeviceParams = (requestBody)=>{
75
99
  rememberMe
76
100
  };
77
101
  };
102
+ const buildSessionMetadataFromContext = (ctx)=>utils.buildSessionMetadata({
103
+ userAgent: ctx.request.headers['user-agent']
104
+ });
105
+ /**
106
+ * Resolves the device id to use when revoking sessions on logout.
107
+ * SSO assigns deviceId server-side, so the client-provided value may not match
108
+ * the active session row. Prefer the deviceId stored on the session backing
109
+ * the current access token when available.
110
+ *
111
+ * Callers should pass `ctx.state.session.id` from the admin auth strategy and
112
+ * the already-parsed body `deviceId` — the logout route requires authentication,
113
+ * so sessionId is expected to be present.
114
+ */ const resolveLogoutDeviceId = async (userId, sessionId, clientDeviceId)=>{
115
+ if (!sessionId) {
116
+ strapi.log.debug('resolveLogoutDeviceId: no sessionId; falling back to client deviceId');
117
+ return clientDeviceId;
118
+ }
119
+ const session = await strapi.db.query(SESSION_CONTENT_TYPE).findOne({
120
+ where: {
121
+ sessionId
122
+ }
123
+ });
124
+ if (session?.userId !== userId || session?.origin !== ADMIN_ORIGIN) {
125
+ strapi.log.debug('resolveLogoutDeviceId: access-token session missing or not owned; falling back to client deviceId');
126
+ return clientDeviceId;
127
+ }
128
+ return typeof session.deviceId === 'string' ? session.deviceId : clientDeviceId;
129
+ };
78
130
 
79
131
  exports.DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN = DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN;
80
132
  exports.DEFAULT_IDLE_SESSION_LIFESPAN = DEFAULT_IDLE_SESSION_LIFESPAN;
@@ -82,8 +134,13 @@ exports.DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN = DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN;
82
134
  exports.DEFAULT_MAX_SESSION_LIFESPAN = DEFAULT_MAX_SESSION_LIFESPAN;
83
135
  exports.REFRESH_COOKIE_NAME = REFRESH_COOKIE_NAME;
84
136
  exports.buildCookieOptionsWithExpiry = buildCookieOptionsWithExpiry;
137
+ exports.buildSessionMetadataFromContext = buildSessionMetadataFromContext;
85
138
  exports.extractDeviceParams = extractDeviceParams;
86
139
  exports.generateDeviceId = generateDeviceId;
140
+ exports.getAccessCookieDomain = getAccessCookieDomain;
141
+ exports.getAccessCookieName = getAccessCookieName;
142
+ exports.getAccessCookiePath = getAccessCookiePath;
87
143
  exports.getRefreshCookieOptions = getRefreshCookieOptions;
88
144
  exports.getSessionManager = getSessionManager;
145
+ exports.resolveLogoutDeviceId = resolveLogoutDeviceId;
89
146
  //# sourceMappingURL=session-auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-auth.js","sources":["../../../../shared/utils/session-auth.ts"],"sourcesContent":["import crypto from 'crypto';\nimport type { Modules } from '@strapi/types';\n\nexport const REFRESH_COOKIE_NAME = 'strapi_admin_refresh';\n\nexport const DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN = 30 * 24 * 60 * 60;\nexport const DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN = 14 * 24 * 60 * 60;\nexport const DEFAULT_MAX_SESSION_LIFESPAN = 1 * 24 * 60 * 60;\nexport const DEFAULT_IDLE_SESSION_LIFESPAN = 2 * 60 * 60;\n\nexport const getRefreshCookieOptions = (secureRequest?: boolean) => {\n const configuredSecure = strapi.config.get('admin.auth.cookie.secure');\n const isProduction = process.env.NODE_ENV === 'production';\n\n const domain: string | undefined =\n strapi.config.get('admin.auth.cookie.domain') || strapi.config.get('admin.auth.domain');\n const path: string = strapi.config.get('admin.auth.cookie.path', '/admin');\n\n const sameSite: boolean | 'lax' | 'strict' | 'none' =\n strapi.config.get('admin.auth.cookie.sameSite') ?? 'lax';\n\n let isSecure: boolean;\n if (typeof configuredSecure === 'boolean') {\n isSecure = configuredSecure;\n } else if (secureRequest !== undefined) {\n isSecure = isProduction && secureRequest;\n } else {\n isSecure = isProduction;\n }\n\n return {\n httpOnly: true,\n secure: isSecure,\n overwrite: true,\n domain,\n path,\n sameSite,\n maxAge: undefined,\n };\n};\n\nconst getLifespansForType = (\n type: 'refresh' | 'session'\n): { idleSeconds: number; maxSeconds: number } => {\n if (type === 'refresh') {\n const idleSeconds = Number(\n strapi.config.get(\n 'admin.auth.sessions.idleRefreshTokenLifespan',\n DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN\n )\n );\n const maxSeconds = Number(\n strapi.config.get(\n 'admin.auth.sessions.maxRefreshTokenLifespan',\n DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN\n )\n );\n\n return { idleSeconds, maxSeconds };\n }\n\n const idleSeconds = Number(\n strapi.config.get('admin.auth.sessions.idleSessionLifespan', DEFAULT_IDLE_SESSION_LIFESPAN)\n );\n const maxSeconds = Number(\n strapi.config.get('admin.auth.sessions.maxSessionLifespan', DEFAULT_MAX_SESSION_LIFESPAN)\n );\n\n return { idleSeconds, maxSeconds };\n};\n\nexport const buildCookieOptionsWithExpiry = (\n type: 'refresh' | 'session',\n absoluteExpiresAtISO?: string,\n secureRequest?: boolean\n) => {\n const base = getRefreshCookieOptions(secureRequest);\n if (type === 'session') {\n return base;\n }\n\n const { idleSeconds } = getLifespansForType('refresh');\n const now = Date.now();\n const idleExpiry = now + idleSeconds * 1000;\n const absoluteExpiry = absoluteExpiresAtISO\n ? new Date(absoluteExpiresAtISO).getTime()\n : idleExpiry;\n const chosen = new Date(Math.min(idleExpiry, absoluteExpiry));\n\n return { ...base, expires: chosen, maxAge: Math.max(0, chosen.getTime() - now) };\n};\n\nexport const getSessionManager = (): Modules.SessionManager.SessionManagerService | null => {\n const manager = strapi.sessionManager as Modules.SessionManager.SessionManagerService | undefined;\n return manager ?? null;\n};\n\nexport const generateDeviceId = (): string => crypto.randomUUID();\n\nexport const extractDeviceParams = (\n requestBody: unknown\n): { deviceId: string; rememberMe: boolean } => {\n const body = (requestBody ?? {}) as { deviceId?: string; rememberMe?: boolean };\n const deviceId = body.deviceId || generateDeviceId();\n const rememberMe = Boolean(body.rememberMe);\n\n return { deviceId, rememberMe };\n};\n"],"names":["REFRESH_COOKIE_NAME","DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN","DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN","DEFAULT_MAX_SESSION_LIFESPAN","DEFAULT_IDLE_SESSION_LIFESPAN","getRefreshCookieOptions","secureRequest","configuredSecure","strapi","config","get","isProduction","process","env","NODE_ENV","domain","path","sameSite","isSecure","undefined","httpOnly","secure","overwrite","maxAge","getLifespansForType","type","idleSeconds","Number","maxSeconds","buildCookieOptionsWithExpiry","absoluteExpiresAtISO","base","now","Date","idleExpiry","absoluteExpiry","getTime","chosen","Math","min","expires","max","getSessionManager","manager","sessionManager","generateDeviceId","crypto","randomUUID","extractDeviceParams","requestBody","body","deviceId","rememberMe","Boolean"],"mappings":"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"}
1
+ {"version":3,"file":"session-auth.js","sources":["../../../../shared/utils/session-auth.ts"],"sourcesContent":["import crypto from 'crypto';\nimport type { Context } from 'koa';\nimport type { Modules } from '@strapi/types';\nimport { buildSessionMetadata } from '@strapi/utils';\n\nimport { resolveAuthCookieName } from './auth-cookie-name';\nimport { resolveAuthCookiePath } from './auth-cookie-path';\nimport { resolveAuthCookieDomain } from './auth-cookie-domain';\n\nconst ADMIN_ORIGIN = 'admin';\nconst SESSION_CONTENT_TYPE = 'admin::session';\n\nexport const REFRESH_COOKIE_NAME = 'strapi_admin_refresh';\n\n// The resolvers are browser-shared (also inlined into the admin bundle) so\n// they default to console.warn; on the server, route their warnings through\n// the Strapi logger instead.\nconst warnViaStrapiLog = (message: string): void => {\n strapi.log.warn(message);\n};\n\nexport const getAccessCookieName = (): string => {\n const configured: string | undefined = strapi.config.get('admin.auth.cookie.name');\n return resolveAuthCookieName(configured, warnViaStrapiLog);\n};\n\nexport const getAccessCookiePath = (): string => {\n const configured: string | undefined = strapi.config.get('admin.auth.cookie.path');\n return resolveAuthCookiePath(configured, warnViaStrapiLog);\n};\n\nexport const getAccessCookieDomain = (): string | undefined => {\n const configured: string | undefined =\n strapi.config.get('admin.auth.cookie.domain') || strapi.config.get('admin.auth.domain');\n return resolveAuthCookieDomain(configured, warnViaStrapiLog);\n};\n\nexport const DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN = 30 * 24 * 60 * 60;\nexport const DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN = 14 * 24 * 60 * 60;\nexport const DEFAULT_MAX_SESSION_LIFESPAN = 1 * 24 * 60 * 60;\nexport const DEFAULT_IDLE_SESSION_LIFESPAN = 2 * 60 * 60;\n\nexport const getRefreshCookieOptions = (secureRequest?: boolean) => {\n const configuredSecure = strapi.config.get('admin.auth.cookie.secure');\n const isProduction = process.env.NODE_ENV === 'production';\n\n const domain = getAccessCookieDomain();\n const path = getAccessCookiePath();\n\n const sameSite: boolean | 'lax' | 'strict' | 'none' =\n strapi.config.get('admin.auth.cookie.sameSite') ?? 'lax';\n\n let isSecure: boolean;\n if (typeof configuredSecure === 'boolean') {\n isSecure = configuredSecure;\n } else if (secureRequest !== undefined) {\n isSecure = isProduction && secureRequest;\n } else {\n isSecure = isProduction;\n }\n\n return {\n httpOnly: true,\n secure: isSecure,\n overwrite: true,\n domain,\n path,\n sameSite,\n maxAge: undefined,\n };\n};\n\nconst getLifespansForType = (\n type: 'refresh' | 'session'\n): { idleSeconds: number; maxSeconds: number } => {\n if (type === 'refresh') {\n const idleSeconds = Number(\n strapi.config.get(\n 'admin.auth.sessions.idleRefreshTokenLifespan',\n DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN\n )\n );\n const maxSeconds = Number(\n strapi.config.get(\n 'admin.auth.sessions.maxRefreshTokenLifespan',\n DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN\n )\n );\n\n return { idleSeconds, maxSeconds };\n }\n\n const idleSeconds = Number(\n strapi.config.get('admin.auth.sessions.idleSessionLifespan', DEFAULT_IDLE_SESSION_LIFESPAN)\n );\n const maxSeconds = Number(\n strapi.config.get('admin.auth.sessions.maxSessionLifespan', DEFAULT_MAX_SESSION_LIFESPAN)\n );\n\n return { idleSeconds, maxSeconds };\n};\n\nexport const buildCookieOptionsWithExpiry = (\n type: 'refresh' | 'session',\n absoluteExpiresAtISO?: string,\n secureRequest?: boolean\n) => {\n const base = getRefreshCookieOptions(secureRequest);\n if (type === 'session') {\n return base;\n }\n\n const { idleSeconds } = getLifespansForType('refresh');\n const now = Date.now();\n const idleExpiry = now + idleSeconds * 1000;\n const absoluteExpiry = absoluteExpiresAtISO\n ? new Date(absoluteExpiresAtISO).getTime()\n : idleExpiry;\n const chosen = new Date(Math.min(idleExpiry, absoluteExpiry));\n\n return { ...base, expires: chosen, maxAge: Math.max(0, chosen.getTime() - now) };\n};\n\nexport const getSessionManager = (): Modules.SessionManager.SessionManagerService | null => {\n const manager = strapi.sessionManager as Modules.SessionManager.SessionManagerService | undefined;\n return manager ?? null;\n};\n\nexport const generateDeviceId = (): string => crypto.randomUUID();\n\nexport const extractDeviceParams = (\n requestBody: unknown\n): { deviceId: string; rememberMe: boolean } => {\n const body = (requestBody ?? {}) as { deviceId?: string; rememberMe?: boolean };\n const deviceId = body.deviceId || generateDeviceId();\n const rememberMe = Boolean(body.rememberMe);\n\n return { deviceId, rememberMe };\n};\n\nexport const buildSessionMetadataFromContext = (ctx: Context) =>\n buildSessionMetadata({\n userAgent: ctx.request.headers['user-agent'],\n });\n\n/**\n * Resolves the device id to use when revoking sessions on logout.\n * SSO assigns deviceId server-side, so the client-provided value may not match\n * the active session row. Prefer the deviceId stored on the session backing\n * the current access token when available.\n *\n * Callers should pass `ctx.state.session.id` from the admin auth strategy and\n * the already-parsed body `deviceId` — the logout route requires authentication,\n * so sessionId is expected to be present.\n */\nexport const resolveLogoutDeviceId = async (\n userId: string,\n sessionId: string | undefined,\n clientDeviceId: string | undefined\n): Promise<string | undefined> => {\n if (!sessionId) {\n strapi.log.debug('resolveLogoutDeviceId: no sessionId; falling back to client deviceId');\n return clientDeviceId;\n }\n\n const session = await strapi.db.query(SESSION_CONTENT_TYPE).findOne({\n where: { sessionId },\n });\n\n if (session?.userId !== userId || session?.origin !== ADMIN_ORIGIN) {\n strapi.log.debug(\n 'resolveLogoutDeviceId: access-token session missing or not owned; falling back to client deviceId'\n );\n return clientDeviceId;\n }\n\n return typeof session.deviceId === 'string' ? session.deviceId : clientDeviceId;\n};\n"],"names":["ADMIN_ORIGIN","SESSION_CONTENT_TYPE","REFRESH_COOKIE_NAME","warnViaStrapiLog","message","strapi","log","warn","getAccessCookieName","configured","config","get","resolveAuthCookieName","getAccessCookiePath","resolveAuthCookiePath","getAccessCookieDomain","resolveAuthCookieDomain","DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN","DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN","DEFAULT_MAX_SESSION_LIFESPAN","DEFAULT_IDLE_SESSION_LIFESPAN","getRefreshCookieOptions","secureRequest","configuredSecure","isProduction","process","env","NODE_ENV","domain","path","sameSite","isSecure","undefined","httpOnly","secure","overwrite","maxAge","getLifespansForType","type","idleSeconds","Number","maxSeconds","buildCookieOptionsWithExpiry","absoluteExpiresAtISO","base","now","Date","idleExpiry","absoluteExpiry","getTime","chosen","Math","min","expires","max","getSessionManager","manager","sessionManager","generateDeviceId","crypto","randomUUID","extractDeviceParams","requestBody","body","deviceId","rememberMe","Boolean","buildSessionMetadataFromContext","ctx","buildSessionMetadata","userAgent","request","headers","resolveLogoutDeviceId","userId","sessionId","clientDeviceId","debug","session","db","query","findOne","where","origin"],"mappings":"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"}