@strapi/admin 5.23.5 → 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.
- package/dist/admin/admin/src/features/Auth.js +9 -28
- package/dist/admin/admin/src/features/Auth.js.map +1 -1
- package/dist/admin/admin/src/features/Auth.mjs +11 -30
- package/dist/admin/admin/src/features/Auth.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Auth/components/Register.js +9 -2
- package/dist/admin/admin/src/pages/Auth/components/Register.js.map +1 -1
- package/dist/admin/admin/src/pages/Auth/components/Register.mjs +9 -2
- package/dist/admin/admin/src/pages/Auth/components/Register.mjs.map +1 -1
- package/dist/admin/admin/src/services/auth.js +7 -6
- package/dist/admin/admin/src/services/auth.js.map +1 -1
- package/dist/admin/admin/src/services/auth.mjs +7 -6
- package/dist/admin/admin/src/services/auth.mjs.map +1 -1
- package/dist/admin/admin/src/utils/baseQuery.js +78 -42
- package/dist/admin/admin/src/utils/baseQuery.js.map +1 -1
- package/dist/admin/admin/src/utils/baseQuery.mjs +79 -43
- package/dist/admin/admin/src/utils/baseQuery.mjs.map +1 -1
- package/dist/admin/admin/src/utils/deviceId.js +38 -0
- package/dist/admin/admin/src/utils/deviceId.js.map +1 -0
- package/dist/admin/admin/src/utils/deviceId.mjs +36 -0
- package/dist/admin/admin/src/utils/deviceId.mjs.map +1 -0
- package/dist/admin/src/services/auth.d.ts +19 -10
- package/dist/admin/src/utils/deviceId.d.ts +5 -0
- package/dist/ee/server/src/controllers/authentication-utils/middlewares.d.ts.map +1 -1
- package/dist/ee/server/src/services/user.d.ts.map +1 -1
- package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js +43 -17
- package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js.map +1 -1
- package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs +43 -17
- package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs.map +1 -1
- package/dist/server/ee/server/src/services/user.js +14 -0
- package/dist/server/ee/server/src/services/user.js.map +1 -1
- package/dist/server/ee/server/src/services/user.mjs +14 -0
- package/dist/server/ee/server/src/services/user.mjs.map +1 -1
- package/dist/server/server/src/bootstrap.js +22 -0
- package/dist/server/server/src/bootstrap.js.map +1 -1
- package/dist/server/server/src/bootstrap.mjs +22 -0
- package/dist/server/server/src/bootstrap.mjs.map +1 -1
- package/dist/server/server/src/content-types/index.js +4 -0
- package/dist/server/server/src/content-types/index.js.map +1 -1
- package/dist/server/server/src/content-types/index.mjs +4 -0
- package/dist/server/server/src/content-types/index.mjs.map +1 -1
- package/dist/server/server/src/content-types/session.js +91 -0
- package/dist/server/server/src/content-types/session.js.map +1 -0
- package/dist/server/server/src/content-types/session.mjs +89 -0
- package/dist/server/server/src/content-types/session.mjs.map +1 -0
- package/dist/server/server/src/controllers/authentication.js +169 -38
- package/dist/server/server/src/controllers/authentication.js.map +1 -1
- package/dist/server/server/src/controllers/authentication.mjs +169 -38
- package/dist/server/server/src/controllers/authentication.mjs.map +1 -1
- package/dist/server/server/src/routes/authentication.js +2 -2
- package/dist/server/server/src/routes/authentication.js.map +1 -1
- package/dist/server/server/src/routes/authentication.mjs +2 -2
- package/dist/server/server/src/routes/authentication.mjs.map +1 -1
- package/dist/server/server/src/services/token.js +44 -31
- package/dist/server/server/src/services/token.js.map +1 -1
- package/dist/server/server/src/services/token.mjs +44 -30
- package/dist/server/server/src/services/token.mjs.map +1 -1
- package/dist/server/server/src/services/user.js +14 -0
- package/dist/server/server/src/services/user.js.map +1 -1
- package/dist/server/server/src/services/user.mjs +14 -0
- package/dist/server/server/src/services/user.mjs.map +1 -1
- package/dist/server/server/src/strategies/admin.js +23 -3
- package/dist/server/server/src/strategies/admin.js.map +1 -1
- package/dist/server/server/src/strategies/admin.mjs +23 -3
- package/dist/server/server/src/strategies/admin.mjs.map +1 -1
- package/dist/server/server/src/validation/authentication/login.js +16 -0
- package/dist/server/server/src/validation/authentication/login.js.map +1 -0
- package/dist/server/server/src/validation/authentication/login.mjs +14 -0
- package/dist/server/server/src/validation/authentication/login.mjs.map +1 -0
- package/dist/server/server/src/validation/authentication/register.js +6 -2
- package/dist/server/server/src/validation/authentication/register.js.map +1 -1
- package/dist/server/server/src/validation/authentication/register.mjs +6 -2
- package/dist/server/server/src/validation/authentication/register.mjs.map +1 -1
- package/dist/server/shared/utils/session-auth.js +76 -0
- package/dist/server/shared/utils/session-auth.js.map +1 -0
- package/dist/server/shared/utils/session-auth.mjs +65 -0
- package/dist/server/shared/utils/session-auth.mjs.map +1 -0
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/content-types/index.d.ts +88 -0
- package/dist/server/src/content-types/index.d.ts.map +1 -1
- package/dist/server/src/content-types/session.d.ts +88 -0
- package/dist/server/src/content-types/session.d.ts.map +1 -0
- package/dist/server/src/controllers/authentication.d.ts +5 -5
- package/dist/server/src/controllers/authentication.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +5 -5
- package/dist/server/src/index.d.ts +93 -5
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/routes/authentication.d.ts.map +1 -1
- package/dist/server/src/services/token.d.ts +11 -19
- package/dist/server/src/services/token.d.ts.map +1 -1
- package/dist/server/src/services/user.d.ts.map +1 -1
- package/dist/server/src/strategies/admin.d.ts.map +1 -1
- package/dist/server/src/validation/authentication/index.d.ts +1 -1
- package/dist/server/src/validation/authentication/index.d.ts.map +1 -1
- package/dist/server/src/validation/authentication/login.d.ts +7 -0
- package/dist/server/src/validation/authentication/login.d.ts.map +1 -0
- package/dist/server/src/validation/authentication/register.d.ts +5 -0
- package/dist/server/src/validation/authentication/register.d.ts.map +1 -1
- package/dist/shared/contracts/authentication.d.ts +20 -10
- package/dist/shared/contracts/authentication.d.ts.map +1 -1
- package/dist/shared/utils/session-auth.d.ts +39 -0
- package/dist/shared/utils/session-auth.d.ts.map +1 -0
- package/package.json +7 -7
- package/dist/server/server/src/validation/authentication/renew-token.js +0 -11
- package/dist/server/server/src/validation/authentication/renew-token.js.map +0 -1
- package/dist/server/server/src/validation/authentication/renew-token.mjs +0 -9
- package/dist/server/server/src/validation/authentication/renew-token.mjs.map +0 -1
- package/dist/server/src/validation/authentication/renew-token.d.ts +0 -3
- package/dist/server/src/validation/authentication/renew-token.d.ts.map +0 -1
|
@@ -1,57 +1,93 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { logout, login } from '../reducer.mjs';
|
|
2
|
+
import { isFetchError, getFetchClient } from './getFetchClient.mjs';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
let refreshPromise = null;
|
|
5
|
+
const isAuthPath = (url)=>/^\/admin\/(login|logout|access-token)\b/.test(url);
|
|
6
|
+
const simpleQuery = async (query, api)=>{
|
|
7
|
+
const { signal, dispatch } = api;
|
|
8
|
+
const executeQuery = async (queryToExecute)=>{
|
|
5
9
|
const { get, post, del, put } = getFetchClient();
|
|
6
|
-
if (typeof
|
|
7
|
-
const result = await get(
|
|
10
|
+
if (typeof queryToExecute === 'string') {
|
|
11
|
+
const result = await get(queryToExecute, {
|
|
8
12
|
signal
|
|
9
13
|
});
|
|
10
|
-
return
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (method === 'POST') {
|
|
16
|
-
const result = await post(url, data, {
|
|
17
|
-
...config,
|
|
18
|
-
signal
|
|
19
|
-
});
|
|
20
|
-
return {
|
|
21
|
-
data: result.data
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
if (method === 'DELETE') {
|
|
25
|
-
const result = await del(url, {
|
|
26
|
-
...config,
|
|
27
|
-
signal
|
|
28
|
-
});
|
|
29
|
-
return {
|
|
30
|
-
data: result.data
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
if (method === 'PUT') {
|
|
34
|
-
const result = await put(url, data, {
|
|
35
|
-
...config,
|
|
36
|
-
signal
|
|
37
|
-
});
|
|
38
|
-
return {
|
|
39
|
-
data: result.data
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Default is GET.
|
|
44
|
-
*/ const result = await get(url, {
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
const { url, method = 'GET', data, config } = queryToExecute;
|
|
17
|
+
if (method === 'POST') {
|
|
18
|
+
return post(url, data, {
|
|
45
19
|
...config,
|
|
46
20
|
signal
|
|
47
21
|
});
|
|
48
|
-
return {
|
|
49
|
-
data: result.data
|
|
50
|
-
};
|
|
51
22
|
}
|
|
23
|
+
if (method === 'DELETE') {
|
|
24
|
+
return del(url, {
|
|
25
|
+
...config,
|
|
26
|
+
signal
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (method === 'PUT') {
|
|
30
|
+
return put(url, data, {
|
|
31
|
+
...config,
|
|
32
|
+
signal
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return get(url, {
|
|
36
|
+
...config,
|
|
37
|
+
signal
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
try {
|
|
41
|
+
const result = await executeQuery(query);
|
|
42
|
+
return {
|
|
43
|
+
data: result.data
|
|
44
|
+
};
|
|
52
45
|
} catch (err) {
|
|
53
46
|
// Handle error of type FetchError
|
|
54
47
|
if (isFetchError(err)) {
|
|
48
|
+
// Attempt auto-refresh on 401 then retry once
|
|
49
|
+
if (err.status === 401) {
|
|
50
|
+
const url = typeof query === 'string' ? query : query.url;
|
|
51
|
+
if (!isAuthPath(url)) {
|
|
52
|
+
if (!refreshPromise) {
|
|
53
|
+
async function refreshAccessToken() {
|
|
54
|
+
const { post } = getFetchClient();
|
|
55
|
+
const res = await post('/admin/access-token');
|
|
56
|
+
const token = res?.data?.data?.token;
|
|
57
|
+
if (!token) {
|
|
58
|
+
throw new Error('access_token_exchange_failed');
|
|
59
|
+
}
|
|
60
|
+
// Persist according to previous choice: localStorage presence implies persist
|
|
61
|
+
const persist = Boolean(localStorage.getItem('jwtToken'));
|
|
62
|
+
dispatch(login({
|
|
63
|
+
token,
|
|
64
|
+
persist
|
|
65
|
+
}));
|
|
66
|
+
return token;
|
|
67
|
+
}
|
|
68
|
+
refreshPromise = refreshAccessToken().finally(()=>{
|
|
69
|
+
refreshPromise = null;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
await refreshPromise;
|
|
74
|
+
// Retry original request once with updated Authorization
|
|
75
|
+
const retry = await executeQuery(query);
|
|
76
|
+
return {
|
|
77
|
+
data: retry.data
|
|
78
|
+
};
|
|
79
|
+
} catch (refreshError) {
|
|
80
|
+
try {
|
|
81
|
+
const { post } = getFetchClient();
|
|
82
|
+
await post('/admin/logout');
|
|
83
|
+
} catch {
|
|
84
|
+
// no-op
|
|
85
|
+
}
|
|
86
|
+
dispatch(logout());
|
|
87
|
+
// Fall through to return the original 401 error shape
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
55
91
|
if (typeof err.response?.data === 'object' && err.response?.data !== null && 'error' in err.response?.data) {
|
|
56
92
|
/**
|
|
57
93
|
* This will most likely be ApiError
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseQuery.mjs","sources":["../../../../../admin/src/utils/baseQuery.ts"],"sourcesContent":["import { SerializedError } from '@reduxjs/toolkit';\nimport { BaseQueryFn } from '@reduxjs/toolkit/query';\n\nimport { getFetchClient, type FetchOptions, ApiError, isFetchError } from '../utils/getFetchClient';\n\ninterface QueryArguments {\n url: string;\n method?: 'GET' | 'POST' | 'DELETE' | 'PUT';\n data?: unknown;\n config?: FetchOptions;\n}\n\ninterface UnknownApiError {\n name: 'UnknownError';\n message: string;\n details?: unknown;\n status?: number;\n}\n\ntype BaseQueryError = ApiError | UnknownApiError;\n\nconst simpleQuery: BaseQueryFn<string | QueryArguments, unknown, BaseQueryError> = async (\n query,\n { signal }
|
|
1
|
+
{"version":3,"file":"baseQuery.mjs","sources":["../../../../../admin/src/utils/baseQuery.ts"],"sourcesContent":["import { SerializedError } from '@reduxjs/toolkit';\nimport { BaseQueryFn } from '@reduxjs/toolkit/query';\n\nimport { login as loginAction, logout as logoutAction } from '../reducer';\nimport { getFetchClient, type FetchOptions, ApiError, isFetchError } from '../utils/getFetchClient';\n\ninterface QueryArguments {\n url: string;\n method?: 'GET' | 'POST' | 'DELETE' | 'PUT';\n data?: unknown;\n config?: FetchOptions;\n}\n\ninterface UnknownApiError {\n name: 'UnknownError';\n message: string;\n details?: unknown;\n status?: number;\n}\n\ntype BaseQueryError = ApiError | UnknownApiError;\n\nlet refreshPromise: Promise<string> | null = null;\n\nconst isAuthPath = (url: string) => /^\\/admin\\/(login|logout|access-token)\\b/.test(url);\n\nconst simpleQuery: BaseQueryFn<string | QueryArguments, unknown, BaseQueryError> = async (\n query,\n api\n) => {\n const { signal, dispatch } = api as { signal?: AbortSignal; dispatch: (a: any) => void };\n\n const executeQuery = async (queryToExecute: string | QueryArguments) => {\n const { get, post, del, put } = getFetchClient();\n if (typeof queryToExecute === 'string') {\n const result = await get(queryToExecute, { signal });\n return result;\n }\n\n const { url, method = 'GET', data, config } = queryToExecute;\n if (method === 'POST') {\n return post(url, data, { ...config, signal });\n }\n if (method === 'DELETE') {\n return del(url, { ...config, signal });\n }\n if (method === 'PUT') {\n return put(url, data, { ...config, signal });\n }\n return get(url, { ...config, signal });\n };\n\n try {\n const result = await executeQuery(query);\n return { data: result.data };\n } catch (err) {\n // Handle error of type FetchError\n\n if (isFetchError(err)) {\n // Attempt auto-refresh on 401 then retry once\n if (err.status === 401) {\n const url = typeof query === 'string' ? query : query.url;\n\n if (!isAuthPath(url)) {\n if (!refreshPromise) {\n async function refreshAccessToken(): Promise<string> {\n const { post } = getFetchClient();\n\n const res = await post('/admin/access-token');\n const token = res?.data?.data?.token as string | undefined;\n if (!token) {\n throw new Error('access_token_exchange_failed');\n }\n\n // Persist according to previous choice: localStorage presence implies persist\n const persist = Boolean(localStorage.getItem('jwtToken'));\n dispatch(loginAction({ token, persist }));\n\n return token;\n }\n\n refreshPromise = refreshAccessToken().finally(() => {\n refreshPromise = null;\n });\n }\n\n try {\n await refreshPromise;\n // Retry original request once with updated Authorization\n const retry = await executeQuery(query);\n\n return { data: retry.data };\n } catch (refreshError) {\n try {\n const { post } = getFetchClient();\n await post('/admin/logout');\n } catch {\n // no-op\n }\n\n dispatch(logoutAction());\n // Fall through to return the original 401 error shape\n }\n }\n }\n\n if (\n typeof err.response?.data === 'object' &&\n err.response?.data !== null &&\n 'error' in err.response?.data\n ) {\n /**\n * This will most likely be ApiError\n */\n return { data: undefined, error: err.response?.data.error as any };\n } else {\n return {\n data: undefined,\n error: {\n name: 'UnknownError',\n message: err.message,\n details: err.response,\n status: err.status,\n } as UnknownApiError,\n };\n }\n }\n\n const error = err as Error;\n return {\n data: undefined,\n error: {\n name: error.name,\n message: error.message,\n stack: error.stack,\n } satisfies SerializedError,\n };\n }\n};\n\nconst fetchBaseQuery = () => simpleQuery;\n\nconst isBaseQueryError = (error: BaseQueryError | SerializedError): error is BaseQueryError => {\n return error.name !== undefined;\n};\n\nexport { fetchBaseQuery, isBaseQueryError };\nexport type { BaseQueryError, UnknownApiError, QueryArguments };\n"],"names":["refreshPromise","isAuthPath","url","test","simpleQuery","query","api","signal","dispatch","executeQuery","queryToExecute","get","post","del","put","getFetchClient","result","method","data","config","err","isFetchError","status","refreshAccessToken","res","token","Error","persist","Boolean","localStorage","getItem","loginAction","finally","retry","refreshError","logoutAction","response","undefined","error","name","message","details","stack","fetchBaseQuery","isBaseQueryError"],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fallbackUUIDv4 = ()=>{
|
|
4
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
5
|
+
bytes[6] = bytes[6] & 0x0f | 0x40;
|
|
6
|
+
bytes[8] = bytes[8] & 0x3f | 0x80;
|
|
7
|
+
const hex = [
|
|
8
|
+
...bytes
|
|
9
|
+
].map((b)=>b.toString(16).padStart(2, '0'));
|
|
10
|
+
return [
|
|
11
|
+
hex.slice(0, 4).join(''),
|
|
12
|
+
hex.slice(4, 6).join(''),
|
|
13
|
+
hex.slice(6, 8).join(''),
|
|
14
|
+
hex.slice(8, 10).join(''),
|
|
15
|
+
hex.slice(10, 16).join('')
|
|
16
|
+
].join('-');
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Returns a stable device identifier for session-based authentication flows.
|
|
20
|
+
* Uses localStorage to persist a UUID between sessions on the same browser.
|
|
21
|
+
*/ const getOrCreateDeviceId = ()=>{
|
|
22
|
+
const storageKey = 'strapi.admin.deviceId';
|
|
23
|
+
const existing = window.localStorage.getItem(storageKey);
|
|
24
|
+
if (existing) {
|
|
25
|
+
return existing;
|
|
26
|
+
}
|
|
27
|
+
// Use randomUUID in secure contexts, otherwise polyfill
|
|
28
|
+
const generated = typeof crypto?.randomUUID === 'function' ? crypto.randomUUID() : fallbackUUIDv4();
|
|
29
|
+
try {
|
|
30
|
+
window.localStorage.setItem(storageKey, generated);
|
|
31
|
+
} catch {
|
|
32
|
+
// no-op
|
|
33
|
+
}
|
|
34
|
+
return generated;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
exports.getOrCreateDeviceId = getOrCreateDeviceId;
|
|
38
|
+
//# sourceMappingURL=deviceId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deviceId.js","sources":["../../../../../admin/src/utils/deviceId.ts"],"sourcesContent":["const fallbackUUIDv4 = (): string => {\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n\n const hex = [...bytes].map((b) => b.toString(16).padStart(2, '0'));\n return [\n hex.slice(0, 4).join(''),\n hex.slice(4, 6).join(''),\n hex.slice(6, 8).join(''),\n hex.slice(8, 10).join(''),\n hex.slice(10, 16).join(''),\n ].join('-');\n};\n\n/**\n * Returns a stable device identifier for session-based authentication flows.\n * Uses localStorage to persist a UUID between sessions on the same browser.\n */\nexport const getOrCreateDeviceId = (): string => {\n const storageKey = 'strapi.admin.deviceId';\n\n const existing = window.localStorage.getItem(storageKey);\n if (existing) {\n return existing;\n }\n\n // Use randomUUID in secure contexts, otherwise polyfill\n const generated =\n typeof crypto?.randomUUID === 'function' ? crypto.randomUUID() : fallbackUUIDv4();\n\n try {\n window.localStorage.setItem(storageKey, generated);\n } catch {\n // no-op\n }\n\n return generated;\n};\n"],"names":["fallbackUUIDv4","bytes","crypto","getRandomValues","Uint8Array","hex","map","b","toString","padStart","slice","join","getOrCreateDeviceId","storageKey","existing","window","localStorage","getItem","generated","randomUUID","setItem"],"mappings":";;AAAA,MAAMA,cAAiB,GAAA,IAAA;AACrB,IAAA,MAAMC,KAAQC,GAAAA,MAAAA,CAAOC,eAAe,CAAC,IAAIC,UAAW,CAAA,EAAA,CAAA,CAAA;IAEpDH,KAAK,CAAC,EAAE,GAAIA,KAAK,CAAC,CAAA,CAAE,GAAG,IAAQ,GAAA,IAAA;IAC/BA,KAAK,CAAC,EAAE,GAAIA,KAAK,CAAC,CAAA,CAAE,GAAG,IAAQ,GAAA,IAAA;AAE/B,IAAA,MAAMI,GAAM,GAAA;AAAIJ,QAAAA,GAAAA;KAAM,CAACK,GAAG,CAAC,CAACC,CAAMA,GAAAA,CAAAA,CAAEC,QAAQ,CAAC,EAAA,CAAA,CAAIC,QAAQ,CAAC,CAAG,EAAA,GAAA,CAAA,CAAA;IAC7D,OAAO;AACLJ,QAAAA,GAAAA,CAAIK,KAAK,CAAC,CAAG,EAAA,CAAA,CAAA,CAAGC,IAAI,CAAC,EAAA,CAAA;AACrBN,QAAAA,GAAAA,CAAIK,KAAK,CAAC,CAAG,EAAA,CAAA,CAAA,CAAGC,IAAI,CAAC,EAAA,CAAA;AACrBN,QAAAA,GAAAA,CAAIK,KAAK,CAAC,CAAG,EAAA,CAAA,CAAA,CAAGC,IAAI,CAAC,EAAA,CAAA;AACrBN,QAAAA,GAAAA,CAAIK,KAAK,CAAC,CAAG,EAAA,EAAA,CAAA,CAAIC,IAAI,CAAC,EAAA,CAAA;AACtBN,QAAAA,GAAAA,CAAIK,KAAK,CAAC,EAAI,EAAA,EAAA,CAAA,CAAIC,IAAI,CAAC,EAAA;AACxB,KAAA,CAACA,IAAI,CAAC,GAAA,CAAA;AACT,CAAA;AAEA;;;UAIaC,mBAAsB,GAAA,IAAA;AACjC,IAAA,MAAMC,UAAa,GAAA,uBAAA;AAEnB,IAAA,MAAMC,QAAWC,GAAAA,MAAAA,CAAOC,YAAY,CAACC,OAAO,CAACJ,UAAAA,CAAAA;AAC7C,IAAA,IAAIC,QAAU,EAAA;QACZ,OAAOA,QAAAA;AACT;;AAGA,IAAA,MAAMI,YACJ,OAAOhB,MAAAA,EAAQiB,eAAe,UAAajB,GAAAA,MAAAA,CAAOiB,UAAU,EAAKnB,GAAAA,cAAAA,EAAAA;IAEnE,IAAI;AACFe,QAAAA,MAAAA,CAAOC,YAAY,CAACI,OAAO,CAACP,UAAYK,EAAAA,SAAAA,CAAAA;AAC1C,KAAA,CAAE,OAAM;;AAER;IAEA,OAAOA,SAAAA;AACT;;;;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const fallbackUUIDv4 = ()=>{
|
|
2
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
3
|
+
bytes[6] = bytes[6] & 0x0f | 0x40;
|
|
4
|
+
bytes[8] = bytes[8] & 0x3f | 0x80;
|
|
5
|
+
const hex = [
|
|
6
|
+
...bytes
|
|
7
|
+
].map((b)=>b.toString(16).padStart(2, '0'));
|
|
8
|
+
return [
|
|
9
|
+
hex.slice(0, 4).join(''),
|
|
10
|
+
hex.slice(4, 6).join(''),
|
|
11
|
+
hex.slice(6, 8).join(''),
|
|
12
|
+
hex.slice(8, 10).join(''),
|
|
13
|
+
hex.slice(10, 16).join('')
|
|
14
|
+
].join('-');
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Returns a stable device identifier for session-based authentication flows.
|
|
18
|
+
* Uses localStorage to persist a UUID between sessions on the same browser.
|
|
19
|
+
*/ const getOrCreateDeviceId = ()=>{
|
|
20
|
+
const storageKey = 'strapi.admin.deviceId';
|
|
21
|
+
const existing = window.localStorage.getItem(storageKey);
|
|
22
|
+
if (existing) {
|
|
23
|
+
return existing;
|
|
24
|
+
}
|
|
25
|
+
// Use randomUUID in secure contexts, otherwise polyfill
|
|
26
|
+
const generated = typeof crypto?.randomUUID === 'function' ? crypto.randomUUID() : fallbackUUIDv4();
|
|
27
|
+
try {
|
|
28
|
+
window.localStorage.setItem(storageKey, generated);
|
|
29
|
+
} catch {
|
|
30
|
+
// no-op
|
|
31
|
+
}
|
|
32
|
+
return generated;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export { getOrCreateDeviceId };
|
|
36
|
+
//# sourceMappingURL=deviceId.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deviceId.mjs","sources":["../../../../../admin/src/utils/deviceId.ts"],"sourcesContent":["const fallbackUUIDv4 = (): string => {\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n\n const hex = [...bytes].map((b) => b.toString(16).padStart(2, '0'));\n return [\n hex.slice(0, 4).join(''),\n hex.slice(4, 6).join(''),\n hex.slice(6, 8).join(''),\n hex.slice(8, 10).join(''),\n hex.slice(10, 16).join(''),\n ].join('-');\n};\n\n/**\n * Returns a stable device identifier for session-based authentication flows.\n * Uses localStorage to persist a UUID between sessions on the same browser.\n */\nexport const getOrCreateDeviceId = (): string => {\n const storageKey = 'strapi.admin.deviceId';\n\n const existing = window.localStorage.getItem(storageKey);\n if (existing) {\n return existing;\n }\n\n // Use randomUUID in secure contexts, otherwise polyfill\n const generated =\n typeof crypto?.randomUUID === 'function' ? crypto.randomUUID() : fallbackUUIDv4();\n\n try {\n window.localStorage.setItem(storageKey, generated);\n } catch {\n // no-op\n }\n\n return generated;\n};\n"],"names":["fallbackUUIDv4","bytes","crypto","getRandomValues","Uint8Array","hex","map","b","toString","padStart","slice","join","getOrCreateDeviceId","storageKey","existing","window","localStorage","getItem","generated","randomUUID","setItem"],"mappings":"AAAA,MAAMA,cAAiB,GAAA,IAAA;AACrB,IAAA,MAAMC,KAAQC,GAAAA,MAAAA,CAAOC,eAAe,CAAC,IAAIC,UAAW,CAAA,EAAA,CAAA,CAAA;IAEpDH,KAAK,CAAC,EAAE,GAAIA,KAAK,CAAC,CAAA,CAAE,GAAG,IAAQ,GAAA,IAAA;IAC/BA,KAAK,CAAC,EAAE,GAAIA,KAAK,CAAC,CAAA,CAAE,GAAG,IAAQ,GAAA,IAAA;AAE/B,IAAA,MAAMI,GAAM,GAAA;AAAIJ,QAAAA,GAAAA;KAAM,CAACK,GAAG,CAAC,CAACC,CAAMA,GAAAA,CAAAA,CAAEC,QAAQ,CAAC,EAAA,CAAA,CAAIC,QAAQ,CAAC,CAAG,EAAA,GAAA,CAAA,CAAA;IAC7D,OAAO;AACLJ,QAAAA,GAAAA,CAAIK,KAAK,CAAC,CAAG,EAAA,CAAA,CAAA,CAAGC,IAAI,CAAC,EAAA,CAAA;AACrBN,QAAAA,GAAAA,CAAIK,KAAK,CAAC,CAAG,EAAA,CAAA,CAAA,CAAGC,IAAI,CAAC,EAAA,CAAA;AACrBN,QAAAA,GAAAA,CAAIK,KAAK,CAAC,CAAG,EAAA,CAAA,CAAA,CAAGC,IAAI,CAAC,EAAA,CAAA;AACrBN,QAAAA,GAAAA,CAAIK,KAAK,CAAC,CAAG,EAAA,EAAA,CAAA,CAAIC,IAAI,CAAC,EAAA,CAAA;AACtBN,QAAAA,GAAAA,CAAIK,KAAK,CAAC,EAAI,EAAA,EAAA,CAAA,CAAIC,IAAI,CAAC,EAAA;AACxB,KAAA,CAACA,IAAI,CAAC,GAAA,CAAA;AACT,CAAA;AAEA;;;UAIaC,mBAAsB,GAAA,IAAA;AACjC,IAAA,MAAMC,UAAa,GAAA,uBAAA;AAEnB,IAAA,MAAMC,QAAWC,GAAAA,MAAAA,CAAOC,YAAY,CAACC,OAAO,CAACJ,UAAAA,CAAAA;AAC7C,IAAA,IAAIC,QAAU,EAAA;QACZ,OAAOA,QAAAA;AACT;;AAGA,IAAA,MAAMI,YACJ,OAAOhB,MAAAA,EAAQiB,eAAe,UAAajB,GAAAA,MAAAA,CAAOiB,UAAU,EAAKnB,GAAAA,cAAAA,EAAAA;IAEnE,IAAI;AACFe,QAAAA,MAAAA,CAAOC,YAAY,CAACI,OAAO,CAACP,UAAYK,EAAAA,SAAAA,CAAAA;AAC1C,KAAA,CAAE,OAAM;;AAER;IAEA,OAAOA,SAAAA;AACT;;;;"}
|
|
@@ -11,29 +11,38 @@ declare const useCheckPermissionsQuery: import("@reduxjs/toolkit/dist/query/reac
|
|
|
11
11
|
permissions: (Pick<import("../../../shared/contracts/shared").Permission, "action" | "subject"> & {
|
|
12
12
|
field?: string | undefined;
|
|
13
13
|
})[];
|
|
14
|
-
}, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", Check.Response, "adminApi">>, useGetMeQuery: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseQuery<import("@reduxjs/toolkit/query").QueryDefinition<void, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", import("..").SanitizedAdminUser, "adminApi">>, useLoginMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<Pick<import("..").AdminUser, "email" | "password"
|
|
14
|
+
}, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", Check.Response, "adminApi">>, useGetMeQuery: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseQuery<import("@reduxjs/toolkit/query").QueryDefinition<void, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", import("..").SanitizedAdminUser, "adminApi">>, useLoginMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<Pick<import("..").AdminUser, "email" | "password"> & {
|
|
15
|
+
deviceId?: string | undefined;
|
|
16
|
+
rememberMe?: boolean | undefined;
|
|
17
|
+
}, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", {
|
|
15
18
|
token: string;
|
|
19
|
+
accessToken?: string | undefined;
|
|
16
20
|
user: Omit<import("..").SanitizedAdminUser, "permissions">;
|
|
17
|
-
}, "adminApi">>,
|
|
18
|
-
token: string;
|
|
19
|
-
}, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", {
|
|
21
|
+
}, "adminApi">>, useAccessTokenExchangeMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<{} | undefined, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", {
|
|
20
22
|
token: string;
|
|
21
|
-
}, "adminApi">>, useLogoutMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<void
|
|
23
|
+
}, "adminApi">>, useLogoutMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<void | {
|
|
24
|
+
deviceId?: string | undefined;
|
|
25
|
+
}, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", void, "adminApi">>, useUpdateMeMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<UpdateMe.BaseRequestBody, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", import("..").SanitizedAdminUser, "adminApi">>, useResetPasswordMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<{
|
|
22
26
|
resetPasswordToken: string;
|
|
23
27
|
password: string;
|
|
24
28
|
}, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", {
|
|
25
29
|
token: string;
|
|
26
30
|
user: Omit<import("..").SanitizedAdminUser, "permissions">;
|
|
27
|
-
}, "adminApi">>, useRegisterAdminMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<Pick<import("..").AdminUser, "firstname" | "lastname" | "email" | "password"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
}, "adminApi">>, useRegisterAdminMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<Pick<import("..").AdminUser, "firstname" | "lastname" | "email" | "password"> & {
|
|
32
|
+
deviceId?: string | undefined;
|
|
33
|
+
rememberMe?: boolean | undefined;
|
|
34
|
+
}, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", {
|
|
35
|
+
token: string;
|
|
36
|
+
accessToken?: string | undefined;
|
|
31
37
|
user: Omit<import("..").SanitizedAdminUser, "permissions">;
|
|
32
38
|
}, "adminApi">>, useRegisterUserMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<{
|
|
33
39
|
registrationToken: string;
|
|
34
40
|
userInfo: Pick<import("..").AdminUser, "firstname" | "lastname" | "email" | "password">;
|
|
41
|
+
deviceId?: string | undefined;
|
|
42
|
+
rememberMe?: boolean | undefined;
|
|
35
43
|
}, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", {
|
|
36
44
|
token: string;
|
|
45
|
+
accessToken?: string | undefined;
|
|
37
46
|
user: Omit<import("..").SanitizedAdminUser, "permissions">;
|
|
38
47
|
}, "adminApi">>, useGetRegistrationInfoQuery: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseQuery<import("@reduxjs/toolkit/query").QueryDefinition<string, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", {
|
|
39
48
|
email?: string | undefined;
|
|
@@ -44,4 +53,4 @@ declare const useCheckPermissionsQuery: import("@reduxjs/toolkit/dist/query/reac
|
|
|
44
53
|
}, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", ForgotPassword.Response, "adminApi">>, useGetMyPermissionsQuery: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseQuery<import("@reduxjs/toolkit/query").QueryDefinition<void, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", import("../../../shared/contracts/shared").Permission[], "adminApi">>, useIsSSOLockedQuery: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseQuery<import("@reduxjs/toolkit/query").QueryDefinition<void, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", {
|
|
45
54
|
isSSOLocked: boolean;
|
|
46
55
|
}, "adminApi">>, useGetProvidersQuery: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseQuery<import("@reduxjs/toolkit/query").QueryDefinition<void, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", GetProviders.Response, "adminApi">>, useGetProviderOptionsQuery: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseQuery<import("@reduxjs/toolkit/query").QueryDefinition<void, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", ProvidersOptions.SSOProviderOptions, "adminApi">>, useUpdateProviderOptionsMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<ProvidersOptions.SSOProviderOptions, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("..").QueryArguments, unknown, import("..").BaseQueryError>, "GuidedTourMeta" | "HomepageKeyStatistics" | "User" | "Me" | "ProvidersOptions", ProvidersOptions.SSOProviderOptions, "adminApi">>;
|
|
47
|
-
export { useCheckPermissionsQuery, useLazyCheckPermissionsQuery, useGetMeQuery, useLoginMutation,
|
|
56
|
+
export { useCheckPermissionsQuery, useLazyCheckPermissionsQuery, useGetMeQuery, useLoginMutation, useAccessTokenExchangeMutation, useLogoutMutation, useUpdateMeMutation, useResetPasswordMutation, useRegisterAdminMutation, useRegisterUserMutation, useGetRegistrationInfoQuery, useForgotPasswordMutation, useGetMyPermissionsQuery, useIsSSOLockedQuery, useGetProvidersQuery, useGetProviderOptionsQuery, useUpdateProviderOptionsMutation, };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middlewares.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/controllers/authentication-utils/middlewares.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"middlewares.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/controllers/authentication-utils/middlewares.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAa1C,eAAO,MAAM,YAAY,EAAE,IAAI,CAAC,iBA0B/B,CAAC;AA4DF,eAAO,MAAM,gBAAgB,EAAE,IAAI,CAAC,iBAuDnC,CAAC;;;;;AAEF,wBAGE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/services/user.ts"],"names":[],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/services/user.ts"],"names":[],"mappings":";;;;;;;;AAmPA,wBAOE"}
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var passport = require('koa-passport');
|
|
6
6
|
var index = require('../../utils/index.js');
|
|
7
7
|
var utils = require('./utils.js');
|
|
8
|
+
var sessionAuth = require('../../../../../shared/utils/session-auth.js');
|
|
8
9
|
|
|
9
10
|
const defaultConnectionError = ()=>new Error('Invalid connection payload');
|
|
10
11
|
const authenticate = async (ctx, next)=>{
|
|
@@ -84,26 +85,51 @@ const nonExistingUserScenario = (ctx, next)=>async (profile, provider)=>{
|
|
|
84
85
|
});
|
|
85
86
|
return next();
|
|
86
87
|
};
|
|
87
|
-
const redirectWithAuth = (ctx)=>{
|
|
88
|
+
const redirectWithAuth = async (ctx)=>{
|
|
88
89
|
const { params: { provider } } = ctx;
|
|
89
90
|
const redirectUrls = utils.default.getPrefixedRedirectUrls();
|
|
90
|
-
const domain = strapi.config.get('admin.auth.domain');
|
|
91
91
|
const { user } = ctx.state;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
92
|
+
try {
|
|
93
|
+
const sessionManager = sessionAuth.getSessionManager();
|
|
94
|
+
if (!sessionManager) {
|
|
95
|
+
strapi.log.error('SessionManager not available for SSO authentication');
|
|
96
|
+
return ctx.redirect(redirectUrls.error);
|
|
97
|
+
}
|
|
98
|
+
const userId = String(user.id);
|
|
99
|
+
const deviceId = sessionAuth.generateDeviceId();
|
|
100
|
+
const { token: refreshToken, absoluteExpiresAt } = await sessionManager('admin').generateRefreshToken(userId, deviceId, {
|
|
101
|
+
type: 'refresh'
|
|
102
|
+
});
|
|
103
|
+
const cookieOptions = sessionAuth.buildCookieOptionsWithExpiry('refresh', absoluteExpiresAt);
|
|
104
|
+
ctx.cookies.set(sessionAuth.REFRESH_COOKIE_NAME, refreshToken, cookieOptions);
|
|
105
|
+
const accessResult = await sessionManager('admin').generateAccessToken(refreshToken);
|
|
106
|
+
if ('error' in accessResult) {
|
|
107
|
+
strapi.log.error('Failed to generate access token for SSO user');
|
|
108
|
+
return ctx.redirect(redirectUrls.error);
|
|
109
|
+
}
|
|
110
|
+
const { token: accessToken } = accessResult;
|
|
111
|
+
const isProduction = strapi.config.get('environment') === 'production';
|
|
112
|
+
const domain = strapi.config.get('admin.auth.domain');
|
|
113
|
+
ctx.cookies.set('jwtToken', accessToken, {
|
|
114
|
+
httpOnly: false,
|
|
115
|
+
secure: isProduction,
|
|
116
|
+
overwrite: true,
|
|
117
|
+
domain
|
|
118
|
+
});
|
|
119
|
+
const sanitizedUser = index.getService('user').sanitizeUser(user);
|
|
120
|
+
strapi.eventHub.emit('admin.auth.success', {
|
|
121
|
+
user: sanitizedUser,
|
|
122
|
+
provider
|
|
123
|
+
});
|
|
124
|
+
ctx.redirect(redirectUrls.success);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
strapi.log.error('SSO authentication failed during token generation', error);
|
|
127
|
+
strapi.eventHub.emit('admin.auth.error', {
|
|
128
|
+
error: error instanceof Error ? error : new Error('Unknown SSO error'),
|
|
129
|
+
provider
|
|
130
|
+
});
|
|
131
|
+
return ctx.redirect(redirectUrls.error);
|
|
132
|
+
}
|
|
107
133
|
};
|
|
108
134
|
var middlewares = {
|
|
109
135
|
authenticate,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middlewares.js","sources":["../../../../../../../ee/server/src/controllers/authentication-utils/middlewares.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport passport from 'koa-passport';\nimport { getService } from '../../utils';\nimport utils from './utils';\n\nconst defaultConnectionError = () => new Error('Invalid connection payload');\n\nexport const authenticate: Core.MiddlewareHandler = async (ctx, next) => {\n const {\n params: { provider },\n } = ctx;\n const redirectUrls = utils.getPrefixedRedirectUrls();\n\n // @ts-expect-error - can not use null to authenticate\n return passport.authenticate(provider, null, async (error, profile) => {\n if (error || !profile || !profile.email) {\n if (error) {\n strapi.log.error(error);\n }\n\n strapi.eventHub.emit('admin.auth.error', {\n error: error || defaultConnectionError(),\n provider,\n });\n\n return ctx.redirect(redirectUrls.error);\n }\n\n const user = await getService('user').findOneByEmail(profile.email);\n const scenario = user ? existingUserScenario : nonExistingUserScenario;\n\n return scenario(ctx, next)(user || profile, provider);\n })(ctx, next);\n};\n\nconst existingUserScenario: Core.MiddlewareHandler =\n (ctx, next) => async (user: any, provider: any) => {\n const redirectUrls = utils.getPrefixedRedirectUrls();\n\n if (!user.isActive) {\n strapi.eventHub.emit('admin.auth.error', {\n error: new Error(`Deactivated user tried to login (${user.id})`),\n provider,\n });\n return ctx.redirect(redirectUrls.error);\n }\n\n ctx.state.user = user;\n return next();\n };\n\nconst nonExistingUserScenario: Core.MiddlewareHandler =\n (ctx, next) => async (profile: any, provider: any) => {\n const { email, firstname, lastname, username } = profile;\n const redirectUrls = utils.getPrefixedRedirectUrls();\n const adminStore = await utils.getAdminStore();\n const { providers } = (await adminStore.get({ key: 'auth' })) as any;\n\n // We need at least the username or the firstname/lastname combination to register a new user\n const isMissingRegisterFields = !username && (!firstname || !lastname);\n\n if (!providers.autoRegister || !providers.defaultRole || isMissingRegisterFields) {\n strapi.eventHub.emit('admin.auth.error', { error: defaultConnectionError(), provider });\n return ctx.redirect(redirectUrls.error);\n }\n\n const defaultRole = await getService('role').findOne({ id: providers.defaultRole });\n\n // If the default role has been misconfigured, redirect with an error\n if (!defaultRole) {\n strapi.eventHub.emit('admin.auth.error', { error: defaultConnectionError(), provider });\n return ctx.redirect(redirectUrls.error);\n }\n\n // Register a new user with the information given by the provider and login with it\n ctx.state.user = await getService('user').create({\n email,\n username,\n firstname,\n lastname,\n roles: [defaultRole.id],\n isActive: true,\n registrationToken: null,\n });\n\n strapi.eventHub.emit('admin.auth.autoRegistration', {\n user: ctx.state.user,\n provider,\n });\n\n return next();\n };\n\nexport const redirectWithAuth: Core.MiddlewareHandler = (ctx) => {\n const {\n params: { provider },\n } = ctx;\n const redirectUrls = utils.getPrefixedRedirectUrls();\n const domain: string | undefined = strapi.config.get('admin.auth.domain');\n const { user } = ctx.state;\n\n const jwt = getService('token').createJwtToken(user);\n\n const isProduction = strapi.config.get('environment') === 'production';\n\n const cookiesOptions = { httpOnly: false, secure: isProduction, overwrite: true, domain };\n\n const sanitizedUser = getService('user').sanitizeUser(user);\n strapi.eventHub.emit('admin.auth.success', { user: sanitizedUser, provider });\n\n ctx.cookies.set('jwtToken', jwt, cookiesOptions);\n ctx.redirect(redirectUrls.success);\n};\n\nexport default {\n authenticate,\n redirectWithAuth,\n};\n"],"names":["defaultConnectionError","Error","authenticate","ctx","next","params","provider","redirectUrls","utils","getPrefixedRedirectUrls","passport","error","profile","email","strapi","log","eventHub","emit","redirect","user","getService","findOneByEmail","scenario","existingUserScenario","nonExistingUserScenario","isActive","id","state","firstname","lastname","username","adminStore","getAdminStore","providers","get","key","isMissingRegisterFields","autoRegister","defaultRole","findOne","create","roles","registrationToken","redirectWithAuth","domain","config","jwt","createJwtToken","isProduction","cookiesOptions","httpOnly","secure","overwrite","sanitizedUser","sanitizeUser","cookies","set","success"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"middlewares.js","sources":["../../../../../../../ee/server/src/controllers/authentication-utils/middlewares.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport passport from 'koa-passport';\nimport { getService } from '../../utils';\nimport utils from './utils';\nimport {\n REFRESH_COOKIE_NAME,\n buildCookieOptionsWithExpiry,\n getSessionManager,\n generateDeviceId,\n} from '../../../../../shared/utils/session-auth';\n\nconst defaultConnectionError = () => new Error('Invalid connection payload');\n\nexport const authenticate: Core.MiddlewareHandler = async (ctx, next) => {\n const {\n params: { provider },\n } = ctx;\n const redirectUrls = utils.getPrefixedRedirectUrls();\n\n // @ts-expect-error - can not use null to authenticate\n return passport.authenticate(provider, null, async (error, profile) => {\n if (error || !profile || !profile.email) {\n if (error) {\n strapi.log.error(error);\n }\n\n strapi.eventHub.emit('admin.auth.error', {\n error: error || defaultConnectionError(),\n provider,\n });\n\n return ctx.redirect(redirectUrls.error);\n }\n\n const user = await getService('user').findOneByEmail(profile.email);\n const scenario = user ? existingUserScenario : nonExistingUserScenario;\n\n return scenario(ctx, next)(user || profile, provider);\n })(ctx, next);\n};\n\nconst existingUserScenario: Core.MiddlewareHandler =\n (ctx, next) => async (user: any, provider: any) => {\n const redirectUrls = utils.getPrefixedRedirectUrls();\n\n if (!user.isActive) {\n strapi.eventHub.emit('admin.auth.error', {\n error: new Error(`Deactivated user tried to login (${user.id})`),\n provider,\n });\n return ctx.redirect(redirectUrls.error);\n }\n\n ctx.state.user = user;\n return next();\n };\n\nconst nonExistingUserScenario: Core.MiddlewareHandler =\n (ctx, next) => async (profile: any, provider: any) => {\n const { email, firstname, lastname, username } = profile;\n const redirectUrls = utils.getPrefixedRedirectUrls();\n const adminStore = await utils.getAdminStore();\n const { providers } = (await adminStore.get({ key: 'auth' })) as any;\n\n // We need at least the username or the firstname/lastname combination to register a new user\n const isMissingRegisterFields = !username && (!firstname || !lastname);\n\n if (!providers.autoRegister || !providers.defaultRole || isMissingRegisterFields) {\n strapi.eventHub.emit('admin.auth.error', { error: defaultConnectionError(), provider });\n return ctx.redirect(redirectUrls.error);\n }\n\n const defaultRole = await getService('role').findOne({ id: providers.defaultRole });\n\n // If the default role has been misconfigured, redirect with an error\n if (!defaultRole) {\n strapi.eventHub.emit('admin.auth.error', { error: defaultConnectionError(), provider });\n return ctx.redirect(redirectUrls.error);\n }\n\n // Register a new user with the information given by the provider and login with it\n ctx.state.user = await getService('user').create({\n email,\n username,\n firstname,\n lastname,\n roles: [defaultRole.id],\n isActive: true,\n registrationToken: null,\n });\n\n strapi.eventHub.emit('admin.auth.autoRegistration', {\n user: ctx.state.user,\n provider,\n });\n\n return next();\n };\n\nexport const redirectWithAuth: Core.MiddlewareHandler = async (ctx) => {\n const {\n params: { provider },\n } = ctx;\n const redirectUrls = utils.getPrefixedRedirectUrls();\n const { user } = ctx.state;\n\n try {\n const sessionManager = getSessionManager();\n if (!sessionManager) {\n strapi.log.error('SessionManager not available for SSO authentication');\n return ctx.redirect(redirectUrls.error);\n }\n\n const userId = String(user.id);\n const deviceId = generateDeviceId();\n\n const { token: refreshToken, absoluteExpiresAt } = await sessionManager(\n 'admin'\n ).generateRefreshToken(userId, deviceId, {\n type: 'refresh',\n });\n\n const cookieOptions = buildCookieOptionsWithExpiry('refresh', 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 strapi.log.error('Failed to generate access token for SSO user');\n return ctx.redirect(redirectUrls.error);\n }\n\n const { token: accessToken } = accessResult;\n\n const isProduction = strapi.config.get('environment') === 'production';\n const domain: string | undefined = strapi.config.get('admin.auth.domain');\n ctx.cookies.set('jwtToken', accessToken, {\n httpOnly: false,\n secure: isProduction,\n overwrite: true,\n domain,\n });\n\n const sanitizedUser = getService('user').sanitizeUser(user);\n strapi.eventHub.emit('admin.auth.success', { user: sanitizedUser, provider });\n\n ctx.redirect(redirectUrls.success);\n } catch (error) {\n strapi.log.error('SSO authentication failed during token generation', error);\n strapi.eventHub.emit('admin.auth.error', {\n error: error instanceof Error ? error : new Error('Unknown SSO error'),\n provider,\n });\n return ctx.redirect(redirectUrls.error);\n }\n};\n\nexport default {\n authenticate,\n redirectWithAuth,\n};\n"],"names":["defaultConnectionError","Error","authenticate","ctx","next","params","provider","redirectUrls","utils","getPrefixedRedirectUrls","passport","error","profile","email","strapi","log","eventHub","emit","redirect","user","getService","findOneByEmail","scenario","existingUserScenario","nonExistingUserScenario","isActive","id","state","firstname","lastname","username","adminStore","getAdminStore","providers","get","key","isMissingRegisterFields","autoRegister","defaultRole","findOne","create","roles","registrationToken","redirectWithAuth","sessionManager","getSessionManager","userId","String","deviceId","generateDeviceId","token","refreshToken","absoluteExpiresAt","generateRefreshToken","type","cookieOptions","buildCookieOptionsWithExpiry","cookies","set","REFRESH_COOKIE_NAME","accessResult","generateAccessToken","accessToken","isProduction","config","domain","httpOnly","secure","overwrite","sanitizedUser","sanitizeUser","success"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import passport from 'koa-passport';
|
|
2
2
|
import { getService } from '../../utils/index.mjs';
|
|
3
3
|
import utils from './utils.mjs';
|
|
4
|
+
import { getSessionManager, generateDeviceId, buildCookieOptionsWithExpiry, REFRESH_COOKIE_NAME } from '../../../../../shared/utils/session-auth.mjs';
|
|
4
5
|
|
|
5
6
|
const defaultConnectionError = ()=>new Error('Invalid connection payload');
|
|
6
7
|
const authenticate = async (ctx, next)=>{
|
|
@@ -80,26 +81,51 @@ const nonExistingUserScenario = (ctx, next)=>async (profile, provider)=>{
|
|
|
80
81
|
});
|
|
81
82
|
return next();
|
|
82
83
|
};
|
|
83
|
-
const redirectWithAuth = (ctx)=>{
|
|
84
|
+
const redirectWithAuth = async (ctx)=>{
|
|
84
85
|
const { params: { provider } } = ctx;
|
|
85
86
|
const redirectUrls = utils.getPrefixedRedirectUrls();
|
|
86
|
-
const domain = strapi.config.get('admin.auth.domain');
|
|
87
87
|
const { user } = ctx.state;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
88
|
+
try {
|
|
89
|
+
const sessionManager = getSessionManager();
|
|
90
|
+
if (!sessionManager) {
|
|
91
|
+
strapi.log.error('SessionManager not available for SSO authentication');
|
|
92
|
+
return ctx.redirect(redirectUrls.error);
|
|
93
|
+
}
|
|
94
|
+
const userId = String(user.id);
|
|
95
|
+
const deviceId = generateDeviceId();
|
|
96
|
+
const { token: refreshToken, absoluteExpiresAt } = await sessionManager('admin').generateRefreshToken(userId, deviceId, {
|
|
97
|
+
type: 'refresh'
|
|
98
|
+
});
|
|
99
|
+
const cookieOptions = buildCookieOptionsWithExpiry('refresh', absoluteExpiresAt);
|
|
100
|
+
ctx.cookies.set(REFRESH_COOKIE_NAME, refreshToken, cookieOptions);
|
|
101
|
+
const accessResult = await sessionManager('admin').generateAccessToken(refreshToken);
|
|
102
|
+
if ('error' in accessResult) {
|
|
103
|
+
strapi.log.error('Failed to generate access token for SSO user');
|
|
104
|
+
return ctx.redirect(redirectUrls.error);
|
|
105
|
+
}
|
|
106
|
+
const { token: accessToken } = accessResult;
|
|
107
|
+
const isProduction = strapi.config.get('environment') === 'production';
|
|
108
|
+
const domain = strapi.config.get('admin.auth.domain');
|
|
109
|
+
ctx.cookies.set('jwtToken', accessToken, {
|
|
110
|
+
httpOnly: false,
|
|
111
|
+
secure: isProduction,
|
|
112
|
+
overwrite: true,
|
|
113
|
+
domain
|
|
114
|
+
});
|
|
115
|
+
const sanitizedUser = getService('user').sanitizeUser(user);
|
|
116
|
+
strapi.eventHub.emit('admin.auth.success', {
|
|
117
|
+
user: sanitizedUser,
|
|
118
|
+
provider
|
|
119
|
+
});
|
|
120
|
+
ctx.redirect(redirectUrls.success);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
strapi.log.error('SSO authentication failed during token generation', error);
|
|
123
|
+
strapi.eventHub.emit('admin.auth.error', {
|
|
124
|
+
error: error instanceof Error ? error : new Error('Unknown SSO error'),
|
|
125
|
+
provider
|
|
126
|
+
});
|
|
127
|
+
return ctx.redirect(redirectUrls.error);
|
|
128
|
+
}
|
|
103
129
|
};
|
|
104
130
|
var middlewares = {
|
|
105
131
|
authenticate,
|