@strapi/admin 5.52.2 → 5.53.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/components/Filters.js +9 -9
- package/dist/admin/admin/src/components/Filters.js.map +1 -1
- package/dist/admin/admin/src/components/Filters.mjs +10 -10
- package/dist/admin/admin/src/components/Filters.mjs.map +1 -1
- package/dist/admin/admin/src/components/Pagination.js +2 -2
- package/dist/admin/admin/src/components/Pagination.js.map +1 -1
- package/dist/admin/admin/src/components/Pagination.mjs +3 -3
- package/dist/admin/admin/src/components/Pagination.mjs.map +1 -1
- package/dist/admin/admin/src/components/SearchInput.js +7 -8
- package/dist/admin/admin/src/components/SearchInput.js.map +1 -1
- package/dist/admin/admin/src/components/SearchInput.mjs +8 -9
- package/dist/admin/admin/src/components/SearchInput.mjs.map +1 -1
- package/dist/admin/admin/src/components/Table.js +2 -2
- package/dist/admin/admin/src/components/Table.js.map +1 -1
- package/dist/admin/admin/src/components/Table.mjs +3 -3
- package/dist/admin/admin/src/components/Table.mjs.map +1 -1
- package/dist/admin/admin/src/hooks/useQueryParams.js +35 -1
- package/dist/admin/admin/src/hooks/useQueryParams.js.map +1 -1
- package/dist/admin/admin/src/hooks/useQueryParams.mjs +34 -2
- package/dist/admin/admin/src/hooks/useQueryParams.mjs.map +1 -1
- package/dist/admin/admin/src/translations/en.json.js +18 -0
- package/dist/admin/admin/src/translations/en.json.js.map +1 -1
- package/dist/admin/admin/src/translations/en.json.mjs +18 -0
- package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.js +118 -43
- package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.mjs +118 -45
- package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
- package/dist/admin/ee/admin/src/constants.js +6 -0
- package/dist/admin/ee/admin/src/constants.js.map +1 -1
- package/dist/admin/ee/admin/src/constants.mjs +6 -0
- package/dist/admin/ee/admin/src/constants.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js +40 -12
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs +43 -15
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.js +177 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.js.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.mjs +175 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.mjs.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js +173 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs +151 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +10 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +10 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
- package/dist/admin/index.js +4 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +2 -2
- package/dist/admin/shared/utils/audit-log-export.js +16 -0
- package/dist/admin/shared/utils/audit-log-export.js.map +1 -0
- package/dist/admin/shared/utils/audit-log-export.mjs +9 -0
- package/dist/admin/shared/utils/audit-log-export.mjs.map +1 -0
- package/dist/admin/src/components/Filters.d.ts +1 -0
- package/dist/admin/src/hooks/useQueryParams.d.ts +13 -1
- package/dist/admin/src/index.d.ts +1 -1
- package/dist/admin/src/utils/getFetchClient.d.ts +9 -2
- package/dist/admin/tests/store.d.ts +4 -0
- package/dist/admin/tests/utils.d.ts +4 -0
- package/dist/ee/admin/src/constants.d.ts +4 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.d.ts +10 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.d.ts +18 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +9 -0
- package/dist/ee/server/src/audit-logs/controllers/audit-logs.d.ts +1 -0
- package/dist/ee/server/src/audit-logs/controllers/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/routes/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/services/audit-logs.d.ts +24 -3
- package/dist/ee/server/src/audit-logs/services/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +8 -2
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/utils/csv.d.ts +5 -0
- package/dist/ee/server/src/audit-logs/utils/csv.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/utils/export-token.d.ts +5 -0
- package/dist/ee/server/src/audit-logs/utils/export-token.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/utils.d.ts +10 -0
- package/dist/ee/server/src/audit-logs/utils.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/validation/audit-logs.d.ts +2 -0
- package/dist/ee/server/src/audit-logs/validation/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/config/admin-actions.d.ts.map +1 -1
- package/dist/ee/server/src/index.d.ts +1 -0
- package/dist/ee/server/src/index.d.ts.map +1 -1
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.js +50 -0
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.mjs +51 -1
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.js +13 -4
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.mjs +13 -4
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.js +201 -7
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.mjs +201 -8
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +119 -34
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +119 -34
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/utils/csv.js +33 -0
- package/dist/server/ee/server/src/audit-logs/utils/csv.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils/csv.mjs +29 -0
- package/dist/server/ee/server/src/audit-logs/utils/csv.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.js +33 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.mjs +29 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils.js +14 -0
- package/dist/server/ee/server/src/audit-logs/utils.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils.mjs +12 -0
- package/dist/server/ee/server/src/audit-logs/utils.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.js +11 -0
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.mjs +11 -1
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/config/admin-actions.js +8 -0
- package/dist/server/ee/server/src/config/admin-actions.js.map +1 -1
- package/dist/server/ee/server/src/config/admin-actions.mjs +8 -0
- package/dist/server/ee/server/src/config/admin-actions.mjs.map +1 -1
- package/dist/server/ee/server/src/index.js +10 -0
- package/dist/server/ee/server/src/index.js.map +1 -1
- package/dist/server/ee/server/src/index.mjs +10 -0
- package/dist/server/ee/server/src/index.mjs.map +1 -1
- package/dist/server/shared/utils/audit-log-export.js +22 -0
- package/dist/server/shared/utils/audit-log-export.js.map +1 -0
- package/dist/server/shared/utils/audit-log-export.mjs +12 -0
- package/dist/server/shared/utils/audit-log-export.mjs.map +1 -0
- package/dist/shared/contracts/audit-logs.d.ts +15 -1
- package/dist/shared/contracts/audit-logs.d.ts.map +1 -1
- package/dist/shared/utils/audit-log-export.d.ts +9 -0
- package/dist/shared/utils/audit-log-export.d.ts.map +1 -0
- package/package.json +7 -7
|
@@ -43,7 +43,12 @@ const useQueryParams = (initialParams)=>{
|
|
|
43
43
|
...nextParams
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
/**
|
|
47
|
+
* TODO V6: Encoding should be enabled in this step, via `{ encodeValuesOnly: true }`
|
|
48
|
+
* So the rest of the app doesn't have to worry about it,
|
|
49
|
+
* It's considered a breaking change because callers currently encode values themselves,
|
|
50
|
+
* including the user's custom code, and would end up double-encoding them.
|
|
51
|
+
*/ navigate({
|
|
47
52
|
search: qs.stringify(nextQuery, {
|
|
48
53
|
encode: false
|
|
49
54
|
})
|
|
@@ -62,6 +67,35 @@ const useQueryParams = (initialParams)=>{
|
|
|
62
67
|
setQuery
|
|
63
68
|
];
|
|
64
69
|
};
|
|
70
|
+
/**
|
|
71
|
+
* These functions are used to encode query values when writing them to the URL.
|
|
72
|
+
* As stated above, it should be handled by `useQueryParams` instead, but that would be a breaking change.
|
|
73
|
+
*/ const deepEncodeQueryValues = (value)=>{
|
|
74
|
+
if (typeof value === 'string') {
|
|
75
|
+
return encodeURIComponent(value);
|
|
76
|
+
}
|
|
77
|
+
if (Array.isArray(value)) {
|
|
78
|
+
return value.map(deepEncodeQueryValues);
|
|
79
|
+
}
|
|
80
|
+
if (value !== null && typeof value === 'object') {
|
|
81
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry])=>[
|
|
82
|
+
key,
|
|
83
|
+
deepEncodeQueryValues(entry)
|
|
84
|
+
]));
|
|
85
|
+
}
|
|
86
|
+
return value;
|
|
87
|
+
};
|
|
88
|
+
const withEncodedUserParams = (query, nextParams)=>({
|
|
89
|
+
...query.filters === undefined ? {} : {
|
|
90
|
+
filters: deepEncodeQueryValues(query.filters)
|
|
91
|
+
},
|
|
92
|
+
...query._q === undefined ? {} : {
|
|
93
|
+
_q: deepEncodeQueryValues(query._q)
|
|
94
|
+
},
|
|
95
|
+
...nextParams
|
|
96
|
+
});
|
|
65
97
|
|
|
98
|
+
exports.deepEncodeQueryValues = deepEncodeQueryValues;
|
|
66
99
|
exports.useQueryParams = useQueryParams;
|
|
100
|
+
exports.withEncodedUserParams = withEncodedUserParams;
|
|
67
101
|
//# sourceMappingURL=useQueryParams.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useQueryParams.js","sources":["../../../../../admin/src/hooks/useQueryParams.ts"],"sourcesContent":["import { useCallback, useMemo } from 'react';\n\nimport { parse, stringify } from 'qs';\nimport { useNavigate, useLocation } from 'react-router-dom';\n\ntype QueryParams = Record<string, unknown>;\n\nconst useSearch = () => {\n const { search } = useLocation();\n\n return useMemo(() => search, [search]);\n};\n\nconst useQueryParams = <TQuery extends object = QueryParams>(initialParams?: TQuery) => {\n const search = useSearch();\n const navigate = useNavigate();\n\n const query = useMemo(() => {\n // TODO: investigate why sometimes we're getting the search with a leading `?` and sometimes not.\n const searchQuery = search.startsWith('?') ? search.slice(1) : search;\n if (!search && initialParams) {\n return initialParams;\n }\n\n return { ...initialParams, ...parse(searchQuery) } as TQuery;\n }, [search, initialParams]);\n\n const setQuery = useCallback(\n (nextParams: TQuery, method: 'push' | 'remove' = 'push', replace = false) => {\n let nextQuery: Partial<TQuery> = { ...query };\n\n if (method === 'remove') {\n Object.keys(nextParams).forEach((key) => {\n if (Object.prototype.hasOwnProperty.call(nextQuery, key)) {\n delete nextQuery[key as keyof TQuery];\n }\n });\n } else {\n nextQuery = { ...query, ...nextParams };\n }\n\n navigate({ search: stringify(nextQuery, { encode: false }) }, { replace });\n },\n [navigate, query]\n );\n\n return [{ query, rawQuery: search }, setQuery] as const;\n};\n\nexport { useQueryParams };\n"],"names":["useSearch","search","useLocation","useMemo","useQueryParams","initialParams","navigate","useNavigate","query","searchQuery","startsWith","slice","parse","setQuery","useCallback","nextParams","method","replace","nextQuery","Object","keys","forEach","key","prototype","hasOwnProperty","call","stringify","encode","rawQuery"],"mappings":";;;;;;AAOA,MAAMA,SAAAA,GAAY,IAAA;IAChB,MAAM,EAAEC,MAAM,EAAE,GAAGC,0BAAAA,EAAAA;IAEnB,OAAOC,aAAAA,CAAQ,IAAMF,MAAAA,EAAQ;AAACA,QAAAA;AAAO,KAAA,CAAA;AACvC,CAAA;AAEA,MAAMG,iBAAiB,CAAsCC,aAAAA,GAAAA;AAC3D,IAAA,MAAMJ,MAAAA,GAASD,SAAAA,EAAAA;AACf,IAAA,MAAMM,QAAAA,GAAWC,0BAAAA,EAAAA;AAEjB,IAAA,MAAMC,QAAQL,aAAAA,CAAQ,IAAA;;QAEpB,MAAMM,WAAAA,GAAcR,OAAOS,UAAU,CAAC,OAAOT,MAAAA,CAAOU,KAAK,CAAC,CAAA,CAAA,GAAKV,MAAAA;QAC/D,IAAI,CAACA,UAAUI,aAAAA,EAAe;YAC5B,OAAOA,aAAAA;AACT,QAAA;QAEA,OAAO;AAAE,YAAA,GAAGA,aAAa;AAAE,YAAA,GAAGO,SAAMH,WAAAA;AAAa,SAAA;IACnD,CAAA,EAAG;AAACR,QAAAA,MAAAA;AAAQI,QAAAA;AAAc,KAAA,CAAA;IAE1B,MAAMQ,QAAAA,GAAWC,kBACf,CAACC,UAAAA,EAAoBC,SAA4B,MAAM,EAAEC,UAAU,KAAK,GAAA;AACtE,QAAA,IAAIC,SAAAA,GAA6B;AAAE,YAAA,GAAGV;AAAM,SAAA;AAE5C,QAAA,IAAIQ,WAAW,QAAA,EAAU;AACvBG,YAAAA,MAAAA,CAAOC,IAAI,CAACL,UAAAA,CAAAA,CAAYM,OAAO,CAAC,CAACC,GAAAA,GAAAA;gBAC/B,IAAIH,MAAAA,CAAOI,SAAS,CAACC,cAAc,CAACC,IAAI,CAACP,WAAWI,GAAAA,CAAAA,EAAM;oBACxD,OAAOJ,SAAS,CAACI,GAAAA,CAAoB;AACvC,gBAAA;AACF,YAAA,CAAA,CAAA;QACF,CAAA,MAAO;YACLJ,SAAAA,GAAY;AAAE,gBAAA,GAAGV,KAAK;AAAE,gBAAA,GAAGO;AAAW,aAAA;AACxC,QAAA;
|
|
1
|
+
{"version":3,"file":"useQueryParams.js","sources":["../../../../../admin/src/hooks/useQueryParams.ts"],"sourcesContent":["import { useCallback, useMemo } from 'react';\n\nimport { parse, stringify } from 'qs';\nimport { useNavigate, useLocation } from 'react-router-dom';\n\ntype QueryParams = Record<string, unknown>;\n\nconst useSearch = () => {\n const { search } = useLocation();\n\n return useMemo(() => search, [search]);\n};\n\nconst useQueryParams = <TQuery extends object = QueryParams>(initialParams?: TQuery) => {\n const search = useSearch();\n const navigate = useNavigate();\n\n const query = useMemo(() => {\n // TODO: investigate why sometimes we're getting the search with a leading `?` and sometimes not.\n const searchQuery = search.startsWith('?') ? search.slice(1) : search;\n if (!search && initialParams) {\n return initialParams;\n }\n\n return { ...initialParams, ...parse(searchQuery) } as TQuery;\n }, [search, initialParams]);\n\n const setQuery = useCallback(\n (nextParams: TQuery, method: 'push' | 'remove' = 'push', replace = false) => {\n let nextQuery: Partial<TQuery> = { ...query };\n\n if (method === 'remove') {\n Object.keys(nextParams).forEach((key) => {\n if (Object.prototype.hasOwnProperty.call(nextQuery, key)) {\n delete nextQuery[key as keyof TQuery];\n }\n });\n } else {\n nextQuery = { ...query, ...nextParams };\n }\n\n /**\n * TODO V6: Encoding should be enabled in this step, via `{ encodeValuesOnly: true }`\n * So the rest of the app doesn't have to worry about it,\n * It's considered a breaking change because callers currently encode values themselves,\n * including the user's custom code, and would end up double-encoding them.\n */\n navigate({ search: stringify(nextQuery, { encode: false }) }, { replace });\n },\n [navigate, query]\n );\n\n return [{ query, rawQuery: search }, setQuery] as const;\n};\n\n/**\n * These functions are used to encode query values when writing them to the URL.\n * As stated above, it should be handled by `useQueryParams` instead, but that would be a breaking change.\n */\n\nconst deepEncodeQueryValues = <T>(value: T): T => {\n if (typeof value === 'string') {\n return encodeURIComponent(value) as T;\n }\n\n if (Array.isArray(value)) {\n return value.map(deepEncodeQueryValues) as T;\n }\n\n if (value !== null && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value).map(([key, entry]) => [key, deepEncodeQueryValues(entry)])\n ) as T;\n }\n\n return value;\n};\n\nconst withEncodedUserParams = <\n T extends object,\n TQuery extends { filters?: unknown; _q?: unknown },\n>(\n query: TQuery,\n nextParams: T\n): T & { filters?: TQuery['filters']; _q?: TQuery['_q'] } => ({\n ...(query.filters === undefined ? {} : { filters: deepEncodeQueryValues(query.filters) }),\n ...(query._q === undefined ? {} : { _q: deepEncodeQueryValues(query._q) }),\n ...nextParams,\n});\n\nexport { useQueryParams, deepEncodeQueryValues, withEncodedUserParams };\n"],"names":["useSearch","search","useLocation","useMemo","useQueryParams","initialParams","navigate","useNavigate","query","searchQuery","startsWith","slice","parse","setQuery","useCallback","nextParams","method","replace","nextQuery","Object","keys","forEach","key","prototype","hasOwnProperty","call","stringify","encode","rawQuery","deepEncodeQueryValues","value","encodeURIComponent","Array","isArray","map","fromEntries","entries","entry","withEncodedUserParams","filters","undefined","_q"],"mappings":"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"}
|
|
@@ -41,7 +41,12 @@ const useQueryParams = (initialParams)=>{
|
|
|
41
41
|
...nextParams
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* TODO V6: Encoding should be enabled in this step, via `{ encodeValuesOnly: true }`
|
|
46
|
+
* So the rest of the app doesn't have to worry about it,
|
|
47
|
+
* It's considered a breaking change because callers currently encode values themselves,
|
|
48
|
+
* including the user's custom code, and would end up double-encoding them.
|
|
49
|
+
*/ navigate({
|
|
45
50
|
search: stringify(nextQuery, {
|
|
46
51
|
encode: false
|
|
47
52
|
})
|
|
@@ -60,6 +65,33 @@ const useQueryParams = (initialParams)=>{
|
|
|
60
65
|
setQuery
|
|
61
66
|
];
|
|
62
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* These functions are used to encode query values when writing them to the URL.
|
|
70
|
+
* As stated above, it should be handled by `useQueryParams` instead, but that would be a breaking change.
|
|
71
|
+
*/ const deepEncodeQueryValues = (value)=>{
|
|
72
|
+
if (typeof value === 'string') {
|
|
73
|
+
return encodeURIComponent(value);
|
|
74
|
+
}
|
|
75
|
+
if (Array.isArray(value)) {
|
|
76
|
+
return value.map(deepEncodeQueryValues);
|
|
77
|
+
}
|
|
78
|
+
if (value !== null && typeof value === 'object') {
|
|
79
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry])=>[
|
|
80
|
+
key,
|
|
81
|
+
deepEncodeQueryValues(entry)
|
|
82
|
+
]));
|
|
83
|
+
}
|
|
84
|
+
return value;
|
|
85
|
+
};
|
|
86
|
+
const withEncodedUserParams = (query, nextParams)=>({
|
|
87
|
+
...query.filters === undefined ? {} : {
|
|
88
|
+
filters: deepEncodeQueryValues(query.filters)
|
|
89
|
+
},
|
|
90
|
+
...query._q === undefined ? {} : {
|
|
91
|
+
_q: deepEncodeQueryValues(query._q)
|
|
92
|
+
},
|
|
93
|
+
...nextParams
|
|
94
|
+
});
|
|
63
95
|
|
|
64
|
-
export { useQueryParams };
|
|
96
|
+
export { deepEncodeQueryValues, useQueryParams, withEncodedUserParams };
|
|
65
97
|
//# sourceMappingURL=useQueryParams.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useQueryParams.mjs","sources":["../../../../../admin/src/hooks/useQueryParams.ts"],"sourcesContent":["import { useCallback, useMemo } from 'react';\n\nimport { parse, stringify } from 'qs';\nimport { useNavigate, useLocation } from 'react-router-dom';\n\ntype QueryParams = Record<string, unknown>;\n\nconst useSearch = () => {\n const { search } = useLocation();\n\n return useMemo(() => search, [search]);\n};\n\nconst useQueryParams = <TQuery extends object = QueryParams>(initialParams?: TQuery) => {\n const search = useSearch();\n const navigate = useNavigate();\n\n const query = useMemo(() => {\n // TODO: investigate why sometimes we're getting the search with a leading `?` and sometimes not.\n const searchQuery = search.startsWith('?') ? search.slice(1) : search;\n if (!search && initialParams) {\n return initialParams;\n }\n\n return { ...initialParams, ...parse(searchQuery) } as TQuery;\n }, [search, initialParams]);\n\n const setQuery = useCallback(\n (nextParams: TQuery, method: 'push' | 'remove' = 'push', replace = false) => {\n let nextQuery: Partial<TQuery> = { ...query };\n\n if (method === 'remove') {\n Object.keys(nextParams).forEach((key) => {\n if (Object.prototype.hasOwnProperty.call(nextQuery, key)) {\n delete nextQuery[key as keyof TQuery];\n }\n });\n } else {\n nextQuery = { ...query, ...nextParams };\n }\n\n navigate({ search: stringify(nextQuery, { encode: false }) }, { replace });\n },\n [navigate, query]\n );\n\n return [{ query, rawQuery: search }, setQuery] as const;\n};\n\nexport { useQueryParams };\n"],"names":["useSearch","search","useLocation","useMemo","useQueryParams","initialParams","navigate","useNavigate","query","searchQuery","startsWith","slice","parse","setQuery","useCallback","nextParams","method","replace","nextQuery","Object","keys","forEach","key","prototype","hasOwnProperty","call","stringify","encode","rawQuery"],"mappings":";;;;AAOA,MAAMA,SAAAA,GAAY,IAAA;IAChB,MAAM,EAAEC,MAAM,EAAE,GAAGC,WAAAA,EAAAA;IAEnB,OAAOC,OAAAA,CAAQ,IAAMF,MAAAA,EAAQ;AAACA,QAAAA;AAAO,KAAA,CAAA;AACvC,CAAA;AAEA,MAAMG,iBAAiB,CAAsCC,aAAAA,GAAAA;AAC3D,IAAA,MAAMJ,MAAAA,GAASD,SAAAA,EAAAA;AACf,IAAA,MAAMM,QAAAA,GAAWC,WAAAA,EAAAA;AAEjB,IAAA,MAAMC,QAAQL,OAAAA,CAAQ,IAAA;;QAEpB,MAAMM,WAAAA,GAAcR,OAAOS,UAAU,CAAC,OAAOT,MAAAA,CAAOU,KAAK,CAAC,CAAA,CAAA,GAAKV,MAAAA;QAC/D,IAAI,CAACA,UAAUI,aAAAA,EAAe;YAC5B,OAAOA,aAAAA;AACT,QAAA;QAEA,OAAO;AAAE,YAAA,GAAGA,aAAa;AAAE,YAAA,GAAGO,MAAMH,WAAAA;AAAa,SAAA;IACnD,CAAA,EAAG;AAACR,QAAAA,MAAAA;AAAQI,QAAAA;AAAc,KAAA,CAAA;IAE1B,MAAMQ,QAAAA,GAAWC,YACf,CAACC,UAAAA,EAAoBC,SAA4B,MAAM,EAAEC,UAAU,KAAK,GAAA;AACtE,QAAA,IAAIC,SAAAA,GAA6B;AAAE,YAAA,GAAGV;AAAM,SAAA;AAE5C,QAAA,IAAIQ,WAAW,QAAA,EAAU;AACvBG,YAAAA,MAAAA,CAAOC,IAAI,CAACL,UAAAA,CAAAA,CAAYM,OAAO,CAAC,CAACC,GAAAA,GAAAA;gBAC/B,IAAIH,MAAAA,CAAOI,SAAS,CAACC,cAAc,CAACC,IAAI,CAACP,WAAWI,GAAAA,CAAAA,EAAM;oBACxD,OAAOJ,SAAS,CAACI,GAAAA,CAAoB;AACvC,gBAAA;AACF,YAAA,CAAA,CAAA;QACF,CAAA,MAAO;YACLJ,SAAAA,GAAY;AAAE,gBAAA,GAAGV,KAAK;AAAE,gBAAA,GAAGO;AAAW,aAAA;AACxC,QAAA;
|
|
1
|
+
{"version":3,"file":"useQueryParams.mjs","sources":["../../../../../admin/src/hooks/useQueryParams.ts"],"sourcesContent":["import { useCallback, useMemo } from 'react';\n\nimport { parse, stringify } from 'qs';\nimport { useNavigate, useLocation } from 'react-router-dom';\n\ntype QueryParams = Record<string, unknown>;\n\nconst useSearch = () => {\n const { search } = useLocation();\n\n return useMemo(() => search, [search]);\n};\n\nconst useQueryParams = <TQuery extends object = QueryParams>(initialParams?: TQuery) => {\n const search = useSearch();\n const navigate = useNavigate();\n\n const query = useMemo(() => {\n // TODO: investigate why sometimes we're getting the search with a leading `?` and sometimes not.\n const searchQuery = search.startsWith('?') ? search.slice(1) : search;\n if (!search && initialParams) {\n return initialParams;\n }\n\n return { ...initialParams, ...parse(searchQuery) } as TQuery;\n }, [search, initialParams]);\n\n const setQuery = useCallback(\n (nextParams: TQuery, method: 'push' | 'remove' = 'push', replace = false) => {\n let nextQuery: Partial<TQuery> = { ...query };\n\n if (method === 'remove') {\n Object.keys(nextParams).forEach((key) => {\n if (Object.prototype.hasOwnProperty.call(nextQuery, key)) {\n delete nextQuery[key as keyof TQuery];\n }\n });\n } else {\n nextQuery = { ...query, ...nextParams };\n }\n\n /**\n * TODO V6: Encoding should be enabled in this step, via `{ encodeValuesOnly: true }`\n * So the rest of the app doesn't have to worry about it,\n * It's considered a breaking change because callers currently encode values themselves,\n * including the user's custom code, and would end up double-encoding them.\n */\n navigate({ search: stringify(nextQuery, { encode: false }) }, { replace });\n },\n [navigate, query]\n );\n\n return [{ query, rawQuery: search }, setQuery] as const;\n};\n\n/**\n * These functions are used to encode query values when writing them to the URL.\n * As stated above, it should be handled by `useQueryParams` instead, but that would be a breaking change.\n */\n\nconst deepEncodeQueryValues = <T>(value: T): T => {\n if (typeof value === 'string') {\n return encodeURIComponent(value) as T;\n }\n\n if (Array.isArray(value)) {\n return value.map(deepEncodeQueryValues) as T;\n }\n\n if (value !== null && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value).map(([key, entry]) => [key, deepEncodeQueryValues(entry)])\n ) as T;\n }\n\n return value;\n};\n\nconst withEncodedUserParams = <\n T extends object,\n TQuery extends { filters?: unknown; _q?: unknown },\n>(\n query: TQuery,\n nextParams: T\n): T & { filters?: TQuery['filters']; _q?: TQuery['_q'] } => ({\n ...(query.filters === undefined ? {} : { filters: deepEncodeQueryValues(query.filters) }),\n ...(query._q === undefined ? {} : { _q: deepEncodeQueryValues(query._q) }),\n ...nextParams,\n});\n\nexport { useQueryParams, deepEncodeQueryValues, withEncodedUserParams };\n"],"names":["useSearch","search","useLocation","useMemo","useQueryParams","initialParams","navigate","useNavigate","query","searchQuery","startsWith","slice","parse","setQuery","useCallback","nextParams","method","replace","nextQuery","Object","keys","forEach","key","prototype","hasOwnProperty","call","stringify","encode","rawQuery","deepEncodeQueryValues","value","encodeURIComponent","Array","isArray","map","fromEntries","entries","entry","withEncodedUserParams","filters","undefined","_q"],"mappings":"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"}
|
|
@@ -184,6 +184,7 @@ var en = {
|
|
|
184
184
|
"Settings.permissions.auditLogs.action": "Action",
|
|
185
185
|
"Settings.permissions.auditLogs.admin.auth.success": "Admin login",
|
|
186
186
|
"Settings.permissions.auditLogs.admin.logout": "Admin logout",
|
|
187
|
+
"Settings.permissions.auditLogs.audit-log.export": "Export audit logs",
|
|
187
188
|
"Settings.permissions.auditLogs.component.create": "Create component",
|
|
188
189
|
"Settings.permissions.auditLogs.component.delete": "Delete component",
|
|
189
190
|
"Settings.permissions.auditLogs.component.update": "Update component",
|
|
@@ -198,6 +199,15 @@ var en = {
|
|
|
198
199
|
"Settings.permissions.auditLogs.entry.unpublish": "Unpublish entry{model, select, undefined {} other { ({model})}}",
|
|
199
200
|
"Settings.permissions.auditLogs.entry.update": "Update entry{model, select, undefined {} other { ({model})}}",
|
|
200
201
|
"Settings.permissions.auditLogs.filters.combobox.aria-label": "Search and select an option to filter",
|
|
202
|
+
"Settings.permissions.auditLogs.listview.export": "Export as CSV",
|
|
203
|
+
"Settings.permissions.auditLogs.listview.export.error": "The export failed. Please try again.",
|
|
204
|
+
"Settings.permissions.auditLogs.listview.export.error.forbidden": "You don't have the permissions to export audit logs.",
|
|
205
|
+
"Settings.permissions.auditLogs.listview.export.error.tooLarge": "Table too large to export. Please add filters and try again.",
|
|
206
|
+
"Settings.permissions.auditLogs.listview.export.leave": "Are you sure you want to leave? Your ongoing export will be canceled.",
|
|
207
|
+
"Settings.permissions.auditLogs.listview.export.progress.caption": "Preparing your export - {fetched, number} out of {total, plural, one {# event} other {# events}}",
|
|
208
|
+
"Settings.permissions.auditLogs.listview.export.progress.title": "Exporting audit logs",
|
|
209
|
+
"Settings.permissions.auditLogs.listview.export.ready.download": "Download CSV",
|
|
210
|
+
"Settings.permissions.auditLogs.listview.export.ready.title": "Export ready",
|
|
201
211
|
"Settings.permissions.auditLogs.listview.header.subtitle": "Logs of all the activities that happened in your environment",
|
|
202
212
|
"Settings.permissions.auditLogs.not-available": "Audit Logs is only available as part of a paid plan. Upgrade to get a searchable and filterable display of all activities.",
|
|
203
213
|
"Settings.permissions.auditLogs.media.create": "Create media",
|
|
@@ -206,6 +216,14 @@ var en = {
|
|
|
206
216
|
"Settings.permissions.auditLogs.payload": "Payload",
|
|
207
217
|
"Settings.permissions.auditLogs.permission.create": "Create permission",
|
|
208
218
|
"Settings.permissions.auditLogs.permission.delete": "Delete permission",
|
|
219
|
+
"Settings.permissions.auditLogs.release.create": "Create release",
|
|
220
|
+
"Settings.permissions.auditLogs.release.update": "Update release",
|
|
221
|
+
"Settings.permissions.auditLogs.release.delete": "Delete release",
|
|
222
|
+
"Settings.permissions.auditLogs.release.trigger": "Trigger release",
|
|
223
|
+
"Settings.permissions.auditLogs.release.entry.add": "Add entry to release",
|
|
224
|
+
"Settings.permissions.auditLogs.release.entry.update": "Change entry on release",
|
|
225
|
+
"Settings.permissions.auditLogs.release.entry.remove": "Remove entry from release",
|
|
226
|
+
"Settings.permissions.auditLogs.release.settings.update": "Update release settings",
|
|
209
227
|
"Settings.permissions.auditLogs.permission.update": "Update permission",
|
|
210
228
|
"Settings.permissions.auditLogs.role.create": "Create role",
|
|
211
229
|
"Settings.permissions.auditLogs.role.delete": "Delete role",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -180,6 +180,7 @@ var en = {
|
|
|
180
180
|
"Settings.permissions.auditLogs.action": "Action",
|
|
181
181
|
"Settings.permissions.auditLogs.admin.auth.success": "Admin login",
|
|
182
182
|
"Settings.permissions.auditLogs.admin.logout": "Admin logout",
|
|
183
|
+
"Settings.permissions.auditLogs.audit-log.export": "Export audit logs",
|
|
183
184
|
"Settings.permissions.auditLogs.component.create": "Create component",
|
|
184
185
|
"Settings.permissions.auditLogs.component.delete": "Delete component",
|
|
185
186
|
"Settings.permissions.auditLogs.component.update": "Update component",
|
|
@@ -194,6 +195,15 @@ var en = {
|
|
|
194
195
|
"Settings.permissions.auditLogs.entry.unpublish": "Unpublish entry{model, select, undefined {} other { ({model})}}",
|
|
195
196
|
"Settings.permissions.auditLogs.entry.update": "Update entry{model, select, undefined {} other { ({model})}}",
|
|
196
197
|
"Settings.permissions.auditLogs.filters.combobox.aria-label": "Search and select an option to filter",
|
|
198
|
+
"Settings.permissions.auditLogs.listview.export": "Export as CSV",
|
|
199
|
+
"Settings.permissions.auditLogs.listview.export.error": "The export failed. Please try again.",
|
|
200
|
+
"Settings.permissions.auditLogs.listview.export.error.forbidden": "You don't have the permissions to export audit logs.",
|
|
201
|
+
"Settings.permissions.auditLogs.listview.export.error.tooLarge": "Table too large to export. Please add filters and try again.",
|
|
202
|
+
"Settings.permissions.auditLogs.listview.export.leave": "Are you sure you want to leave? Your ongoing export will be canceled.",
|
|
203
|
+
"Settings.permissions.auditLogs.listview.export.progress.caption": "Preparing your export - {fetched, number} out of {total, plural, one {# event} other {# events}}",
|
|
204
|
+
"Settings.permissions.auditLogs.listview.export.progress.title": "Exporting audit logs",
|
|
205
|
+
"Settings.permissions.auditLogs.listview.export.ready.download": "Download CSV",
|
|
206
|
+
"Settings.permissions.auditLogs.listview.export.ready.title": "Export ready",
|
|
197
207
|
"Settings.permissions.auditLogs.listview.header.subtitle": "Logs of all the activities that happened in your environment",
|
|
198
208
|
"Settings.permissions.auditLogs.not-available": "Audit Logs is only available as part of a paid plan. Upgrade to get a searchable and filterable display of all activities.",
|
|
199
209
|
"Settings.permissions.auditLogs.media.create": "Create media",
|
|
@@ -202,6 +212,14 @@ var en = {
|
|
|
202
212
|
"Settings.permissions.auditLogs.payload": "Payload",
|
|
203
213
|
"Settings.permissions.auditLogs.permission.create": "Create permission",
|
|
204
214
|
"Settings.permissions.auditLogs.permission.delete": "Delete permission",
|
|
215
|
+
"Settings.permissions.auditLogs.release.create": "Create release",
|
|
216
|
+
"Settings.permissions.auditLogs.release.update": "Update release",
|
|
217
|
+
"Settings.permissions.auditLogs.release.delete": "Delete release",
|
|
218
|
+
"Settings.permissions.auditLogs.release.trigger": "Trigger release",
|
|
219
|
+
"Settings.permissions.auditLogs.release.entry.add": "Add entry to release",
|
|
220
|
+
"Settings.permissions.auditLogs.release.entry.update": "Change entry on release",
|
|
221
|
+
"Settings.permissions.auditLogs.release.entry.remove": "Remove entry from release",
|
|
222
|
+
"Settings.permissions.auditLogs.release.settings.update": "Update release settings",
|
|
205
223
|
"Settings.permissions.auditLogs.permission.update": "Update permission",
|
|
206
224
|
"Settings.permissions.auditLogs.role.create": "Create role",
|
|
207
225
|
"Settings.permissions.auditLogs.role.delete": "Delete role",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var pipe = require('lodash/fp/pipe');
|
|
4
4
|
var qs = require('qs');
|
|
5
5
|
var cookies = require('./cookies.js');
|
|
6
|
+
var jwt = require('./jwt.js');
|
|
6
7
|
|
|
7
8
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
9
|
|
|
@@ -80,33 +81,105 @@ const STORAGE_KEYS = {
|
|
|
80
81
|
onTokenUpdate(token);
|
|
81
82
|
}
|
|
82
83
|
};
|
|
84
|
+
const getToken = ()=>{
|
|
85
|
+
const fromLocalStorage = localStorage.getItem(STORAGE_KEYS.TOKEN);
|
|
86
|
+
if (fromLocalStorage) {
|
|
87
|
+
return JSON.parse(fromLocalStorage);
|
|
88
|
+
}
|
|
89
|
+
const fromCookie = cookies.getCookieValue(cookies.AUTH_COOKIE_NAME);
|
|
90
|
+
return fromCookie ?? null;
|
|
91
|
+
};
|
|
92
|
+
const ADMIN_REFRESH_LOCK = 'strapi-admin-access-token';
|
|
93
|
+
const FALLBACK_ADOPT_TIMEOUT_MS = 250;
|
|
94
|
+
const FALLBACK_ADOPT_POLL_MS = 25;
|
|
95
|
+
const postAccessToken = (backendURL)=>fetch(`${backendURL}/admin/access-token`, {
|
|
96
|
+
method: 'POST',
|
|
97
|
+
credentials: 'include',
|
|
98
|
+
headers: {
|
|
99
|
+
Accept: 'application/json',
|
|
100
|
+
'Content-Type': 'application/json'
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
const adoptSharedAccessToken = (token)=>{
|
|
104
|
+
if (onTokenUpdate) {
|
|
105
|
+
onTokenUpdate(token);
|
|
106
|
+
}
|
|
107
|
+
return token;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Another tab may have refreshed already and written a newer access token to the
|
|
111
|
+
* shared localStorage/cookie. Per-tab Redux is not visible here — only shared
|
|
112
|
+
* storage counts.
|
|
113
|
+
*/ const readValidAccessTokenFromSharedStorage = (staleToken)=>{
|
|
114
|
+
const stored = getToken();
|
|
115
|
+
if (!stored || stored === staleToken) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const expiry = jwt.decodeAccessTokenExpiry(stored);
|
|
119
|
+
if (expiry === null || expiry <= Date.now()) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
return stored;
|
|
123
|
+
};
|
|
124
|
+
const waitForSharedAccessToken = async (staleToken)=>{
|
|
125
|
+
const timeoutAt = Date.now() + FALLBACK_ADOPT_TIMEOUT_MS;
|
|
126
|
+
while(Date.now() < timeoutAt){
|
|
127
|
+
await new Promise((resolve)=>{
|
|
128
|
+
setTimeout(resolve, FALLBACK_ADOPT_POLL_MS);
|
|
129
|
+
});
|
|
130
|
+
const adopted = readValidAccessTokenFromSharedStorage(staleToken);
|
|
131
|
+
if (adopted) {
|
|
132
|
+
return adoptSharedAccessToken(adopted);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
};
|
|
137
|
+
const executeRefreshAccessToken = async (backendURL, tokenBeforeRefresh, { allowHttpRetry })=>{
|
|
138
|
+
const adopted = readValidAccessTokenFromSharedStorage(tokenBeforeRefresh);
|
|
139
|
+
if (adopted) {
|
|
140
|
+
return adoptSharedAccessToken(adopted);
|
|
141
|
+
}
|
|
142
|
+
let response = await postAccessToken(backendURL);
|
|
143
|
+
if (response.status === 401 && allowHttpRetry) {
|
|
144
|
+
const adoptedAfterFail = readValidAccessTokenFromSharedStorage(tokenBeforeRefresh);
|
|
145
|
+
if (adoptedAfterFail) {
|
|
146
|
+
return adoptSharedAccessToken(adoptedAfterFail);
|
|
147
|
+
}
|
|
148
|
+
const adoptedAfterWait = await waitForSharedAccessToken(tokenBeforeRefresh);
|
|
149
|
+
if (adoptedAfterWait) {
|
|
150
|
+
return adoptedAfterWait;
|
|
151
|
+
}
|
|
152
|
+
response = await postAccessToken(backendURL);
|
|
153
|
+
}
|
|
154
|
+
if (!response.ok) {
|
|
155
|
+
console.warn('[Auth] Token refresh failed with status:', response.status);
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
const result = await response.json();
|
|
159
|
+
const token = result?.data?.token;
|
|
160
|
+
if (!token) {
|
|
161
|
+
console.warn('[Auth] Token refresh response missing token');
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
storeToken(token);
|
|
165
|
+
return token;
|
|
166
|
+
};
|
|
83
167
|
/**
|
|
84
168
|
* Refresh the access token by calling the /admin/access-token endpoint.
|
|
85
169
|
* This uses a low-level fetch to avoid recursion through the interceptor.
|
|
86
170
|
* Returns the new token on success, or null on failure.
|
|
87
|
-
*/ const refreshAccessToken = async ()=>{
|
|
171
|
+
*/ const refreshAccessToken = async (tokenUsedByFailedRequest)=>{
|
|
88
172
|
const backendURL = window.strapi.backendURL;
|
|
173
|
+
const tokenBeforeRefresh = tokenUsedByFailedRequest ?? getToken();
|
|
89
174
|
try {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
Accept: 'application/json',
|
|
95
|
-
'Content-Type': 'application/json'
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
if (!response.ok) {
|
|
99
|
-
console.warn('[Auth] Token refresh failed with status:', response.status);
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
const result = await response.json();
|
|
103
|
-
const token = result?.data?.token;
|
|
104
|
-
if (!token) {
|
|
105
|
-
console.warn('[Auth] Token refresh response missing token');
|
|
106
|
-
return null;
|
|
175
|
+
if (typeof navigator !== 'undefined' && navigator.locks?.request) {
|
|
176
|
+
return await navigator.locks.request(ADMIN_REFRESH_LOCK, ()=>executeRefreshAccessToken(backendURL, tokenBeforeRefresh, {
|
|
177
|
+
allowHttpRetry: false
|
|
178
|
+
}));
|
|
107
179
|
}
|
|
108
|
-
|
|
109
|
-
|
|
180
|
+
return await executeRefreshAccessToken(backendURL, tokenBeforeRefresh, {
|
|
181
|
+
allowHttpRetry: true
|
|
182
|
+
});
|
|
110
183
|
} catch (error) {
|
|
111
184
|
console.error('[Auth] Token refresh error:', error);
|
|
112
185
|
return null;
|
|
@@ -119,9 +192,9 @@ const STORAGE_KEYS = {
|
|
|
119
192
|
* @returns The new authentication token
|
|
120
193
|
* @throws {Error} If the token refresh fails (e.g., refresh token expired)
|
|
121
194
|
* @internal Exported for testing purposes
|
|
122
|
-
*/ const attemptTokenRefresh = async ()=>{
|
|
195
|
+
*/ const attemptTokenRefresh = async (tokenUsedByFailedRequest)=>{
|
|
123
196
|
if (!refreshPromise) {
|
|
124
|
-
refreshPromise = refreshAccessToken().finally(()=>{
|
|
197
|
+
refreshPromise = refreshAccessToken(tokenUsedByFailedRequest).finally(()=>{
|
|
125
198
|
refreshPromise = null;
|
|
126
199
|
});
|
|
127
200
|
}
|
|
@@ -150,14 +223,6 @@ class FetchError extends Error {
|
|
|
150
223
|
const isFetchError = (error)=>{
|
|
151
224
|
return error instanceof FetchError;
|
|
152
225
|
};
|
|
153
|
-
const getToken = ()=>{
|
|
154
|
-
const fromLocalStorage = localStorage.getItem(STORAGE_KEYS.TOKEN);
|
|
155
|
-
if (fromLocalStorage) {
|
|
156
|
-
return JSON.parse(fromLocalStorage);
|
|
157
|
-
}
|
|
158
|
-
const fromCookie = cookies.getCookieValue(cookies.AUTH_COOKIE_NAME);
|
|
159
|
-
return fromCookie ?? null;
|
|
160
|
-
};
|
|
161
226
|
/**
|
|
162
227
|
* @public
|
|
163
228
|
* @param {FetchConfig} [defaultOptions={}] - Fetch Configs.
|
|
@@ -182,10 +247,10 @@ const getToken = ()=>{
|
|
|
182
247
|
/**
|
|
183
248
|
* Create default headers with the current token.
|
|
184
249
|
* This is a function so we can get a fresh token after refresh.
|
|
185
|
-
*/ const getDefaultHeaders = ()=>({
|
|
250
|
+
*/ const getDefaultHeaders = (token = getToken())=>({
|
|
186
251
|
Accept: 'application/json',
|
|
187
252
|
'Content-Type': 'application/json',
|
|
188
|
-
Authorization: `Bearer ${
|
|
253
|
+
Authorization: `Bearer ${token}`
|
|
189
254
|
});
|
|
190
255
|
const isFormDataRequest = (body)=>body instanceof FormData;
|
|
191
256
|
const addPrependingSlash = (url)=>url.charAt(0) !== '/' ? `/${url}` : url;
|
|
@@ -260,14 +325,14 @@ const getToken = ()=>{
|
|
|
260
325
|
* Execute a fetch request with automatic token refresh on 401 errors.
|
|
261
326
|
* @param url - The request URL (used to check if it's an auth path)
|
|
262
327
|
* @param executeRequest - Function that performs the fetch (called again on retry with fresh headers)
|
|
263
|
-
*/ const withTokenRefresh = async (url, executeRequest)=>{
|
|
328
|
+
*/ const withTokenRefresh = async (url, executeRequest, getRequestToken)=>{
|
|
264
329
|
try {
|
|
265
330
|
return await executeRequest();
|
|
266
331
|
} catch (error) {
|
|
267
332
|
// Only attempt refresh for 401 errors on non-auth paths
|
|
268
333
|
if (isFetchError(error) && error.status === 401 && !isAuthPath(url)) {
|
|
269
334
|
try {
|
|
270
|
-
await attemptTokenRefresh();
|
|
335
|
+
await attemptTokenRefresh(getRequestToken());
|
|
271
336
|
// Retry - executeRequest will call getDefaultHeaders() again, picking up the new token
|
|
272
337
|
return await executeRequest();
|
|
273
338
|
} catch {
|
|
@@ -308,10 +373,12 @@ const getToken = ()=>{
|
|
|
308
373
|
get: async (url, options)=>{
|
|
309
374
|
const createRequestUrl = makeCreateRequestUrl(options);
|
|
310
375
|
const responseType = options?.responseType ?? 'json';
|
|
376
|
+
let requestToken = null;
|
|
311
377
|
const executeRequest = async ()=>{
|
|
312
|
-
|
|
378
|
+
requestToken = getToken();
|
|
379
|
+
const { Authorization } = getDefaultHeaders(requestToken);
|
|
313
380
|
// For non-JSON response types, omit content negotiation headers that imply JSON
|
|
314
|
-
const defaultHeaders = responseType === 'json' ? getDefaultHeaders() : {
|
|
381
|
+
const defaultHeaders = responseType === 'json' ? getDefaultHeaders(requestToken) : {
|
|
315
382
|
Authorization
|
|
316
383
|
};
|
|
317
384
|
const headers = new Headers({
|
|
@@ -326,13 +393,15 @@ const getToken = ()=>{
|
|
|
326
393
|
});
|
|
327
394
|
return responseInterceptor(response, options?.validateStatus, responseType);
|
|
328
395
|
};
|
|
329
|
-
return withTokenRefresh(url, executeRequest);
|
|
396
|
+
return withTokenRefresh(url, executeRequest, ()=>requestToken);
|
|
330
397
|
},
|
|
331
398
|
post: async (url, data, options)=>{
|
|
332
399
|
const createRequestUrl = makeCreateRequestUrl(options);
|
|
400
|
+
let requestToken = null;
|
|
333
401
|
const executeRequest = async ()=>{
|
|
402
|
+
requestToken = getToken();
|
|
334
403
|
const headers = new Headers({
|
|
335
|
-
...getDefaultHeaders(),
|
|
404
|
+
...getDefaultHeaders(requestToken),
|
|
336
405
|
...options?.headers
|
|
337
406
|
});
|
|
338
407
|
/**
|
|
@@ -350,13 +419,15 @@ const getToken = ()=>{
|
|
|
350
419
|
});
|
|
351
420
|
return responseInterceptor(response, options?.validateStatus);
|
|
352
421
|
};
|
|
353
|
-
return withTokenRefresh(url, executeRequest);
|
|
422
|
+
return withTokenRefresh(url, executeRequest, ()=>requestToken);
|
|
354
423
|
},
|
|
355
424
|
put: async (url, data, options)=>{
|
|
356
425
|
const createRequestUrl = makeCreateRequestUrl(options);
|
|
426
|
+
let requestToken = null;
|
|
357
427
|
const executeRequest = async ()=>{
|
|
428
|
+
requestToken = getToken();
|
|
358
429
|
const headers = new Headers({
|
|
359
|
-
...getDefaultHeaders(),
|
|
430
|
+
...getDefaultHeaders(requestToken),
|
|
360
431
|
...options?.headers
|
|
361
432
|
});
|
|
362
433
|
/**
|
|
@@ -374,13 +445,15 @@ const getToken = ()=>{
|
|
|
374
445
|
});
|
|
375
446
|
return responseInterceptor(response, options?.validateStatus);
|
|
376
447
|
};
|
|
377
|
-
return withTokenRefresh(url, executeRequest);
|
|
448
|
+
return withTokenRefresh(url, executeRequest, ()=>requestToken);
|
|
378
449
|
},
|
|
379
450
|
del: async (url, options)=>{
|
|
380
451
|
const createRequestUrl = makeCreateRequestUrl(options);
|
|
452
|
+
let requestToken = null;
|
|
381
453
|
const executeRequest = async ()=>{
|
|
454
|
+
requestToken = getToken();
|
|
382
455
|
const headers = new Headers({
|
|
383
|
-
...getDefaultHeaders(),
|
|
456
|
+
...getDefaultHeaders(requestToken),
|
|
384
457
|
...options?.headers
|
|
385
458
|
});
|
|
386
459
|
const response = await fetch(createRequestUrl(url), {
|
|
@@ -391,16 +464,18 @@ const getToken = ()=>{
|
|
|
391
464
|
});
|
|
392
465
|
return responseInterceptor(response, options?.validateStatus);
|
|
393
466
|
};
|
|
394
|
-
return withTokenRefresh(url, executeRequest);
|
|
467
|
+
return withTokenRefresh(url, executeRequest, ()=>requestToken);
|
|
395
468
|
}
|
|
396
469
|
};
|
|
397
470
|
return fetchClient;
|
|
398
471
|
};
|
|
399
472
|
|
|
473
|
+
exports.ADMIN_REFRESH_LOCK = ADMIN_REFRESH_LOCK;
|
|
400
474
|
exports.FetchError = FetchError;
|
|
401
475
|
exports.attemptTokenRefresh = attemptTokenRefresh;
|
|
402
476
|
exports.getFetchClient = getFetchClient;
|
|
403
477
|
exports.isFetchError = isFetchError;
|
|
478
|
+
exports.refreshAccessToken = refreshAccessToken;
|
|
404
479
|
exports.setOnSessionExpired = setOnSessionExpired;
|
|
405
480
|
exports.setOnTokenUpdate = setOnTokenUpdate;
|
|
406
481
|
exports.storeToken = storeToken;
|