@strapi/admin 5.23.6 → 5.24.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 (108) hide show
  1. package/dist/admin/admin/src/features/Auth.js +9 -28
  2. package/dist/admin/admin/src/features/Auth.js.map +1 -1
  3. package/dist/admin/admin/src/features/Auth.mjs +11 -30
  4. package/dist/admin/admin/src/features/Auth.mjs.map +1 -1
  5. package/dist/admin/admin/src/pages/Auth/components/Register.js +9 -2
  6. package/dist/admin/admin/src/pages/Auth/components/Register.js.map +1 -1
  7. package/dist/admin/admin/src/pages/Auth/components/Register.mjs +9 -2
  8. package/dist/admin/admin/src/pages/Auth/components/Register.mjs.map +1 -1
  9. package/dist/admin/admin/src/services/auth.js +7 -6
  10. package/dist/admin/admin/src/services/auth.js.map +1 -1
  11. package/dist/admin/admin/src/services/auth.mjs +7 -6
  12. package/dist/admin/admin/src/services/auth.mjs.map +1 -1
  13. package/dist/admin/admin/src/utils/baseQuery.js +78 -42
  14. package/dist/admin/admin/src/utils/baseQuery.js.map +1 -1
  15. package/dist/admin/admin/src/utils/baseQuery.mjs +79 -43
  16. package/dist/admin/admin/src/utils/baseQuery.mjs.map +1 -1
  17. package/dist/admin/admin/src/utils/deviceId.js +38 -0
  18. package/dist/admin/admin/src/utils/deviceId.js.map +1 -0
  19. package/dist/admin/admin/src/utils/deviceId.mjs +36 -0
  20. package/dist/admin/admin/src/utils/deviceId.mjs.map +1 -0
  21. package/dist/admin/src/services/auth.d.ts +19 -10
  22. package/dist/admin/src/utils/deviceId.d.ts +5 -0
  23. package/dist/ee/server/src/controllers/authentication-utils/middlewares.d.ts.map +1 -1
  24. package/dist/ee/server/src/services/user.d.ts.map +1 -1
  25. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js +43 -17
  26. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js.map +1 -1
  27. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs +43 -17
  28. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs.map +1 -1
  29. package/dist/server/ee/server/src/services/user.js +14 -0
  30. package/dist/server/ee/server/src/services/user.js.map +1 -1
  31. package/dist/server/ee/server/src/services/user.mjs +14 -0
  32. package/dist/server/ee/server/src/services/user.mjs.map +1 -1
  33. package/dist/server/server/src/bootstrap.js +22 -0
  34. package/dist/server/server/src/bootstrap.js.map +1 -1
  35. package/dist/server/server/src/bootstrap.mjs +22 -0
  36. package/dist/server/server/src/bootstrap.mjs.map +1 -1
  37. package/dist/server/server/src/content-types/index.js +4 -0
  38. package/dist/server/server/src/content-types/index.js.map +1 -1
  39. package/dist/server/server/src/content-types/index.mjs +4 -0
  40. package/dist/server/server/src/content-types/index.mjs.map +1 -1
  41. package/dist/server/server/src/content-types/session.js +91 -0
  42. package/dist/server/server/src/content-types/session.js.map +1 -0
  43. package/dist/server/server/src/content-types/session.mjs +89 -0
  44. package/dist/server/server/src/content-types/session.mjs.map +1 -0
  45. package/dist/server/server/src/controllers/authentication.js +169 -38
  46. package/dist/server/server/src/controllers/authentication.js.map +1 -1
  47. package/dist/server/server/src/controllers/authentication.mjs +169 -38
  48. package/dist/server/server/src/controllers/authentication.mjs.map +1 -1
  49. package/dist/server/server/src/routes/authentication.js +2 -2
  50. package/dist/server/server/src/routes/authentication.js.map +1 -1
  51. package/dist/server/server/src/routes/authentication.mjs +2 -2
  52. package/dist/server/server/src/routes/authentication.mjs.map +1 -1
  53. package/dist/server/server/src/services/token.js +44 -31
  54. package/dist/server/server/src/services/token.js.map +1 -1
  55. package/dist/server/server/src/services/token.mjs +44 -30
  56. package/dist/server/server/src/services/token.mjs.map +1 -1
  57. package/dist/server/server/src/services/user.js +14 -0
  58. package/dist/server/server/src/services/user.js.map +1 -1
  59. package/dist/server/server/src/services/user.mjs +14 -0
  60. package/dist/server/server/src/services/user.mjs.map +1 -1
  61. package/dist/server/server/src/strategies/admin.js +23 -3
  62. package/dist/server/server/src/strategies/admin.js.map +1 -1
  63. package/dist/server/server/src/strategies/admin.mjs +23 -3
  64. package/dist/server/server/src/strategies/admin.mjs.map +1 -1
  65. package/dist/server/server/src/validation/authentication/login.js +16 -0
  66. package/dist/server/server/src/validation/authentication/login.js.map +1 -0
  67. package/dist/server/server/src/validation/authentication/login.mjs +14 -0
  68. package/dist/server/server/src/validation/authentication/login.mjs.map +1 -0
  69. package/dist/server/server/src/validation/authentication/register.js +6 -2
  70. package/dist/server/server/src/validation/authentication/register.js.map +1 -1
  71. package/dist/server/server/src/validation/authentication/register.mjs +6 -2
  72. package/dist/server/server/src/validation/authentication/register.mjs.map +1 -1
  73. package/dist/server/shared/utils/session-auth.js +76 -0
  74. package/dist/server/shared/utils/session-auth.js.map +1 -0
  75. package/dist/server/shared/utils/session-auth.mjs +65 -0
  76. package/dist/server/shared/utils/session-auth.mjs.map +1 -0
  77. package/dist/server/src/bootstrap.d.ts.map +1 -1
  78. package/dist/server/src/content-types/index.d.ts +88 -0
  79. package/dist/server/src/content-types/index.d.ts.map +1 -1
  80. package/dist/server/src/content-types/session.d.ts +88 -0
  81. package/dist/server/src/content-types/session.d.ts.map +1 -0
  82. package/dist/server/src/controllers/authentication.d.ts +5 -5
  83. package/dist/server/src/controllers/authentication.d.ts.map +1 -1
  84. package/dist/server/src/controllers/index.d.ts +5 -5
  85. package/dist/server/src/index.d.ts +93 -5
  86. package/dist/server/src/index.d.ts.map +1 -1
  87. package/dist/server/src/routes/authentication.d.ts.map +1 -1
  88. package/dist/server/src/services/token.d.ts +11 -19
  89. package/dist/server/src/services/token.d.ts.map +1 -1
  90. package/dist/server/src/services/user.d.ts.map +1 -1
  91. package/dist/server/src/strategies/admin.d.ts.map +1 -1
  92. package/dist/server/src/validation/authentication/index.d.ts +1 -1
  93. package/dist/server/src/validation/authentication/index.d.ts.map +1 -1
  94. package/dist/server/src/validation/authentication/login.d.ts +7 -0
  95. package/dist/server/src/validation/authentication/login.d.ts.map +1 -0
  96. package/dist/server/src/validation/authentication/register.d.ts +5 -0
  97. package/dist/server/src/validation/authentication/register.d.ts.map +1 -1
  98. package/dist/shared/contracts/authentication.d.ts +20 -10
  99. package/dist/shared/contracts/authentication.d.ts.map +1 -1
  100. package/dist/shared/utils/session-auth.d.ts +39 -0
  101. package/dist/shared/utils/session-auth.d.ts.map +1 -0
  102. package/package.json +7 -7
  103. package/dist/server/server/src/validation/authentication/renew-token.js +0 -11
  104. package/dist/server/server/src/validation/authentication/renew-token.js.map +0 -1
  105. package/dist/server/server/src/validation/authentication/renew-token.mjs +0 -9
  106. package/dist/server/server/src/validation/authentication/renew-token.mjs.map +0 -1
  107. package/dist/server/src/validation/authentication/renew-token.d.ts +0 -3
  108. package/dist/server/src/validation/authentication/renew-token.d.ts.map +0 -1
@@ -0,0 +1,91 @@
1
+ 'use strict';
2
+
3
+ var session = {
4
+ collectionName: 'strapi_sessions',
5
+ info: {
6
+ name: 'Session',
7
+ description: 'Session Manager storage',
8
+ singularName: 'session',
9
+ pluralName: 'sessions',
10
+ displayName: 'Session'
11
+ },
12
+ options: {
13
+ draftAndPublish: false
14
+ },
15
+ pluginOptions: {
16
+ 'content-manager': {
17
+ visible: false
18
+ },
19
+ 'content-type-builder': {
20
+ visible: false
21
+ },
22
+ i18n: {
23
+ localized: false
24
+ }
25
+ },
26
+ attributes: {
27
+ userId: {
28
+ type: 'string',
29
+ required: true,
30
+ configurable: false,
31
+ private: true,
32
+ searchable: false
33
+ },
34
+ sessionId: {
35
+ type: 'string',
36
+ unique: true,
37
+ required: true,
38
+ configurable: false,
39
+ private: true,
40
+ searchable: false
41
+ },
42
+ childId: {
43
+ type: 'string',
44
+ configurable: false,
45
+ private: true,
46
+ searchable: false
47
+ },
48
+ deviceId: {
49
+ type: 'string',
50
+ required: true,
51
+ configurable: false,
52
+ private: true,
53
+ searchable: false
54
+ },
55
+ origin: {
56
+ type: 'string',
57
+ required: true,
58
+ configurable: false,
59
+ private: true,
60
+ searchable: false
61
+ },
62
+ expiresAt: {
63
+ type: 'datetime',
64
+ required: true,
65
+ configurable: false,
66
+ private: true,
67
+ searchable: false
68
+ },
69
+ absoluteExpiresAt: {
70
+ type: 'datetime',
71
+ configurable: false,
72
+ private: true,
73
+ searchable: false
74
+ },
75
+ status: {
76
+ type: 'string',
77
+ configurable: false,
78
+ private: true,
79
+ searchable: false
80
+ },
81
+ type: {
82
+ type: 'string',
83
+ configurable: false,
84
+ private: true,
85
+ searchable: false
86
+ }
87
+ }
88
+ };
89
+
90
+ module.exports = session;
91
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sources":["../../../../../server/src/content-types/session.ts"],"sourcesContent":["export default {\n collectionName: 'strapi_sessions',\n info: {\n name: 'Session',\n description: 'Session Manager storage',\n singularName: 'session',\n pluralName: 'sessions',\n displayName: 'Session',\n },\n options: {\n draftAndPublish: false,\n },\n pluginOptions: {\n 'content-manager': {\n visible: false,\n },\n 'content-type-builder': {\n visible: false,\n },\n i18n: {\n localized: false,\n },\n },\n attributes: {\n userId: {\n type: 'string',\n required: true,\n configurable: false,\n private: true,\n searchable: false,\n },\n sessionId: {\n type: 'string',\n unique: true,\n required: true,\n configurable: false,\n private: true,\n searchable: false,\n },\n childId: {\n type: 'string',\n configurable: false,\n private: true,\n searchable: false,\n },\n deviceId: {\n type: 'string',\n required: true,\n configurable: false,\n private: true,\n searchable: false,\n },\n origin: {\n type: 'string',\n required: true,\n configurable: false,\n private: true,\n searchable: false,\n },\n expiresAt: {\n type: 'datetime',\n required: true,\n configurable: false,\n private: true,\n searchable: false,\n },\n absoluteExpiresAt: {\n type: 'datetime',\n configurable: false,\n private: true,\n searchable: false,\n },\n status: {\n type: 'string',\n configurable: false,\n private: true,\n searchable: false,\n },\n type: {\n type: 'string',\n configurable: false,\n private: true,\n searchable: false,\n },\n },\n};\n"],"names":["collectionName","info","name","description","singularName","pluralName","displayName","options","draftAndPublish","pluginOptions","visible","i18n","localized","attributes","userId","type","required","configurable","private","searchable","sessionId","unique","childId","deviceId","origin","expiresAt","absoluteExpiresAt","status"],"mappings":";;AAAA,cAAe;IACbA,cAAgB,EAAA,iBAAA;IAChBC,IAAM,EAAA;QACJC,IAAM,EAAA,SAAA;QACNC,WAAa,EAAA,yBAAA;QACbC,YAAc,EAAA,SAAA;QACdC,UAAY,EAAA,UAAA;QACZC,WAAa,EAAA;AACf,KAAA;IACAC,OAAS,EAAA;QACPC,eAAiB,EAAA;AACnB,KAAA;IACAC,aAAe,EAAA;QACb,iBAAmB,EAAA;YACjBC,OAAS,EAAA;AACX,SAAA;QACA,sBAAwB,EAAA;YACtBA,OAAS,EAAA;AACX,SAAA;QACAC,IAAM,EAAA;YACJC,SAAW,EAAA;AACb;AACF,KAAA;IACAC,UAAY,EAAA;QACVC,MAAQ,EAAA;YACNC,IAAM,EAAA,QAAA;YACNC,QAAU,EAAA,IAAA;YACVC,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAC,SAAW,EAAA;YACTL,IAAM,EAAA,QAAA;YACNM,MAAQ,EAAA,IAAA;YACRL,QAAU,EAAA,IAAA;YACVC,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAG,OAAS,EAAA;YACPP,IAAM,EAAA,QAAA;YACNE,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAI,QAAU,EAAA;YACRR,IAAM,EAAA,QAAA;YACNC,QAAU,EAAA,IAAA;YACVC,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAK,MAAQ,EAAA;YACNT,IAAM,EAAA,QAAA;YACNC,QAAU,EAAA,IAAA;YACVC,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAM,SAAW,EAAA;YACTV,IAAM,EAAA,UAAA;YACNC,QAAU,EAAA,IAAA;YACVC,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAO,iBAAmB,EAAA;YACjBX,IAAM,EAAA,UAAA;YACNE,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAQ,MAAQ,EAAA;YACNZ,IAAM,EAAA,QAAA;YACNE,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAJ,IAAM,EAAA;YACJA,IAAM,EAAA,QAAA;YACNE,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd;AACF;AACF,CAAE;;;;"}
@@ -0,0 +1,89 @@
1
+ var session = {
2
+ collectionName: 'strapi_sessions',
3
+ info: {
4
+ name: 'Session',
5
+ description: 'Session Manager storage',
6
+ singularName: 'session',
7
+ pluralName: 'sessions',
8
+ displayName: 'Session'
9
+ },
10
+ options: {
11
+ draftAndPublish: false
12
+ },
13
+ pluginOptions: {
14
+ 'content-manager': {
15
+ visible: false
16
+ },
17
+ 'content-type-builder': {
18
+ visible: false
19
+ },
20
+ i18n: {
21
+ localized: false
22
+ }
23
+ },
24
+ attributes: {
25
+ userId: {
26
+ type: 'string',
27
+ required: true,
28
+ configurable: false,
29
+ private: true,
30
+ searchable: false
31
+ },
32
+ sessionId: {
33
+ type: 'string',
34
+ unique: true,
35
+ required: true,
36
+ configurable: false,
37
+ private: true,
38
+ searchable: false
39
+ },
40
+ childId: {
41
+ type: 'string',
42
+ configurable: false,
43
+ private: true,
44
+ searchable: false
45
+ },
46
+ deviceId: {
47
+ type: 'string',
48
+ required: true,
49
+ configurable: false,
50
+ private: true,
51
+ searchable: false
52
+ },
53
+ origin: {
54
+ type: 'string',
55
+ required: true,
56
+ configurable: false,
57
+ private: true,
58
+ searchable: false
59
+ },
60
+ expiresAt: {
61
+ type: 'datetime',
62
+ required: true,
63
+ configurable: false,
64
+ private: true,
65
+ searchable: false
66
+ },
67
+ absoluteExpiresAt: {
68
+ type: 'datetime',
69
+ configurable: false,
70
+ private: true,
71
+ searchable: false
72
+ },
73
+ status: {
74
+ type: 'string',
75
+ configurable: false,
76
+ private: true,
77
+ searchable: false
78
+ },
79
+ type: {
80
+ type: 'string',
81
+ configurable: false,
82
+ private: true,
83
+ searchable: false
84
+ }
85
+ }
86
+ };
87
+
88
+ export { session as default };
89
+ //# sourceMappingURL=session.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.mjs","sources":["../../../../../server/src/content-types/session.ts"],"sourcesContent":["export default {\n collectionName: 'strapi_sessions',\n info: {\n name: 'Session',\n description: 'Session Manager storage',\n singularName: 'session',\n pluralName: 'sessions',\n displayName: 'Session',\n },\n options: {\n draftAndPublish: false,\n },\n pluginOptions: {\n 'content-manager': {\n visible: false,\n },\n 'content-type-builder': {\n visible: false,\n },\n i18n: {\n localized: false,\n },\n },\n attributes: {\n userId: {\n type: 'string',\n required: true,\n configurable: false,\n private: true,\n searchable: false,\n },\n sessionId: {\n type: 'string',\n unique: true,\n required: true,\n configurable: false,\n private: true,\n searchable: false,\n },\n childId: {\n type: 'string',\n configurable: false,\n private: true,\n searchable: false,\n },\n deviceId: {\n type: 'string',\n required: true,\n configurable: false,\n private: true,\n searchable: false,\n },\n origin: {\n type: 'string',\n required: true,\n configurable: false,\n private: true,\n searchable: false,\n },\n expiresAt: {\n type: 'datetime',\n required: true,\n configurable: false,\n private: true,\n searchable: false,\n },\n absoluteExpiresAt: {\n type: 'datetime',\n configurable: false,\n private: true,\n searchable: false,\n },\n status: {\n type: 'string',\n configurable: false,\n private: true,\n searchable: false,\n },\n type: {\n type: 'string',\n configurable: false,\n private: true,\n searchable: false,\n },\n },\n};\n"],"names":["collectionName","info","name","description","singularName","pluralName","displayName","options","draftAndPublish","pluginOptions","visible","i18n","localized","attributes","userId","type","required","configurable","private","searchable","sessionId","unique","childId","deviceId","origin","expiresAt","absoluteExpiresAt","status"],"mappings":"AAAA,cAAe;IACbA,cAAgB,EAAA,iBAAA;IAChBC,IAAM,EAAA;QACJC,IAAM,EAAA,SAAA;QACNC,WAAa,EAAA,yBAAA;QACbC,YAAc,EAAA,SAAA;QACdC,UAAY,EAAA,UAAA;QACZC,WAAa,EAAA;AACf,KAAA;IACAC,OAAS,EAAA;QACPC,eAAiB,EAAA;AACnB,KAAA;IACAC,aAAe,EAAA;QACb,iBAAmB,EAAA;YACjBC,OAAS,EAAA;AACX,SAAA;QACA,sBAAwB,EAAA;YACtBA,OAAS,EAAA;AACX,SAAA;QACAC,IAAM,EAAA;YACJC,SAAW,EAAA;AACb;AACF,KAAA;IACAC,UAAY,EAAA;QACVC,MAAQ,EAAA;YACNC,IAAM,EAAA,QAAA;YACNC,QAAU,EAAA,IAAA;YACVC,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAC,SAAW,EAAA;YACTL,IAAM,EAAA,QAAA;YACNM,MAAQ,EAAA,IAAA;YACRL,QAAU,EAAA,IAAA;YACVC,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAG,OAAS,EAAA;YACPP,IAAM,EAAA,QAAA;YACNE,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAI,QAAU,EAAA;YACRR,IAAM,EAAA,QAAA;YACNC,QAAU,EAAA,IAAA;YACVC,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAK,MAAQ,EAAA;YACNT,IAAM,EAAA,QAAA;YACNC,QAAU,EAAA,IAAA;YACVC,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAM,SAAW,EAAA;YACTV,IAAM,EAAA,UAAA;YACNC,QAAU,EAAA,IAAA;YACVC,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAO,iBAAmB,EAAA;YACjBX,IAAM,EAAA,UAAA;YACNE,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAQ,MAAQ,EAAA;YACNZ,IAAM,EAAA,QAAA;YACNE,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd,SAAA;QACAJ,IAAM,EAAA;YACJA,IAAM,EAAA,QAAA;YACNE,YAAc,EAAA,KAAA;YACdC,OAAS,EAAA,IAAA;YACTC,UAAY,EAAA;AACd;AACF;AACF,CAAE;;;;"}
@@ -5,14 +5,19 @@ var compose = require('koa-compose');
5
5
  require('@strapi/types');
6
6
  var utils = require('@strapi/utils');
7
7
  var index = require('../utils/index.js');
8
+ var sessionAuth = require('../../../shared/utils/session-auth.js');
8
9
  var register = require('../validation/authentication/register.js');
9
10
  var forgotPassword = require('../validation/authentication/forgot-password.js');
10
11
  var resetPassword = require('../validation/authentication/reset-password.js');
11
- var renewToken = require('../validation/authentication/renew-token.js');
12
+ var login = require('../validation/authentication/login.js');
12
13
 
13
14
  const { ApplicationError, ValidationError } = utils.errors;
14
15
  var authentication = {
15
16
  login: compose([
17
+ async (ctx, next)=>{
18
+ await login(ctx.request.body ?? {});
19
+ return next();
20
+ },
16
21
  (ctx, next)=>{
17
22
  return passport.authenticate('local', {
18
23
  session: false
@@ -46,31 +51,38 @@ var authentication = {
46
51
  return next();
47
52
  })(ctx, next);
48
53
  },
49
- (ctx)=>{
54
+ async (ctx)=>{
50
55
  const { user } = ctx.state;
51
- ctx.body = {
52
- data: {
53
- token: index.getService('token').createJwtToken(user),
54
- user: index.getService('user').sanitizeUser(ctx.state.user)
56
+ try {
57
+ const sessionManager = sessionAuth.getSessionManager();
58
+ if (!sessionManager) {
59
+ return ctx.internalServerError();
55
60
  }
56
- };
61
+ const userId = String(user.id);
62
+ const { deviceId, rememberMe } = sessionAuth.extractDeviceParams(ctx.request.body);
63
+ const { token: refreshToken, absoluteExpiresAt } = await sessionManager('admin').generateRefreshToken(userId, deviceId, {
64
+ type: rememberMe ? 'refresh' : 'session'
65
+ });
66
+ const cookieOptions = sessionAuth.buildCookieOptionsWithExpiry(rememberMe ? 'refresh' : 'session', absoluteExpiresAt);
67
+ ctx.cookies.set(sessionAuth.REFRESH_COOKIE_NAME, refreshToken, cookieOptions);
68
+ const accessResult = await sessionManager('admin').generateAccessToken(refreshToken);
69
+ if ('error' in accessResult) {
70
+ return ctx.internalServerError();
71
+ }
72
+ const { token: accessToken } = accessResult;
73
+ ctx.body = {
74
+ data: {
75
+ token: accessToken,
76
+ accessToken,
77
+ user: index.getService('user').sanitizeUser(ctx.state.user)
78
+ }
79
+ };
80
+ } catch (error) {
81
+ strapi.log.error('Failed to create admin refresh session', error);
82
+ return ctx.internalServerError();
83
+ }
57
84
  }
58
85
  ]),
59
- async renewToken (ctx) {
60
- await renewToken(ctx.request.body);
61
- const { token } = ctx.request.body;
62
- const { isValid, payload } = index.getService('token').decodeJwtToken(token);
63
- if (!isValid) {
64
- throw new ValidationError('Invalid token');
65
- }
66
- ctx.body = {
67
- data: {
68
- token: index.getService('token').createJwtToken({
69
- id: payload.id
70
- })
71
- }
72
- };
73
- },
74
86
  async registrationInfo (ctx) {
75
87
  await register.validateRegistrationInfoQuery(ctx.request.query);
76
88
  const { registrationToken } = ctx.request.query;
@@ -86,12 +98,34 @@ var authentication = {
86
98
  const input = ctx.request.body;
87
99
  await register.validateRegistrationInput(input);
88
100
  const user = await index.getService('user').register(input);
89
- ctx.body = {
90
- data: {
91
- token: index.getService('token').createJwtToken(user),
92
- user: index.getService('user').sanitizeUser(user)
101
+ try {
102
+ const sessionManager = sessionAuth.getSessionManager();
103
+ if (!sessionManager) {
104
+ return ctx.internalServerError();
93
105
  }
94
- };
106
+ const userId = String(user.id);
107
+ const { deviceId, rememberMe } = sessionAuth.extractDeviceParams(ctx.request.body);
108
+ const { token: refreshToken, absoluteExpiresAt } = await sessionManager('admin').generateRefreshToken(userId, deviceId, {
109
+ type: rememberMe ? 'refresh' : 'session'
110
+ });
111
+ const cookieOptions = sessionAuth.buildCookieOptionsWithExpiry(rememberMe ? 'refresh' : 'session', absoluteExpiresAt);
112
+ ctx.cookies.set(sessionAuth.REFRESH_COOKIE_NAME, refreshToken, cookieOptions);
113
+ const accessResult = await sessionManager('admin').generateAccessToken(refreshToken);
114
+ if ('error' in accessResult) {
115
+ return ctx.internalServerError();
116
+ }
117
+ const { token: accessToken } = accessResult;
118
+ ctx.body = {
119
+ data: {
120
+ token: accessToken,
121
+ accessToken,
122
+ user: index.getService('user').sanitizeUser(user)
123
+ }
124
+ };
125
+ } catch (error) {
126
+ strapi.log.error('Failed to create admin refresh session during register', error);
127
+ return ctx.internalServerError();
128
+ }
95
129
  },
96
130
  async registerAdmin (ctx) {
97
131
  const input = ctx.request.body;
@@ -113,12 +147,34 @@ var authentication = {
113
147
  ] : []
114
148
  });
115
149
  strapi.telemetry.send('didCreateFirstAdmin');
116
- ctx.body = {
117
- data: {
118
- token: index.getService('token').createJwtToken(user),
119
- user: index.getService('user').sanitizeUser(user)
150
+ try {
151
+ const sessionManager = sessionAuth.getSessionManager();
152
+ if (!sessionManager) {
153
+ return ctx.internalServerError();
120
154
  }
121
- };
155
+ const userId = String(user.id);
156
+ const { deviceId, rememberMe } = sessionAuth.extractDeviceParams(ctx.request.body);
157
+ const { token: refreshToken, absoluteExpiresAt } = await sessionManager('admin').generateRefreshToken(userId, deviceId, {
158
+ type: rememberMe ? 'refresh' : 'session'
159
+ });
160
+ const cookieOptions = sessionAuth.buildCookieOptionsWithExpiry(rememberMe ? 'refresh' : 'session', absoluteExpiresAt);
161
+ ctx.cookies.set(sessionAuth.REFRESH_COOKIE_NAME, refreshToken, cookieOptions);
162
+ const accessResult = await sessionManager('admin').generateAccessToken(refreshToken);
163
+ if ('error' in accessResult) {
164
+ return ctx.internalServerError();
165
+ }
166
+ const { token: accessToken } = accessResult;
167
+ ctx.body = {
168
+ data: {
169
+ token: accessToken,
170
+ accessToken,
171
+ user: index.getService('user').sanitizeUser(user)
172
+ }
173
+ };
174
+ } catch (error) {
175
+ strapi.log.error('Failed to create admin refresh session during register-admin', error);
176
+ return ctx.internalServerError();
177
+ }
122
178
  },
123
179
  async forgotPassword (ctx) {
124
180
  const input = ctx.request.body;
@@ -130,18 +186,93 @@ var authentication = {
130
186
  const input = ctx.request.body;
131
187
  await resetPassword(input);
132
188
  const user = await index.getService('auth').resetPassword(input);
133
- ctx.body = {
134
- data: {
135
- token: index.getService('token').createJwtToken(user),
136
- user: index.getService('user').sanitizeUser(user)
189
+ // Issue a new admin refresh session and access token after password reset.
190
+ try {
191
+ const sessionManager = sessionAuth.getSessionManager();
192
+ if (!sessionManager) {
193
+ return ctx.internalServerError();
137
194
  }
138
- };
195
+ const userId = String(user.id);
196
+ const deviceId = sessionAuth.generateDeviceId();
197
+ // Invalidate all existing sessions before creating a new one
198
+ await sessionManager('admin').invalidateRefreshToken(userId);
199
+ const { token: refreshToken, absoluteExpiresAt } = await sessionManager('admin').generateRefreshToken(userId, deviceId, {
200
+ type: 'session'
201
+ });
202
+ // No rememberMe flow here; expire with session by default (session cookie)
203
+ const cookieOptions = sessionAuth.buildCookieOptionsWithExpiry('session', absoluteExpiresAt);
204
+ ctx.cookies.set(sessionAuth.REFRESH_COOKIE_NAME, refreshToken, cookieOptions);
205
+ const accessResult = await sessionManager('admin').generateAccessToken(refreshToken);
206
+ if ('error' in accessResult) {
207
+ return ctx.internalServerError();
208
+ }
209
+ const { token } = accessResult;
210
+ ctx.body = {
211
+ data: {
212
+ token,
213
+ user: index.getService('user').sanitizeUser(user)
214
+ }
215
+ };
216
+ } catch (err) {
217
+ strapi.log.error('Failed to create admin refresh session during reset-password', err);
218
+ return ctx.internalServerError();
219
+ }
139
220
  },
140
- logout (ctx) {
221
+ async accessToken (ctx) {
222
+ const refreshToken = ctx.cookies.get(sessionAuth.REFRESH_COOKIE_NAME);
223
+ if (!refreshToken) {
224
+ return ctx.unauthorized('Missing refresh token');
225
+ }
226
+ try {
227
+ const sessionManager = sessionAuth.getSessionManager();
228
+ if (!sessionManager) {
229
+ return ctx.internalServerError();
230
+ }
231
+ // Single-use renewal: rotate on access exchange, then create access token
232
+ // from the new refresh token
233
+ const rotation = await sessionManager('admin').rotateRefreshToken(refreshToken);
234
+ if ('error' in rotation) {
235
+ return ctx.unauthorized('Invalid refresh token');
236
+ }
237
+ const result = await sessionManager('admin').generateAccessToken(rotation.token);
238
+ if ('error' in result) {
239
+ return ctx.unauthorized('Invalid refresh token');
240
+ }
241
+ const { token } = result;
242
+ // Preserve session-vs-remember mode using rotation.type and rotation.absoluteExpiresAt
243
+ const opts = sessionAuth.buildCookieOptionsWithExpiry(rotation.type, rotation.absoluteExpiresAt);
244
+ ctx.cookies.set(sessionAuth.REFRESH_COOKIE_NAME, rotation.token, opts);
245
+ ctx.body = {
246
+ data: {
247
+ token
248
+ }
249
+ };
250
+ } catch (err) {
251
+ strapi.log.error('Failed to generate access token from refresh token', err);
252
+ return ctx.internalServerError();
253
+ }
254
+ },
255
+ async logout (ctx) {
141
256
  const sanitizedUser = index.getService('user').sanitizeUser(ctx.state.user);
142
257
  strapi.eventHub.emit('admin.logout', {
143
258
  user: sanitizedUser
144
259
  });
260
+ const bodyDeviceId = ctx.request.body?.deviceId;
261
+ const deviceId = typeof bodyDeviceId === 'string' ? bodyDeviceId : undefined;
262
+ // Clear cookie regardless of token validity
263
+ ctx.cookies.set(sessionAuth.REFRESH_COOKIE_NAME, '', {
264
+ ...sessionAuth.getRefreshCookieOptions(),
265
+ expires: new Date(0)
266
+ });
267
+ try {
268
+ const sessionManager = sessionAuth.getSessionManager();
269
+ if (sessionManager) {
270
+ const userId = String(ctx.state.user.id);
271
+ await sessionManager('admin').invalidateRefreshToken(userId, deviceId);
272
+ }
273
+ } catch (err) {
274
+ strapi.log.error('Failed to revoke admin sessions during logout', err);
275
+ }
145
276
  ctx.body = {
146
277
  data: {}
147
278
  };
@@ -1 +1 @@
1
- {"version":3,"file":"authentication.js","sources":["../../../../../server/src/controllers/authentication.ts"],"sourcesContent":["import type { Context, Next } from 'koa';\nimport passport from 'koa-passport';\nimport compose from 'koa-compose';\nimport '@strapi/types';\nimport { errors } from '@strapi/utils';\nimport { getService } from '../utils';\nimport {\n validateRegistrationInput,\n validateAdminRegistrationInput,\n validateRegistrationInfoQuery,\n validateForgotPasswordInput,\n validateResetPasswordInput,\n validateRenewTokenInput,\n} from '../validation/authentication';\n\nimport type {\n ForgotPassword,\n Login,\n Register,\n RegistrationInfo,\n RenewToken,\n ResetPassword,\n} from '../../../shared/contracts/authentication';\nimport { AdminUser } from '../../../shared/contracts/shared';\n\nconst { ApplicationError, ValidationError } = errors;\n\nexport default {\n login: compose([\n (ctx: Context, next: Next) => {\n return passport.authenticate('local', { session: false }, (err, user, info) => {\n if (err) {\n strapi.eventHub.emit('admin.auth.error', { error: err, provider: 'local' });\n // if this is a recognized error, allow it to bubble up to user\n if (err.details?.code === 'LOGIN_NOT_ALLOWED') {\n throw err;\n }\n\n // for all other errors throw a generic error to prevent leaking info\n return ctx.notImplemented();\n }\n\n if (!user) {\n strapi.eventHub.emit('admin.auth.error', {\n error: new Error(info.message),\n provider: 'local',\n });\n throw new ApplicationError(info.message);\n }\n\n const query = ctx.state as Login.Request['query'];\n query.user = user;\n\n const sanitizedUser = getService('user').sanitizeUser(user);\n strapi.eventHub.emit('admin.auth.success', { user: sanitizedUser, provider: 'local' });\n\n return next();\n })(ctx, next);\n },\n (ctx: Context) => {\n const { user } = ctx.state as { user: AdminUser };\n\n ctx.body = {\n data: {\n token: getService('token').createJwtToken(user),\n user: getService('user').sanitizeUser(ctx.state.user), // TODO: fetch more detailed info\n },\n } satisfies Login.Response;\n },\n ]),\n\n async renewToken(ctx: Context) {\n await validateRenewTokenInput(ctx.request.body);\n\n const { token } = ctx.request.body as RenewToken.Request['body'];\n\n const { isValid, payload } = getService('token').decodeJwtToken(token);\n\n if (!isValid) {\n throw new ValidationError('Invalid token');\n }\n\n ctx.body = {\n data: {\n token: getService('token').createJwtToken({ id: payload.id }),\n },\n } satisfies RenewToken.Response;\n },\n\n async registrationInfo(ctx: Context) {\n await validateRegistrationInfoQuery(ctx.request.query);\n\n const { registrationToken } = ctx.request.query as RegistrationInfo.Request['query'];\n\n const registrationInfo = await getService('user').findRegistrationInfo(registrationToken);\n\n if (!registrationInfo) {\n throw new ValidationError('Invalid registrationToken');\n }\n\n ctx.body = { data: registrationInfo } satisfies RegistrationInfo.Response;\n },\n\n async register(ctx: Context) {\n const input = ctx.request.body as Register.Request['body'];\n\n await validateRegistrationInput(input);\n\n const user = await getService('user').register(input);\n\n ctx.body = {\n data: {\n token: getService('token').createJwtToken(user),\n user: getService('user').sanitizeUser(user),\n },\n } satisfies Register.Response;\n },\n\n async registerAdmin(ctx: Context) {\n const input = ctx.request.body as Register.Request['body'];\n\n await validateAdminRegistrationInput(input);\n\n const hasAdmin = await getService('user').exists();\n\n if (hasAdmin) {\n throw new ApplicationError('You cannot register a new super admin');\n }\n\n const superAdminRole = await getService('role').getSuperAdmin();\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 user = await getService('user').create({\n ...input,\n registrationToken: null,\n isActive: true,\n roles: superAdminRole ? [superAdminRole.id] : [],\n });\n\n strapi.telemetry.send('didCreateFirstAdmin');\n\n ctx.body = {\n data: {\n token: getService('token').createJwtToken(user),\n user: getService('user').sanitizeUser(user),\n },\n };\n },\n\n async forgotPassword(ctx: Context) {\n const input = ctx.request.body as ForgotPassword.Request['body'];\n\n await validateForgotPasswordInput(input);\n\n getService('auth').forgotPassword(input);\n\n ctx.status = 204;\n },\n\n async resetPassword(ctx: Context) {\n const input = ctx.request.body as ResetPassword.Request['body'];\n\n await validateResetPasswordInput(input);\n\n const user = await getService('auth').resetPassword(input);\n\n ctx.body = {\n data: {\n token: getService('token').createJwtToken(user),\n user: getService('user').sanitizeUser(user),\n },\n } satisfies ResetPassword.Response;\n },\n\n logout(ctx: Context) {\n const sanitizedUser = getService('user').sanitizeUser(ctx.state.user);\n strapi.eventHub.emit('admin.logout', { user: sanitizedUser });\n ctx.body = { data: {} };\n },\n};\n"],"names":["ApplicationError","ValidationError","errors","login","compose","ctx","next","passport","authenticate","session","err","user","info","strapi","eventHub","emit","error","provider","details","code","notImplemented","Error","message","query","state","sanitizedUser","getService","sanitizeUser","body","data","token","createJwtToken","renewToken","validateRenewTokenInput","request","isValid","payload","decodeJwtToken","id","registrationInfo","validateRegistrationInfoQuery","registrationToken","findRegistrationInfo","register","input","validateRegistrationInput","registerAdmin","validateAdminRegistrationInput","hasAdmin","exists","superAdminRole","getSuperAdmin","create","isActive","roles","telemetry","send","forgotPassword","validateForgotPasswordInput","status","resetPassword","validateResetPasswordInput","logout"],"mappings":"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"}
1
+ {"version":3,"file":"authentication.js","sources":["../../../../../server/src/controllers/authentication.ts"],"sourcesContent":["import type { Context, Next } from 'koa';\nimport passport from 'koa-passport';\nimport compose from 'koa-compose';\nimport '@strapi/types';\nimport { errors } from '@strapi/utils';\nimport { getService } from '../utils';\nimport {\n REFRESH_COOKIE_NAME,\n buildCookieOptionsWithExpiry,\n getSessionManager,\n extractDeviceParams,\n generateDeviceId,\n getRefreshCookieOptions,\n} from '../../../shared/utils/session-auth';\n\nimport {\n validateRegistrationInput,\n validateAdminRegistrationInput,\n validateRegistrationInfoQuery,\n validateForgotPasswordInput,\n validateResetPasswordInput,\n validateLoginSessionInput,\n} from '../validation/authentication';\n\nimport type {\n ForgotPassword,\n Login,\n Register,\n RegistrationInfo,\n ResetPassword,\n} from '../../../shared/contracts/authentication';\nimport { AdminUser } from '../../../shared/contracts/shared';\n\nconst { ApplicationError, ValidationError } = errors;\n\nexport default {\n login: compose([\n async (ctx: Context, next: Next) => {\n await validateLoginSessionInput(ctx.request.body ?? {});\n return next();\n },\n (ctx: Context, next: Next) => {\n return passport.authenticate('local', { session: false }, (err, user, info) => {\n if (err) {\n strapi.eventHub.emit('admin.auth.error', { error: err, provider: 'local' });\n // if this is a recognized error, allow it to bubble up to user\n if (err.details?.code === 'LOGIN_NOT_ALLOWED') {\n throw err;\n }\n\n // for all other errors throw a generic error to prevent leaking info\n return ctx.notImplemented();\n }\n\n if (!user) {\n strapi.eventHub.emit('admin.auth.error', {\n error: new Error(info.message),\n provider: 'local',\n });\n throw new ApplicationError(info.message);\n }\n\n const query = ctx.state as Login.Request['query'];\n query.user = user;\n\n const sanitizedUser = getService('user').sanitizeUser(user);\n strapi.eventHub.emit('admin.auth.success', { user: sanitizedUser, provider: 'local' });\n\n return next();\n })(ctx, next);\n },\n async (ctx: Context) => {\n const { user } = ctx.state as { user: AdminUser };\n\n try {\n const sessionManager = getSessionManager();\n if (!sessionManager) {\n return ctx.internalServerError();\n }\n const userId = String(user.id);\n const { deviceId, rememberMe } = extractDeviceParams(ctx.request.body);\n\n const { token: refreshToken, absoluteExpiresAt } = await sessionManager(\n 'admin'\n ).generateRefreshToken(userId, deviceId, {\n type: rememberMe ? 'refresh' : 'session',\n });\n\n const cookieOptions = buildCookieOptionsWithExpiry(\n rememberMe ? 'refresh' : 'session',\n absoluteExpiresAt\n );\n ctx.cookies.set(REFRESH_COOKIE_NAME, refreshToken, cookieOptions);\n\n const accessResult = await sessionManager('admin').generateAccessToken(refreshToken);\n if ('error' in accessResult) {\n return ctx.internalServerError();\n }\n\n const { token: accessToken } = accessResult;\n\n ctx.body = {\n data: {\n token: accessToken,\n accessToken,\n user: getService('user').sanitizeUser(ctx.state.user),\n },\n } satisfies Login.Response;\n } catch (error) {\n strapi.log.error('Failed to create admin refresh session', error);\n return ctx.internalServerError();\n }\n },\n ]),\n\n async registrationInfo(ctx: Context) {\n await validateRegistrationInfoQuery(ctx.request.query);\n\n const { registrationToken } = ctx.request.query as RegistrationInfo.Request['query'];\n\n const registrationInfo = await getService('user').findRegistrationInfo(registrationToken);\n\n if (!registrationInfo) {\n throw new ValidationError('Invalid registrationToken');\n }\n\n ctx.body = { data: registrationInfo } satisfies RegistrationInfo.Response;\n },\n\n async register(ctx: Context) {\n const input = ctx.request.body as Register.Request['body'];\n\n await validateRegistrationInput(input);\n\n const user = await getService('user').register(input);\n\n try {\n const sessionManager = getSessionManager();\n if (!sessionManager) {\n return ctx.internalServerError();\n }\n const userId = String(user.id);\n const { deviceId, rememberMe } = extractDeviceParams(ctx.request.body);\n\n const { token: refreshToken, absoluteExpiresAt } = await sessionManager(\n 'admin'\n ).generateRefreshToken(userId, deviceId, { type: rememberMe ? 'refresh' : 'session' });\n\n const cookieOptions = buildCookieOptionsWithExpiry(\n rememberMe ? 'refresh' : 'session',\n absoluteExpiresAt\n );\n ctx.cookies.set(REFRESH_COOKIE_NAME, refreshToken, cookieOptions);\n\n const accessResult = await sessionManager('admin').generateAccessToken(refreshToken);\n if ('error' in accessResult) {\n return ctx.internalServerError();\n }\n\n const { token: accessToken } = accessResult;\n\n ctx.body = {\n data: {\n token: accessToken,\n accessToken,\n user: getService('user').sanitizeUser(user),\n },\n } satisfies Register.Response;\n } catch (error) {\n strapi.log.error('Failed to create admin refresh session during register', error);\n return ctx.internalServerError();\n }\n },\n\n async registerAdmin(ctx: Context) {\n const input = ctx.request.body as Register.Request['body'];\n\n await validateAdminRegistrationInput(input);\n\n const hasAdmin = await getService('user').exists();\n\n if (hasAdmin) {\n throw new ApplicationError('You cannot register a new super admin');\n }\n\n const superAdminRole = await getService('role').getSuperAdmin();\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 user = await getService('user').create({\n ...input,\n registrationToken: null,\n isActive: true,\n roles: superAdminRole ? [superAdminRole.id] : [],\n });\n\n strapi.telemetry.send('didCreateFirstAdmin');\n\n try {\n const sessionManager = getSessionManager();\n if (!sessionManager) {\n return ctx.internalServerError();\n }\n const userId = String(user.id);\n const { deviceId, rememberMe } = extractDeviceParams(ctx.request.body);\n\n const { token: refreshToken, absoluteExpiresAt } = await sessionManager(\n 'admin'\n ).generateRefreshToken(userId, deviceId, { type: rememberMe ? 'refresh' : 'session' });\n\n const cookieOptions = buildCookieOptionsWithExpiry(\n rememberMe ? 'refresh' : 'session',\n absoluteExpiresAt\n );\n ctx.cookies.set(REFRESH_COOKIE_NAME, refreshToken, cookieOptions);\n\n const accessResult = await sessionManager('admin').generateAccessToken(refreshToken);\n if ('error' in accessResult) {\n return ctx.internalServerError();\n }\n\n const { token: accessToken } = accessResult;\n\n ctx.body = {\n data: {\n token: accessToken,\n accessToken,\n user: getService('user').sanitizeUser(user),\n },\n };\n } catch (error) {\n strapi.log.error('Failed to create admin refresh session during register-admin', error);\n return ctx.internalServerError();\n }\n },\n\n async forgotPassword(ctx: Context) {\n const input = ctx.request.body as ForgotPassword.Request['body'];\n\n await validateForgotPasswordInput(input);\n\n getService('auth').forgotPassword(input);\n\n ctx.status = 204;\n },\n\n async resetPassword(ctx: Context) {\n const input = ctx.request.body as ResetPassword.Request['body'];\n\n await validateResetPasswordInput(input);\n\n const user = await getService('auth').resetPassword(input);\n\n // Issue a new admin refresh session and access token after password reset.\n try {\n const sessionManager = getSessionManager();\n if (!sessionManager) {\n return ctx.internalServerError();\n }\n\n const userId = String(user.id);\n const deviceId = generateDeviceId();\n\n // Invalidate all existing sessions before creating a new one\n await sessionManager('admin').invalidateRefreshToken(userId);\n\n const { token: refreshToken, absoluteExpiresAt } = await sessionManager(\n 'admin'\n ).generateRefreshToken(userId, deviceId, { type: 'session' });\n\n // No rememberMe flow here; expire with session by default (session cookie)\n const cookieOptions = buildCookieOptionsWithExpiry('session', absoluteExpiresAt);\n ctx.cookies.set(REFRESH_COOKIE_NAME, refreshToken, cookieOptions);\n\n const accessResult = await sessionManager('admin').generateAccessToken(refreshToken);\n if ('error' in accessResult) {\n return ctx.internalServerError();\n }\n\n const { token } = accessResult;\n\n ctx.body = {\n data: {\n token,\n user: getService('user').sanitizeUser(user),\n },\n } satisfies ResetPassword.Response;\n } catch (err) {\n strapi.log.error('Failed to create admin refresh session during reset-password', err as any);\n return ctx.internalServerError();\n }\n },\n\n async accessToken(ctx: Context) {\n const refreshToken = ctx.cookies.get(REFRESH_COOKIE_NAME);\n\n if (!refreshToken) {\n return ctx.unauthorized('Missing refresh token');\n }\n\n try {\n const sessionManager = getSessionManager();\n if (!sessionManager) {\n return ctx.internalServerError();\n }\n\n // Single-use renewal: rotate on access exchange, then create access token\n // from the new refresh token\n const rotation = await sessionManager('admin').rotateRefreshToken(refreshToken);\n if ('error' in rotation) {\n return ctx.unauthorized('Invalid refresh token');\n }\n\n const result = await sessionManager('admin').generateAccessToken(rotation.token);\n if ('error' in result) {\n return ctx.unauthorized('Invalid refresh token');\n }\n\n const { token } = result;\n // Preserve session-vs-remember mode using rotation.type and rotation.absoluteExpiresAt\n const opts = buildCookieOptionsWithExpiry(rotation.type, rotation.absoluteExpiresAt);\n\n ctx.cookies.set(REFRESH_COOKIE_NAME, rotation.token, opts);\n ctx.body = { data: { token } };\n } catch (err) {\n strapi.log.error('Failed to generate access token from refresh token', err as any);\n return ctx.internalServerError();\n }\n },\n\n async logout(ctx: Context) {\n const sanitizedUser = getService('user').sanitizeUser(ctx.state.user);\n strapi.eventHub.emit('admin.logout', { user: sanitizedUser });\n\n const bodyDeviceId = ctx.request.body?.deviceId as string | undefined;\n const deviceId = typeof bodyDeviceId === 'string' ? bodyDeviceId : undefined;\n\n // Clear cookie regardless of token validity\n ctx.cookies.set(REFRESH_COOKIE_NAME, '', {\n ...getRefreshCookieOptions(),\n expires: new Date(0),\n });\n\n try {\n const sessionManager = getSessionManager();\n if (sessionManager) {\n const userId = String(ctx.state.user.id);\n await sessionManager('admin').invalidateRefreshToken(userId, deviceId);\n }\n } catch (err) {\n strapi.log.error('Failed to revoke admin sessions during logout', err as any);\n }\n\n ctx.body = { data: {} };\n },\n};\n"],"names":["ApplicationError","ValidationError","errors","login","compose","ctx","next","validateLoginSessionInput","request","body","passport","authenticate","session","err","user","info","strapi","eventHub","emit","error","provider","details","code","notImplemented","Error","message","query","state","sanitizedUser","getService","sanitizeUser","sessionManager","getSessionManager","internalServerError","userId","String","id","deviceId","rememberMe","extractDeviceParams","token","refreshToken","absoluteExpiresAt","generateRefreshToken","type","cookieOptions","buildCookieOptionsWithExpiry","cookies","set","REFRESH_COOKIE_NAME","accessResult","generateAccessToken","accessToken","data","log","registrationInfo","validateRegistrationInfoQuery","registrationToken","findRegistrationInfo","register","input","validateRegistrationInput","registerAdmin","validateAdminRegistrationInput","hasAdmin","exists","superAdminRole","getSuperAdmin","create","isActive","roles","telemetry","send","forgotPassword","validateForgotPasswordInput","status","resetPassword","validateResetPasswordInput","generateDeviceId","invalidateRefreshToken","get","unauthorized","rotation","rotateRefreshToken","result","opts","logout","bodyDeviceId","undefined","getRefreshCookieOptions","expires","Date"],"mappings":"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"}