@strapi/admin 5.17.0 → 5.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/dist/admin/admin/src/StrapiApp.js +27 -4
  2. package/dist/admin/admin/src/StrapiApp.js.map +1 -1
  3. package/dist/admin/admin/src/StrapiApp.mjs +27 -4
  4. package/dist/admin/admin/src/StrapiApp.mjs.map +1 -1
  5. package/dist/admin/admin/src/components/LeftMenu.js +1 -1
  6. package/dist/admin/admin/src/components/LeftMenu.js.map +1 -1
  7. package/dist/admin/admin/src/components/LeftMenu.mjs +2 -2
  8. package/dist/admin/admin/src/components/LeftMenu.mjs.map +1 -1
  9. package/dist/admin/admin/src/components/MainNav/NavLink.js +40 -4
  10. package/dist/admin/admin/src/components/MainNav/NavLink.js.map +1 -1
  11. package/dist/admin/admin/src/components/MainNav/NavLink.mjs +21 -4
  12. package/dist/admin/admin/src/components/MainNav/NavLink.mjs.map +1 -1
  13. package/dist/admin/admin/src/components/MainNav/NavUser.js +1 -1
  14. package/dist/admin/admin/src/components/MainNav/NavUser.js.map +1 -1
  15. package/dist/admin/admin/src/components/MainNav/NavUser.mjs +1 -1
  16. package/dist/admin/admin/src/components/MainNav/NavUser.mjs.map +1 -1
  17. package/dist/admin/admin/src/components/Providers.js +0 -2
  18. package/dist/admin/admin/src/components/Providers.js.map +1 -1
  19. package/dist/admin/admin/src/components/Providers.mjs +0 -2
  20. package/dist/admin/admin/src/components/Providers.mjs.map +1 -1
  21. package/dist/admin/admin/src/components/SubNav.js +27 -7
  22. package/dist/admin/admin/src/components/SubNav.js.map +1 -1
  23. package/dist/admin/admin/src/components/SubNav.mjs +28 -8
  24. package/dist/admin/admin/src/components/SubNav.mjs.map +1 -1
  25. package/dist/admin/admin/src/components/UnstableGuidedTour/Context.js +31 -9
  26. package/dist/admin/admin/src/components/UnstableGuidedTour/Context.js.map +1 -1
  27. package/dist/admin/admin/src/components/UnstableGuidedTour/Context.mjs +31 -9
  28. package/dist/admin/admin/src/components/UnstableGuidedTour/Context.mjs.map +1 -1
  29. package/dist/admin/admin/src/components/UnstableGuidedTour/Overview.js +291 -0
  30. package/dist/admin/admin/src/components/UnstableGuidedTour/Overview.js.map +1 -0
  31. package/dist/admin/admin/src/components/UnstableGuidedTour/Overview.mjs +289 -0
  32. package/dist/admin/admin/src/components/UnstableGuidedTour/Overview.mjs.map +1 -0
  33. package/dist/admin/admin/src/components/UnstableGuidedTour/Step.js +20 -4
  34. package/dist/admin/admin/src/components/UnstableGuidedTour/Step.js.map +1 -1
  35. package/dist/admin/admin/src/components/UnstableGuidedTour/Step.mjs +21 -5
  36. package/dist/admin/admin/src/components/UnstableGuidedTour/Step.mjs.map +1 -1
  37. package/dist/admin/admin/src/components/UnstableGuidedTour/Tours.js +299 -26
  38. package/dist/admin/admin/src/components/UnstableGuidedTour/Tours.js.map +1 -1
  39. package/dist/admin/admin/src/components/UnstableGuidedTour/Tours.mjs +301 -27
  40. package/dist/admin/admin/src/components/UnstableGuidedTour/Tours.mjs.map +1 -1
  41. package/dist/admin/admin/src/components/Widgets.js +52 -0
  42. package/dist/admin/admin/src/components/Widgets.js.map +1 -0
  43. package/dist/admin/admin/src/components/Widgets.mjs +50 -0
  44. package/dist/admin/admin/src/components/Widgets.mjs.map +1 -0
  45. package/dist/admin/admin/src/core/apis/Widgets.js.map +1 -1
  46. package/dist/admin/admin/src/core/apis/Widgets.mjs.map +1 -1
  47. package/dist/admin/admin/src/features/Auth.js.map +1 -1
  48. package/dist/admin/admin/src/features/Auth.mjs.map +1 -1
  49. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
  50. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
  51. package/dist/admin/admin/src/pages/Home/HomePage.js +2 -1
  52. package/dist/admin/admin/src/pages/Home/HomePage.js.map +1 -1
  53. package/dist/admin/admin/src/pages/Home/HomePage.mjs +2 -1
  54. package/dist/admin/admin/src/pages/Home/HomePage.mjs.map +1 -1
  55. package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.js +93 -0
  56. package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.js.map +1 -1
  57. package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.mjs +95 -3
  58. package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.mjs.map +1 -1
  59. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.js +8 -3
  60. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.js.map +1 -1
  61. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.mjs +10 -5
  62. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.mjs.map +1 -1
  63. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.js +6 -1
  64. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.js.map +1 -1
  65. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.mjs +6 -1
  66. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.mjs.map +1 -1
  67. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.js +58 -53
  68. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.js.map +1 -1
  69. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.mjs +58 -53
  70. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.mjs.map +1 -1
  71. package/dist/admin/admin/src/translations/en.json.js +29 -2
  72. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  73. package/dist/admin/admin/src/translations/en.json.mjs +29 -2
  74. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  75. package/dist/admin/admin/src/translations/es.json.js +1 -0
  76. package/dist/admin/admin/src/translations/es.json.js.map +1 -1
  77. package/dist/admin/admin/src/translations/es.json.mjs +1 -0
  78. package/dist/admin/admin/src/translations/es.json.mjs.map +1 -1
  79. package/dist/admin/admin/src/translations/fr.json.js +3 -1
  80. package/dist/admin/admin/src/translations/fr.json.js.map +1 -1
  81. package/dist/admin/admin/src/translations/fr.json.mjs +3 -1
  82. package/dist/admin/admin/src/translations/fr.json.mjs.map +1 -1
  83. package/dist/admin/admin/src/utils/users.js +8 -0
  84. package/dist/admin/admin/src/utils/users.js.map +1 -1
  85. package/dist/admin/admin/src/utils/users.mjs +8 -1
  86. package/dist/admin/admin/src/utils/users.mjs.map +1 -1
  87. package/dist/admin/admin/tests/server.js +8 -0
  88. package/dist/admin/admin/tests/server.js.map +1 -1
  89. package/dist/admin/admin/tests/server.mjs +8 -0
  90. package/dist/admin/admin/tests/server.mjs.map +1 -1
  91. package/dist/admin/admin/tests/utils.js +25 -21
  92. package/dist/admin/admin/tests/utils.js.map +1 -1
  93. package/dist/admin/admin/tests/utils.mjs +25 -21
  94. package/dist/admin/admin/tests/utils.mjs.map +1 -1
  95. package/dist/admin/src/components/UnstableGuidedTour/Context.d.ts +12 -3
  96. package/dist/admin/src/components/UnstableGuidedTour/Overview.d.ts +1 -0
  97. package/dist/admin/src/components/UnstableGuidedTour/Step.d.ts +3 -1
  98. package/dist/admin/src/components/UnstableGuidedTour/Tours.d.ts +40 -9
  99. package/dist/admin/src/components/Widgets.d.ts +2 -0
  100. package/dist/admin/src/core/apis/Widgets.d.ts +1 -1
  101. package/dist/admin/src/features/Auth.d.ts +1 -1
  102. package/dist/admin/src/pages/Settings/components/Tokens/TokenBox.d.ts +1 -0
  103. package/dist/admin/src/utils/users.d.ts +5 -1
  104. package/dist/server/server/src/services/guided-tour.js +20 -2
  105. package/dist/server/server/src/services/guided-tour.js.map +1 -1
  106. package/dist/server/server/src/services/guided-tour.mjs +20 -2
  107. package/dist/server/server/src/services/guided-tour.mjs.map +1 -1
  108. package/dist/server/server/src/strategies/api-token.js +15 -4
  109. package/dist/server/server/src/strategies/api-token.js.map +1 -1
  110. package/dist/server/server/src/strategies/api-token.mjs +15 -4
  111. package/dist/server/server/src/strategies/api-token.mjs.map +1 -1
  112. package/dist/server/src/services/guided-tour.d.ts.map +1 -1
  113. package/dist/server/src/strategies/api-token.d.ts.map +1 -1
  114. package/package.json +9 -9
@@ -2,26 +2,57 @@ import * as React from 'react';
2
2
  import { type State, type Action } from './Context';
3
3
  import { Step } from './Step';
4
4
  declare const tours: {
5
- readonly TEST: {
5
+ readonly contentTypeBuilder: {
6
6
  Introduction: React.ComponentType<{
7
7
  children: React.ReactNode;
8
8
  }>;
9
- Done: React.ComponentType<{
9
+ CollectionTypes: React.ComponentType<{
10
+ children: React.ReactNode;
11
+ }>;
12
+ SingleTypes: React.ComponentType<{
13
+ children: React.ReactNode;
14
+ }>;
15
+ Components: React.ComponentType<{
16
+ children: React.ReactNode;
17
+ }>;
18
+ Finish: React.ComponentType<{
19
+ children: React.ReactNode;
20
+ }>;
21
+ };
22
+ readonly contentManager: {
23
+ Introduction: React.ComponentType<{
24
+ children: React.ReactNode;
25
+ }>;
26
+ Finish: React.ComponentType<{
27
+ children: React.ReactNode;
28
+ }>;
29
+ Fields: React.ComponentType<{
30
+ children: React.ReactNode;
31
+ }>;
32
+ Publish: React.ComponentType<{
33
+ children: React.ReactNode;
34
+ }>;
35
+ };
36
+ readonly apiTokens: {
37
+ Introduction: React.ComponentType<{
38
+ children: React.ReactNode;
39
+ }>;
40
+ Finish: React.ComponentType<{
41
+ children: React.ReactNode;
42
+ }>;
43
+ CreateAnAPIToken: React.ComponentType<{
44
+ children: React.ReactNode;
45
+ }>;
46
+ CopyAPIToken: React.ComponentType<{
10
47
  children: React.ReactNode;
11
48
  }>;
12
49
  };
50
+ readonly strapiCloud: {};
13
51
  };
14
52
  type Tours = typeof tours;
15
53
  type Content = (Step: Step, { state, dispatch, }: {
16
54
  state: State;
17
55
  dispatch: React.Dispatch<Action>;
18
56
  }) => React.ReactNode;
19
- export declare const GuidedTourOverlay: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<Omit<import("@strapi/design-system").TransientBoxProps & {
20
- children?: React.ReactNode;
21
- } & import("@strapi/design-system/dist/types").AsProp<React.ElementType<any, keyof React.JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
22
- ref?: any;
23
- }, "ref"> & {
24
- ref?: any;
25
- }, never>> & Omit<import("@strapi/design-system").BoxComponent<"div">, keyof React.Component<any, {}, any>>;
26
57
  export type { Content, Tours };
27
58
  export { tours };
@@ -0,0 +1,2 @@
1
+ declare const ProfileWidget: () => import("react/jsx-runtime").JSX.Element;
2
+ export { ProfileWidget };
@@ -14,7 +14,7 @@ type WidgetArgs = {
14
14
  component: () => Promise<React.ComponentType>;
15
15
  pluginId?: string;
16
16
  id: string;
17
- permissions?: Permission[];
17
+ permissions?: Array<Pick<Permission, 'action'> & Partial<Omit<Permission, 'action'>>>;
18
18
  };
19
19
  type Widget = Omit<WidgetArgs, 'id' | 'pluginId'> & {
20
20
  uid: WidgetUID;
@@ -19,7 +19,7 @@ interface AuthContextValue {
19
19
  * permission object form the API is returned. Therefore, if the list is
20
20
  * empty, the user does not have any of those permissions.
21
21
  */
22
- checkUserHasPermissions: (permissions?: Permission[], passedPermissions?: Permission[], rawQueryContext?: string) => Promise<Permission[]>;
22
+ checkUserHasPermissions: (permissions?: Array<Pick<Permission, 'action'> & Partial<Omit<Permission, 'action'>>>, passedPermissions?: Permission[], rawQueryContext?: string) => Promise<Permission[]>;
23
23
  isLoading: boolean;
24
24
  permissions: Permission[];
25
25
  refetchPermissions: () => Promise<void>;
@@ -2,5 +2,6 @@ interface TokenBoxProps {
2
2
  token?: string;
3
3
  tokenType: 'transfer-token' | 'api-token';
4
4
  }
5
+ export declare const UnstableApiTokenBox: ({ token, tokenType }: TokenBoxProps) => import("react/jsx-runtime").JSX.Element;
5
6
  export declare const TokenBox: ({ token, tokenType }: TokenBoxProps) => import("react/jsx-runtime").JSX.Element;
6
7
  export {};
@@ -3,5 +3,9 @@ import type { User } from '../features/Auth';
3
3
  * Retrieves the display name of an admin panel user
4
4
  */
5
5
  declare const getDisplayName: ({ firstname, lastname, username, email }?: Partial<User>) => string;
6
+ /**
7
+ * Retrieves the initials of the user (based on their firstname / lastname or their display name)
8
+ */
9
+ declare const getInitials: (user?: Partial<User>) => string;
6
10
  declare const hashAdminUserEmail: (payload?: User) => Promise<string | null>;
7
- export { getDisplayName, hashAdminUserEmail };
11
+ export { getDisplayName, getInitials, hashAdminUserEmail };
@@ -2,11 +2,29 @@
2
2
 
3
3
  var constants = require('./constants.js');
4
4
 
5
+ const DEFAULT_ATTIBUTES = [
6
+ 'createdAt',
7
+ 'updatedAt',
8
+ 'publishedAt',
9
+ 'createdBy',
10
+ 'updatedBy',
11
+ 'locale',
12
+ 'localizations'
13
+ ];
5
14
  const createGuidedTourService = ({ strapi })=>{
6
15
  const getCompletedActions = async ()=>{
7
- // Check if any content-type schemas have been create on the api:: namespace
16
+ // Check if any content-type schemas have been created on the api:: namespace
8
17
  const contentTypeSchemaNames = Object.keys(strapi.contentTypes).filter((contentTypeUid)=>contentTypeUid.startsWith('api::'));
9
- const didCreateContentTypeSchema = contentTypeSchemaNames.length > 0;
18
+ const contentTypeSchemaAttributes = contentTypeSchemaNames.map((uid)=>{
19
+ const attributes = Object.keys(strapi.contentType(uid).attributes);
20
+ return attributes.filter((attribute)=>!DEFAULT_ATTIBUTES.includes(attribute));
21
+ });
22
+ const didCreateContentTypeSchema = (()=>{
23
+ if (contentTypeSchemaNames.length === 0) {
24
+ return false;
25
+ }
26
+ return contentTypeSchemaAttributes.some((attributes)=>attributes.length > 0);
27
+ })();
10
28
  // Check if any content has been created for content-types on the api:: namespace
11
29
  const hasContent = await (async ()=>{
12
30
  for (const name of contentTypeSchemaNames){
@@ -1 +1 @@
1
- {"version":3,"file":"guided-tour.js","sources":["../../../../../server/src/services/guided-tour.ts"],"sourcesContent":["import { Core, Internal } from '@strapi/types';\nimport constants from './constants';\n\nexport type GuidedTourRequiredActions = {\n didCreateContentTypeSchema: boolean;\n didCreateContent: boolean;\n didCreateApiToken: boolean;\n};\nexport type GuidedTourCompletedActions = keyof GuidedTourRequiredActions;\n\nexport const createGuidedTourService = ({ strapi }: { strapi: Core.Strapi }) => {\n const getCompletedActions = async () => {\n // Check if any content-type schemas have been create on the api:: namespace\n const contentTypeSchemaNames = Object.keys(strapi.contentTypes).filter((contentTypeUid) =>\n contentTypeUid.startsWith('api::')\n );\n const didCreateContentTypeSchema = contentTypeSchemaNames.length > 0;\n\n // Check if any content has been created for content-types on the api:: namespace\n const hasContent = await (async () => {\n for (const name of contentTypeSchemaNames) {\n const count = await strapi.documents(name as Internal.UID.ContentType).count({});\n\n if (count > 0) return true;\n }\n\n return false;\n })();\n const didCreateContent = didCreateContentTypeSchema && hasContent;\n\n // Check if any api tokens have been created besides the default ones\n const createdApiTokens = await strapi\n .documents('admin::api-token')\n .findMany({ fields: ['name', 'description'] });\n const didCreateApiToken = createdApiTokens.some((doc) =>\n constants.DEFAULT_API_TOKENS.every(\n (token) => token.name !== doc.name && token.description !== doc.description\n )\n );\n\n // Compute an array of action names that have been completed\n const requiredActions = {\n didCreateContentTypeSchema,\n didCreateContent,\n didCreateApiToken,\n };\n const requiredActionNames = Object.keys(requiredActions) as Array<GuidedTourCompletedActions>;\n const completedActions = requiredActionNames.filter((key) => requiredActions[key]);\n\n return completedActions;\n };\n\n return {\n getCompletedActions,\n };\n};\n"],"names":["createGuidedTourService","strapi","getCompletedActions","contentTypeSchemaNames","Object","keys","contentTypes","filter","contentTypeUid","startsWith","didCreateContentTypeSchema","length","hasContent","name","count","documents","didCreateContent","createdApiTokens","findMany","fields","didCreateApiToken","some","doc","constants","DEFAULT_API_TOKENS","every","token","description","requiredActions","requiredActionNames","completedActions","key"],"mappings":";;;;AAUaA,MAAAA,uBAAAA,GAA0B,CAAC,EAAEC,MAAM,EAA2B,GAAA;AACzE,IAAA,MAAMC,mBAAsB,GAAA,UAAA;;AAE1B,QAAA,MAAMC,sBAAyBC,GAAAA,MAAAA,CAAOC,IAAI,CAACJ,MAAOK,CAAAA,YAAY,CAAEC,CAAAA,MAAM,CAAC,CAACC,cACtEA,GAAAA,cAAAA,CAAeC,UAAU,CAAC,OAAA,CAAA,CAAA;QAE5B,MAAMC,0BAAAA,GAA6BP,sBAAuBQ,CAAAA,MAAM,GAAG,CAAA;;QAGnE,MAAMC,UAAAA,GAAa,MAAO,CAAA,UAAA;YACxB,KAAK,MAAMC,QAAQV,sBAAwB,CAAA;gBACzC,MAAMW,KAAAA,GAAQ,MAAMb,MAAOc,CAAAA,SAAS,CAACF,IAAkCC,CAAAA,CAAAA,KAAK,CAAC,EAAC,CAAA;gBAE9E,IAAIA,KAAAA,GAAQ,GAAG,OAAO,IAAA;AACxB;YAEA,OAAO,KAAA;SACT,GAAA;AACA,QAAA,MAAME,mBAAmBN,0BAA8BE,IAAAA,UAAAA;;AAGvD,QAAA,MAAMK,mBAAmB,MAAMhB,MAAAA,CAC5Bc,SAAS,CAAC,kBAAA,CAAA,CACVG,QAAQ,CAAC;YAAEC,MAAQ,EAAA;AAAC,gBAAA,MAAA;AAAQ,gBAAA;AAAc;AAAC,SAAA,CAAA;QAC9C,MAAMC,iBAAAA,GAAoBH,iBAAiBI,IAAI,CAAC,CAACC,GAC/CC,GAAAA,SAAAA,CAAUC,kBAAkB,CAACC,KAAK,CAChC,CAACC,KAAUA,GAAAA,KAAAA,CAAMb,IAAI,KAAKS,GAAIT,CAAAA,IAAI,IAAIa,KAAMC,CAAAA,WAAW,KAAKL,GAAAA,CAAIK,WAAW,CAAA,CAAA;;AAK/E,QAAA,MAAMC,eAAkB,GAAA;AACtBlB,YAAAA,0BAAAA;AACAM,YAAAA,gBAAAA;AACAI,YAAAA;AACF,SAAA;QACA,MAAMS,mBAAAA,GAAsBzB,MAAOC,CAAAA,IAAI,CAACuB,eAAAA,CAAAA;QACxC,MAAME,gBAAAA,GAAmBD,oBAAoBtB,MAAM,CAAC,CAACwB,GAAQH,GAAAA,eAAe,CAACG,GAAI,CAAA,CAAA;QAEjF,OAAOD,gBAAAA;AACT,KAAA;IAEA,OAAO;AACL5B,QAAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"guided-tour.js","sources":["../../../../../server/src/services/guided-tour.ts"],"sourcesContent":["import { Core, Internal } from '@strapi/types';\nimport constants from './constants';\n\nexport type GuidedTourRequiredActions = {\n didCreateContentTypeSchema: boolean;\n didCreateContent: boolean;\n didCreateApiToken: boolean;\n};\nexport type GuidedTourCompletedActions = keyof GuidedTourRequiredActions;\n\nconst DEFAULT_ATTIBUTES = [\n 'createdAt',\n 'updatedAt',\n 'publishedAt',\n 'createdBy',\n 'updatedBy',\n 'locale',\n 'localizations',\n];\n\nexport const createGuidedTourService = ({ strapi }: { strapi: Core.Strapi }) => {\n const getCompletedActions = async () => {\n // Check if any content-type schemas have been created on the api:: namespace\n const contentTypeSchemaNames = Object.keys(strapi.contentTypes).filter((contentTypeUid) =>\n contentTypeUid.startsWith('api::')\n );\n const contentTypeSchemaAttributes = contentTypeSchemaNames.map((uid) => {\n const attributes = Object.keys(\n strapi.contentType(uid as Internal.UID.ContentType).attributes\n );\n return attributes.filter((attribute) => !DEFAULT_ATTIBUTES.includes(attribute));\n });\n const didCreateContentTypeSchema = (() => {\n if (contentTypeSchemaNames.length === 0) {\n return false;\n }\n return contentTypeSchemaAttributes.some((attributes) => attributes.length > 0);\n })();\n\n // Check if any content has been created for content-types on the api:: namespace\n const hasContent = await (async () => {\n for (const name of contentTypeSchemaNames) {\n const count = await strapi.documents(name as Internal.UID.ContentType).count({});\n\n if (count > 0) return true;\n }\n\n return false;\n })();\n const didCreateContent = didCreateContentTypeSchema && hasContent;\n\n // Check if any api tokens have been created besides the default ones\n const createdApiTokens = await strapi\n .documents('admin::api-token')\n .findMany({ fields: ['name', 'description'] });\n const didCreateApiToken = createdApiTokens.some((doc) =>\n constants.DEFAULT_API_TOKENS.every(\n (token) => token.name !== doc.name && token.description !== doc.description\n )\n );\n\n // Compute an array of action names that have been completed\n const requiredActions = {\n didCreateContentTypeSchema,\n didCreateContent,\n didCreateApiToken,\n };\n const requiredActionNames = Object.keys(requiredActions) as Array<GuidedTourCompletedActions>;\n const completedActions = requiredActionNames.filter((key) => requiredActions[key]);\n\n return completedActions;\n };\n\n return {\n getCompletedActions,\n };\n};\n"],"names":["DEFAULT_ATTIBUTES","createGuidedTourService","strapi","getCompletedActions","contentTypeSchemaNames","Object","keys","contentTypes","filter","contentTypeUid","startsWith","contentTypeSchemaAttributes","map","uid","attributes","contentType","attribute","includes","didCreateContentTypeSchema","length","some","hasContent","name","count","documents","didCreateContent","createdApiTokens","findMany","fields","didCreateApiToken","doc","constants","DEFAULT_API_TOKENS","every","token","description","requiredActions","requiredActionNames","completedActions","key"],"mappings":";;;;AAUA,MAAMA,iBAAoB,GAAA;AACxB,IAAA,WAAA;AACA,IAAA,WAAA;AACA,IAAA,aAAA;AACA,IAAA,WAAA;AACA,IAAA,WAAA;AACA,IAAA,QAAA;AACA,IAAA;AACD,CAAA;AAEYC,MAAAA,uBAAAA,GAA0B,CAAC,EAAEC,MAAM,EAA2B,GAAA;AACzE,IAAA,MAAMC,mBAAsB,GAAA,UAAA;;AAE1B,QAAA,MAAMC,sBAAyBC,GAAAA,MAAAA,CAAOC,IAAI,CAACJ,MAAOK,CAAAA,YAAY,CAAEC,CAAAA,MAAM,CAAC,CAACC,cACtEA,GAAAA,cAAAA,CAAeC,UAAU,CAAC,OAAA,CAAA,CAAA;AAE5B,QAAA,MAAMC,2BAA8BP,GAAAA,sBAAAA,CAAuBQ,GAAG,CAAC,CAACC,GAAAA,GAAAA;YAC9D,MAAMC,UAAAA,GAAaT,OAAOC,IAAI,CAC5BJ,OAAOa,WAAW,CAACF,KAAiCC,UAAU,CAAA;YAEhE,OAAOA,UAAAA,CAAWN,MAAM,CAAC,CAACQ,YAAc,CAAChB,iBAAAA,CAAkBiB,QAAQ,CAACD,SAAAA,CAAAA,CAAAA;AACtE,SAAA,CAAA;QACA,MAAME,0BAAAA,GAA6B,CAAC,IAAA;YAClC,IAAId,sBAAAA,CAAuBe,MAAM,KAAK,CAAG,EAAA;gBACvC,OAAO,KAAA;AACT;AACA,YAAA,OAAOR,4BAA4BS,IAAI,CAAC,CAACN,UAAeA,GAAAA,UAAAA,CAAWK,MAAM,GAAG,CAAA,CAAA;SAC9E,GAAA;;QAGA,MAAME,UAAAA,GAAa,MAAO,CAAA,UAAA;YACxB,KAAK,MAAMC,QAAQlB,sBAAwB,CAAA;gBACzC,MAAMmB,KAAAA,GAAQ,MAAMrB,MAAOsB,CAAAA,SAAS,CAACF,IAAkCC,CAAAA,CAAAA,KAAK,CAAC,EAAC,CAAA;gBAE9E,IAAIA,KAAAA,GAAQ,GAAG,OAAO,IAAA;AACxB;YAEA,OAAO,KAAA;SACT,GAAA;AACA,QAAA,MAAME,mBAAmBP,0BAA8BG,IAAAA,UAAAA;;AAGvD,QAAA,MAAMK,mBAAmB,MAAMxB,MAAAA,CAC5BsB,SAAS,CAAC,kBAAA,CAAA,CACVG,QAAQ,CAAC;YAAEC,MAAQ,EAAA;AAAC,gBAAA,MAAA;AAAQ,gBAAA;AAAc;AAAC,SAAA,CAAA;QAC9C,MAAMC,iBAAAA,GAAoBH,iBAAiBN,IAAI,CAAC,CAACU,GAC/CC,GAAAA,SAAAA,CAAUC,kBAAkB,CAACC,KAAK,CAChC,CAACC,KAAUA,GAAAA,KAAAA,CAAMZ,IAAI,KAAKQ,GAAIR,CAAAA,IAAI,IAAIY,KAAMC,CAAAA,WAAW,KAAKL,GAAAA,CAAIK,WAAW,CAAA,CAAA;;AAK/E,QAAA,MAAMC,eAAkB,GAAA;AACtBlB,YAAAA,0BAAAA;AACAO,YAAAA,gBAAAA;AACAI,YAAAA;AACF,SAAA;QACA,MAAMQ,mBAAAA,GAAsBhC,MAAOC,CAAAA,IAAI,CAAC8B,eAAAA,CAAAA;QACxC,MAAME,gBAAAA,GAAmBD,oBAAoB7B,MAAM,CAAC,CAAC+B,GAAQH,GAAAA,eAAe,CAACG,GAAI,CAAA,CAAA;QAEjF,OAAOD,gBAAAA;AACT,KAAA;IAEA,OAAO;AACLnC,QAAAA;AACF,KAAA;AACF;;;;"}
@@ -1,10 +1,28 @@
1
1
  import constants from './constants.mjs';
2
2
 
3
+ const DEFAULT_ATTIBUTES = [
4
+ 'createdAt',
5
+ 'updatedAt',
6
+ 'publishedAt',
7
+ 'createdBy',
8
+ 'updatedBy',
9
+ 'locale',
10
+ 'localizations'
11
+ ];
3
12
  const createGuidedTourService = ({ strapi })=>{
4
13
  const getCompletedActions = async ()=>{
5
- // Check if any content-type schemas have been create on the api:: namespace
14
+ // Check if any content-type schemas have been created on the api:: namespace
6
15
  const contentTypeSchemaNames = Object.keys(strapi.contentTypes).filter((contentTypeUid)=>contentTypeUid.startsWith('api::'));
7
- const didCreateContentTypeSchema = contentTypeSchemaNames.length > 0;
16
+ const contentTypeSchemaAttributes = contentTypeSchemaNames.map((uid)=>{
17
+ const attributes = Object.keys(strapi.contentType(uid).attributes);
18
+ return attributes.filter((attribute)=>!DEFAULT_ATTIBUTES.includes(attribute));
19
+ });
20
+ const didCreateContentTypeSchema = (()=>{
21
+ if (contentTypeSchemaNames.length === 0) {
22
+ return false;
23
+ }
24
+ return contentTypeSchemaAttributes.some((attributes)=>attributes.length > 0);
25
+ })();
8
26
  // Check if any content has been created for content-types on the api:: namespace
9
27
  const hasContent = await (async ()=>{
10
28
  for (const name of contentTypeSchemaNames){
@@ -1 +1 @@
1
- {"version":3,"file":"guided-tour.mjs","sources":["../../../../../server/src/services/guided-tour.ts"],"sourcesContent":["import { Core, Internal } from '@strapi/types';\nimport constants from './constants';\n\nexport type GuidedTourRequiredActions = {\n didCreateContentTypeSchema: boolean;\n didCreateContent: boolean;\n didCreateApiToken: boolean;\n};\nexport type GuidedTourCompletedActions = keyof GuidedTourRequiredActions;\n\nexport const createGuidedTourService = ({ strapi }: { strapi: Core.Strapi }) => {\n const getCompletedActions = async () => {\n // Check if any content-type schemas have been create on the api:: namespace\n const contentTypeSchemaNames = Object.keys(strapi.contentTypes).filter((contentTypeUid) =>\n contentTypeUid.startsWith('api::')\n );\n const didCreateContentTypeSchema = contentTypeSchemaNames.length > 0;\n\n // Check if any content has been created for content-types on the api:: namespace\n const hasContent = await (async () => {\n for (const name of contentTypeSchemaNames) {\n const count = await strapi.documents(name as Internal.UID.ContentType).count({});\n\n if (count > 0) return true;\n }\n\n return false;\n })();\n const didCreateContent = didCreateContentTypeSchema && hasContent;\n\n // Check if any api tokens have been created besides the default ones\n const createdApiTokens = await strapi\n .documents('admin::api-token')\n .findMany({ fields: ['name', 'description'] });\n const didCreateApiToken = createdApiTokens.some((doc) =>\n constants.DEFAULT_API_TOKENS.every(\n (token) => token.name !== doc.name && token.description !== doc.description\n )\n );\n\n // Compute an array of action names that have been completed\n const requiredActions = {\n didCreateContentTypeSchema,\n didCreateContent,\n didCreateApiToken,\n };\n const requiredActionNames = Object.keys(requiredActions) as Array<GuidedTourCompletedActions>;\n const completedActions = requiredActionNames.filter((key) => requiredActions[key]);\n\n return completedActions;\n };\n\n return {\n getCompletedActions,\n };\n};\n"],"names":["createGuidedTourService","strapi","getCompletedActions","contentTypeSchemaNames","Object","keys","contentTypes","filter","contentTypeUid","startsWith","didCreateContentTypeSchema","length","hasContent","name","count","documents","didCreateContent","createdApiTokens","findMany","fields","didCreateApiToken","some","doc","constants","DEFAULT_API_TOKENS","every","token","description","requiredActions","requiredActionNames","completedActions","key"],"mappings":";;AAUaA,MAAAA,uBAAAA,GAA0B,CAAC,EAAEC,MAAM,EAA2B,GAAA;AACzE,IAAA,MAAMC,mBAAsB,GAAA,UAAA;;AAE1B,QAAA,MAAMC,sBAAyBC,GAAAA,MAAAA,CAAOC,IAAI,CAACJ,MAAOK,CAAAA,YAAY,CAAEC,CAAAA,MAAM,CAAC,CAACC,cACtEA,GAAAA,cAAAA,CAAeC,UAAU,CAAC,OAAA,CAAA,CAAA;QAE5B,MAAMC,0BAAAA,GAA6BP,sBAAuBQ,CAAAA,MAAM,GAAG,CAAA;;QAGnE,MAAMC,UAAAA,GAAa,MAAO,CAAA,UAAA;YACxB,KAAK,MAAMC,QAAQV,sBAAwB,CAAA;gBACzC,MAAMW,KAAAA,GAAQ,MAAMb,MAAOc,CAAAA,SAAS,CAACF,IAAkCC,CAAAA,CAAAA,KAAK,CAAC,EAAC,CAAA;gBAE9E,IAAIA,KAAAA,GAAQ,GAAG,OAAO,IAAA;AACxB;YAEA,OAAO,KAAA;SACT,GAAA;AACA,QAAA,MAAME,mBAAmBN,0BAA8BE,IAAAA,UAAAA;;AAGvD,QAAA,MAAMK,mBAAmB,MAAMhB,MAAAA,CAC5Bc,SAAS,CAAC,kBAAA,CAAA,CACVG,QAAQ,CAAC;YAAEC,MAAQ,EAAA;AAAC,gBAAA,MAAA;AAAQ,gBAAA;AAAc;AAAC,SAAA,CAAA;QAC9C,MAAMC,iBAAAA,GAAoBH,iBAAiBI,IAAI,CAAC,CAACC,GAC/CC,GAAAA,SAAAA,CAAUC,kBAAkB,CAACC,KAAK,CAChC,CAACC,KAAUA,GAAAA,KAAAA,CAAMb,IAAI,KAAKS,GAAIT,CAAAA,IAAI,IAAIa,KAAMC,CAAAA,WAAW,KAAKL,GAAAA,CAAIK,WAAW,CAAA,CAAA;;AAK/E,QAAA,MAAMC,eAAkB,GAAA;AACtBlB,YAAAA,0BAAAA;AACAM,YAAAA,gBAAAA;AACAI,YAAAA;AACF,SAAA;QACA,MAAMS,mBAAAA,GAAsBzB,MAAOC,CAAAA,IAAI,CAACuB,eAAAA,CAAAA;QACxC,MAAME,gBAAAA,GAAmBD,oBAAoBtB,MAAM,CAAC,CAACwB,GAAQH,GAAAA,eAAe,CAACG,GAAI,CAAA,CAAA;QAEjF,OAAOD,gBAAAA;AACT,KAAA;IAEA,OAAO;AACL5B,QAAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"guided-tour.mjs","sources":["../../../../../server/src/services/guided-tour.ts"],"sourcesContent":["import { Core, Internal } from '@strapi/types';\nimport constants from './constants';\n\nexport type GuidedTourRequiredActions = {\n didCreateContentTypeSchema: boolean;\n didCreateContent: boolean;\n didCreateApiToken: boolean;\n};\nexport type GuidedTourCompletedActions = keyof GuidedTourRequiredActions;\n\nconst DEFAULT_ATTIBUTES = [\n 'createdAt',\n 'updatedAt',\n 'publishedAt',\n 'createdBy',\n 'updatedBy',\n 'locale',\n 'localizations',\n];\n\nexport const createGuidedTourService = ({ strapi }: { strapi: Core.Strapi }) => {\n const getCompletedActions = async () => {\n // Check if any content-type schemas have been created on the api:: namespace\n const contentTypeSchemaNames = Object.keys(strapi.contentTypes).filter((contentTypeUid) =>\n contentTypeUid.startsWith('api::')\n );\n const contentTypeSchemaAttributes = contentTypeSchemaNames.map((uid) => {\n const attributes = Object.keys(\n strapi.contentType(uid as Internal.UID.ContentType).attributes\n );\n return attributes.filter((attribute) => !DEFAULT_ATTIBUTES.includes(attribute));\n });\n const didCreateContentTypeSchema = (() => {\n if (contentTypeSchemaNames.length === 0) {\n return false;\n }\n return contentTypeSchemaAttributes.some((attributes) => attributes.length > 0);\n })();\n\n // Check if any content has been created for content-types on the api:: namespace\n const hasContent = await (async () => {\n for (const name of contentTypeSchemaNames) {\n const count = await strapi.documents(name as Internal.UID.ContentType).count({});\n\n if (count > 0) return true;\n }\n\n return false;\n })();\n const didCreateContent = didCreateContentTypeSchema && hasContent;\n\n // Check if any api tokens have been created besides the default ones\n const createdApiTokens = await strapi\n .documents('admin::api-token')\n .findMany({ fields: ['name', 'description'] });\n const didCreateApiToken = createdApiTokens.some((doc) =>\n constants.DEFAULT_API_TOKENS.every(\n (token) => token.name !== doc.name && token.description !== doc.description\n )\n );\n\n // Compute an array of action names that have been completed\n const requiredActions = {\n didCreateContentTypeSchema,\n didCreateContent,\n didCreateApiToken,\n };\n const requiredActionNames = Object.keys(requiredActions) as Array<GuidedTourCompletedActions>;\n const completedActions = requiredActionNames.filter((key) => requiredActions[key]);\n\n return completedActions;\n };\n\n return {\n getCompletedActions,\n };\n};\n"],"names":["DEFAULT_ATTIBUTES","createGuidedTourService","strapi","getCompletedActions","contentTypeSchemaNames","Object","keys","contentTypes","filter","contentTypeUid","startsWith","contentTypeSchemaAttributes","map","uid","attributes","contentType","attribute","includes","didCreateContentTypeSchema","length","some","hasContent","name","count","documents","didCreateContent","createdApiTokens","findMany","fields","didCreateApiToken","doc","constants","DEFAULT_API_TOKENS","every","token","description","requiredActions","requiredActionNames","completedActions","key"],"mappings":";;AAUA,MAAMA,iBAAoB,GAAA;AACxB,IAAA,WAAA;AACA,IAAA,WAAA;AACA,IAAA,aAAA;AACA,IAAA,WAAA;AACA,IAAA,WAAA;AACA,IAAA,QAAA;AACA,IAAA;AACD,CAAA;AAEYC,MAAAA,uBAAAA,GAA0B,CAAC,EAAEC,MAAM,EAA2B,GAAA;AACzE,IAAA,MAAMC,mBAAsB,GAAA,UAAA;;AAE1B,QAAA,MAAMC,sBAAyBC,GAAAA,MAAAA,CAAOC,IAAI,CAACJ,MAAOK,CAAAA,YAAY,CAAEC,CAAAA,MAAM,CAAC,CAACC,cACtEA,GAAAA,cAAAA,CAAeC,UAAU,CAAC,OAAA,CAAA,CAAA;AAE5B,QAAA,MAAMC,2BAA8BP,GAAAA,sBAAAA,CAAuBQ,GAAG,CAAC,CAACC,GAAAA,GAAAA;YAC9D,MAAMC,UAAAA,GAAaT,OAAOC,IAAI,CAC5BJ,OAAOa,WAAW,CAACF,KAAiCC,UAAU,CAAA;YAEhE,OAAOA,UAAAA,CAAWN,MAAM,CAAC,CAACQ,YAAc,CAAChB,iBAAAA,CAAkBiB,QAAQ,CAACD,SAAAA,CAAAA,CAAAA;AACtE,SAAA,CAAA;QACA,MAAME,0BAAAA,GAA6B,CAAC,IAAA;YAClC,IAAId,sBAAAA,CAAuBe,MAAM,KAAK,CAAG,EAAA;gBACvC,OAAO,KAAA;AACT;AACA,YAAA,OAAOR,4BAA4BS,IAAI,CAAC,CAACN,UAAeA,GAAAA,UAAAA,CAAWK,MAAM,GAAG,CAAA,CAAA;SAC9E,GAAA;;QAGA,MAAME,UAAAA,GAAa,MAAO,CAAA,UAAA;YACxB,KAAK,MAAMC,QAAQlB,sBAAwB,CAAA;gBACzC,MAAMmB,KAAAA,GAAQ,MAAMrB,MAAOsB,CAAAA,SAAS,CAACF,IAAkCC,CAAAA,CAAAA,KAAK,CAAC,EAAC,CAAA;gBAE9E,IAAIA,KAAAA,GAAQ,GAAG,OAAO,IAAA;AACxB;YAEA,OAAO,KAAA;SACT,GAAA;AACA,QAAA,MAAME,mBAAmBP,0BAA8BG,IAAAA,UAAAA;;AAGvD,QAAA,MAAMK,mBAAmB,MAAMxB,MAAAA,CAC5BsB,SAAS,CAAC,kBAAA,CAAA,CACVG,QAAQ,CAAC;YAAEC,MAAQ,EAAA;AAAC,gBAAA,MAAA;AAAQ,gBAAA;AAAc;AAAC,SAAA,CAAA;QAC9C,MAAMC,iBAAAA,GAAoBH,iBAAiBN,IAAI,CAAC,CAACU,GAC/CC,GAAAA,SAAAA,CAAUC,kBAAkB,CAACC,KAAK,CAChC,CAACC,KAAUA,GAAAA,KAAAA,CAAMZ,IAAI,KAAKQ,GAAIR,CAAAA,IAAI,IAAIY,KAAMC,CAAAA,WAAW,KAAKL,GAAAA,CAAIK,WAAW,CAAA,CAAA;;AAK/E,QAAA,MAAMC,eAAkB,GAAA;AACtBlB,YAAAA,0BAAAA;AACAO,YAAAA,gBAAAA;AACAI,YAAAA;AACF,SAAA;QACA,MAAMQ,mBAAAA,GAAsBhC,MAAOC,CAAAA,IAAI,CAAC8B,eAAAA,CAAAA;QACxC,MAAME,gBAAAA,GAAmBD,oBAAoB7B,MAAM,CAAC,CAAC+B,GAAQH,GAAAA,eAAe,CAACG,GAAI,CAAA,CAAA;QAEjF,OAAOD,gBAAAA;AACT,KAAA;IAEA,OAAO;AACLnC,QAAAA;AACF,KAAA;AACF;;;;"}
@@ -51,10 +51,21 @@ const extractToken = (ctx)=>{
51
51
  };
52
52
  }
53
53
  }
54
- // update lastUsedAt if the token has not been used in the last hour
55
- // @ts-expect-error - FIXME: verify lastUsedAt is defined
56
- const hoursSinceLastUsed = dateFns.differenceInHours(currentDate, dateFns.parseISO(apiToken.lastUsedAt));
57
- if (hoursSinceLastUsed >= 1) {
54
+ if (!fp.isNil(apiToken.lastUsedAt)) {
55
+ // update lastUsedAt if the token has not been used in the last hour
56
+ const hoursSinceLastUsed = dateFns.differenceInHours(currentDate, dateFns.parseISO(apiToken.lastUsedAt));
57
+ if (hoursSinceLastUsed >= 1) {
58
+ await strapi.db.query('admin::api-token').update({
59
+ where: {
60
+ id: apiToken.id
61
+ },
62
+ data: {
63
+ lastUsedAt: currentDate
64
+ }
65
+ });
66
+ }
67
+ } else {
68
+ // If lastUsedAt is not set, initialize it to the current date
58
69
  await strapi.db.query('admin::api-token').update({
59
70
  where: {
60
71
  id: apiToken.id
@@ -1 +1 @@
1
- {"version":3,"file":"api-token.js","sources":["../../../../../server/src/strategies/api-token.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport { castArray, isNil } from 'lodash/fp';\nimport { differenceInHours, parseISO } from 'date-fns';\nimport { errors } from '@strapi/utils';\nimport constants from '../services/constants';\nimport { getService } from '../utils';\nimport '@strapi/types';\n\nconst { UnauthorizedError, ForbiddenError } = errors;\n\nconst isReadScope = (scope: any) => scope.endsWith('find') || scope.endsWith('findOne');\n\nconst extractToken = (ctx: Context) => {\n if (ctx.request && ctx.request.header && ctx.request.header.authorization) {\n const parts = ctx.request.header.authorization.split(/\\s+/);\n\n if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {\n return null;\n }\n\n return parts[1];\n }\n\n return null;\n};\n\n/**\n * Authenticate the validity of the token\n */\nexport const authenticate = async (ctx: Context) => {\n const apiTokenService = getService('api-token');\n const token = extractToken(ctx);\n\n if (!token) {\n return { authenticated: false };\n }\n\n const apiToken = await apiTokenService.getBy({\n accessKey: apiTokenService.hash(token),\n });\n\n // token not found\n if (!apiToken) {\n return { authenticated: false };\n }\n\n const currentDate = new Date();\n\n if (!isNil(apiToken.expiresAt)) {\n const expirationDate = new Date(apiToken.expiresAt);\n // token has expired\n if (expirationDate < currentDate) {\n return { authenticated: false, error: new UnauthorizedError('Token expired') };\n }\n }\n\n // update lastUsedAt if the token has not been used in the last hour\n // @ts-expect-error - FIXME: verify lastUsedAt is defined\n const hoursSinceLastUsed = differenceInHours(currentDate, parseISO(apiToken.lastUsedAt));\n if (hoursSinceLastUsed >= 1) {\n await strapi.db.query('admin::api-token').update({\n where: { id: apiToken.id },\n data: { lastUsedAt: currentDate },\n });\n }\n\n if (apiToken.type === constants.API_TOKEN_TYPE.CUSTOM) {\n const ability = await strapi.contentAPI.permissions.engine.generateAbility(\n apiToken.permissions.map((action: any) => ({ action }))\n );\n\n return { authenticated: true, ability, credentials: apiToken };\n }\n\n return { authenticated: true, credentials: apiToken };\n};\n\n/**\n * Verify the token has the required abilities for the requested scope\n *\n * @type {import('.').VerifyFunction}\n */\nexport const verify = (auth: any, config: any) => {\n const { credentials: apiToken, ability } = auth;\n\n if (!apiToken) {\n throw new UnauthorizedError('Token not found');\n }\n\n const currentDate = new Date();\n\n if (!isNil(apiToken.expiresAt)) {\n const expirationDate = new Date(apiToken.expiresAt);\n // token has expired\n if (expirationDate < currentDate) {\n throw new UnauthorizedError('Token expired');\n }\n }\n\n // Full access\n if (apiToken.type === constants.API_TOKEN_TYPE.FULL_ACCESS) {\n return;\n }\n\n // Read only\n if (apiToken.type === constants.API_TOKEN_TYPE.READ_ONLY) {\n /**\n * If you don't have `full-access` you can only access `find` and `findOne`\n * scopes. If the route has no scope, then you can't get access to it.\n */\n const scopes = castArray(config.scope);\n\n if (config.scope && scopes.every(isReadScope)) {\n return;\n }\n }\n\n // Custom\n else if (apiToken.type === constants.API_TOKEN_TYPE.CUSTOM) {\n if (!ability) {\n throw new ForbiddenError();\n }\n\n const scopes = castArray(config.scope);\n\n const isAllowed = scopes.every((scope) => ability.can(scope));\n\n if (isAllowed) {\n return;\n }\n }\n\n throw new ForbiddenError();\n};\n\nexport const name = 'api-token';\n\nexport default {\n name: 'api-token',\n authenticate,\n verify,\n};\n"],"names":["UnauthorizedError","ForbiddenError","errors","isReadScope","scope","endsWith","extractToken","ctx","request","header","authorization","parts","split","toLowerCase","length","authenticate","apiTokenService","getService","token","authenticated","apiToken","getBy","accessKey","hash","currentDate","Date","isNil","expiresAt","expirationDate","error","hoursSinceLastUsed","differenceInHours","parseISO","lastUsedAt","strapi","db","query","update","where","id","data","type","constants","API_TOKEN_TYPE","CUSTOM","ability","contentAPI","permissions","engine","generateAbility","map","action","credentials","verify","auth","config","FULL_ACCESS","READ_ONLY","scopes","castArray","every","isAllowed","can","name"],"mappings":"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"}
1
+ {"version":3,"file":"api-token.js","sources":["../../../../../server/src/strategies/api-token.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport { castArray, isNil } from 'lodash/fp';\nimport { differenceInHours, parseISO } from 'date-fns';\nimport { errors } from '@strapi/utils';\nimport constants from '../services/constants';\nimport { getService } from '../utils';\nimport '@strapi/types';\n\nconst { UnauthorizedError, ForbiddenError } = errors;\n\nconst isReadScope = (scope: any) => scope.endsWith('find') || scope.endsWith('findOne');\n\nconst extractToken = (ctx: Context) => {\n if (ctx.request && ctx.request.header && ctx.request.header.authorization) {\n const parts = ctx.request.header.authorization.split(/\\s+/);\n\n if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {\n return null;\n }\n\n return parts[1];\n }\n\n return null;\n};\n\n/**\n * Authenticate the validity of the token\n */\nexport const authenticate = async (ctx: Context) => {\n const apiTokenService = getService('api-token');\n const token = extractToken(ctx);\n\n if (!token) {\n return { authenticated: false };\n }\n\n const apiToken = await apiTokenService.getBy({\n accessKey: apiTokenService.hash(token),\n });\n\n // token not found\n if (!apiToken) {\n return { authenticated: false };\n }\n\n const currentDate = new Date();\n\n if (!isNil(apiToken.expiresAt)) {\n const expirationDate = new Date(apiToken.expiresAt);\n // token has expired\n if (expirationDate < currentDate) {\n return { authenticated: false, error: new UnauthorizedError('Token expired') };\n }\n }\n\n if (!isNil(apiToken.lastUsedAt)) {\n // update lastUsedAt if the token has not been used in the last hour\n const hoursSinceLastUsed = differenceInHours(currentDate, parseISO(apiToken.lastUsedAt));\n if (hoursSinceLastUsed >= 1) {\n await strapi.db.query('admin::api-token').update({\n where: { id: apiToken.id },\n data: { lastUsedAt: currentDate },\n });\n }\n } else {\n // If lastUsedAt is not set, initialize it to the current date\n await strapi.db.query('admin::api-token').update({\n where: { id: apiToken.id },\n data: { lastUsedAt: currentDate },\n });\n }\n\n if (apiToken.type === constants.API_TOKEN_TYPE.CUSTOM) {\n const ability = await strapi.contentAPI.permissions.engine.generateAbility(\n apiToken.permissions.map((action: any) => ({ action }))\n );\n\n return { authenticated: true, ability, credentials: apiToken };\n }\n\n return { authenticated: true, credentials: apiToken };\n};\n\n/**\n * Verify the token has the required abilities for the requested scope\n *\n * @type {import('.').VerifyFunction}\n */\nexport const verify = (auth: any, config: any) => {\n const { credentials: apiToken, ability } = auth;\n\n if (!apiToken) {\n throw new UnauthorizedError('Token not found');\n }\n\n const currentDate = new Date();\n\n if (!isNil(apiToken.expiresAt)) {\n const expirationDate = new Date(apiToken.expiresAt);\n // token has expired\n if (expirationDate < currentDate) {\n throw new UnauthorizedError('Token expired');\n }\n }\n\n // Full access\n if (apiToken.type === constants.API_TOKEN_TYPE.FULL_ACCESS) {\n return;\n }\n\n // Read only\n if (apiToken.type === constants.API_TOKEN_TYPE.READ_ONLY) {\n /**\n * If you don't have `full-access` you can only access `find` and `findOne`\n * scopes. If the route has no scope, then you can't get access to it.\n */\n const scopes = castArray(config.scope);\n\n if (config.scope && scopes.every(isReadScope)) {\n return;\n }\n }\n\n // Custom\n else if (apiToken.type === constants.API_TOKEN_TYPE.CUSTOM) {\n if (!ability) {\n throw new ForbiddenError();\n }\n\n const scopes = castArray(config.scope);\n\n const isAllowed = scopes.every((scope) => ability.can(scope));\n\n if (isAllowed) {\n return;\n }\n }\n\n throw new ForbiddenError();\n};\n\nexport const name = 'api-token';\n\nexport default {\n name: 'api-token',\n authenticate,\n verify,\n};\n"],"names":["UnauthorizedError","ForbiddenError","errors","isReadScope","scope","endsWith","extractToken","ctx","request","header","authorization","parts","split","toLowerCase","length","authenticate","apiTokenService","getService","token","authenticated","apiToken","getBy","accessKey","hash","currentDate","Date","isNil","expiresAt","expirationDate","error","lastUsedAt","hoursSinceLastUsed","differenceInHours","parseISO","strapi","db","query","update","where","id","data","type","constants","API_TOKEN_TYPE","CUSTOM","ability","contentAPI","permissions","engine","generateAbility","map","action","credentials","verify","auth","config","FULL_ACCESS","READ_ONLY","scopes","castArray","every","isAllowed","can","name"],"mappings":"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"}
@@ -47,10 +47,21 @@ const extractToken = (ctx)=>{
47
47
  };
48
48
  }
49
49
  }
50
- // update lastUsedAt if the token has not been used in the last hour
51
- // @ts-expect-error - FIXME: verify lastUsedAt is defined
52
- const hoursSinceLastUsed = differenceInHours(currentDate, parseISO(apiToken.lastUsedAt));
53
- if (hoursSinceLastUsed >= 1) {
50
+ if (!isNil(apiToken.lastUsedAt)) {
51
+ // update lastUsedAt if the token has not been used in the last hour
52
+ const hoursSinceLastUsed = differenceInHours(currentDate, parseISO(apiToken.lastUsedAt));
53
+ if (hoursSinceLastUsed >= 1) {
54
+ await strapi.db.query('admin::api-token').update({
55
+ where: {
56
+ id: apiToken.id
57
+ },
58
+ data: {
59
+ lastUsedAt: currentDate
60
+ }
61
+ });
62
+ }
63
+ } else {
64
+ // If lastUsedAt is not set, initialize it to the current date
54
65
  await strapi.db.query('admin::api-token').update({
55
66
  where: {
56
67
  id: apiToken.id
@@ -1 +1 @@
1
- {"version":3,"file":"api-token.mjs","sources":["../../../../../server/src/strategies/api-token.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport { castArray, isNil } from 'lodash/fp';\nimport { differenceInHours, parseISO } from 'date-fns';\nimport { errors } from '@strapi/utils';\nimport constants from '../services/constants';\nimport { getService } from '../utils';\nimport '@strapi/types';\n\nconst { UnauthorizedError, ForbiddenError } = errors;\n\nconst isReadScope = (scope: any) => scope.endsWith('find') || scope.endsWith('findOne');\n\nconst extractToken = (ctx: Context) => {\n if (ctx.request && ctx.request.header && ctx.request.header.authorization) {\n const parts = ctx.request.header.authorization.split(/\\s+/);\n\n if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {\n return null;\n }\n\n return parts[1];\n }\n\n return null;\n};\n\n/**\n * Authenticate the validity of the token\n */\nexport const authenticate = async (ctx: Context) => {\n const apiTokenService = getService('api-token');\n const token = extractToken(ctx);\n\n if (!token) {\n return { authenticated: false };\n }\n\n const apiToken = await apiTokenService.getBy({\n accessKey: apiTokenService.hash(token),\n });\n\n // token not found\n if (!apiToken) {\n return { authenticated: false };\n }\n\n const currentDate = new Date();\n\n if (!isNil(apiToken.expiresAt)) {\n const expirationDate = new Date(apiToken.expiresAt);\n // token has expired\n if (expirationDate < currentDate) {\n return { authenticated: false, error: new UnauthorizedError('Token expired') };\n }\n }\n\n // update lastUsedAt if the token has not been used in the last hour\n // @ts-expect-error - FIXME: verify lastUsedAt is defined\n const hoursSinceLastUsed = differenceInHours(currentDate, parseISO(apiToken.lastUsedAt));\n if (hoursSinceLastUsed >= 1) {\n await strapi.db.query('admin::api-token').update({\n where: { id: apiToken.id },\n data: { lastUsedAt: currentDate },\n });\n }\n\n if (apiToken.type === constants.API_TOKEN_TYPE.CUSTOM) {\n const ability = await strapi.contentAPI.permissions.engine.generateAbility(\n apiToken.permissions.map((action: any) => ({ action }))\n );\n\n return { authenticated: true, ability, credentials: apiToken };\n }\n\n return { authenticated: true, credentials: apiToken };\n};\n\n/**\n * Verify the token has the required abilities for the requested scope\n *\n * @type {import('.').VerifyFunction}\n */\nexport const verify = (auth: any, config: any) => {\n const { credentials: apiToken, ability } = auth;\n\n if (!apiToken) {\n throw new UnauthorizedError('Token not found');\n }\n\n const currentDate = new Date();\n\n if (!isNil(apiToken.expiresAt)) {\n const expirationDate = new Date(apiToken.expiresAt);\n // token has expired\n if (expirationDate < currentDate) {\n throw new UnauthorizedError('Token expired');\n }\n }\n\n // Full access\n if (apiToken.type === constants.API_TOKEN_TYPE.FULL_ACCESS) {\n return;\n }\n\n // Read only\n if (apiToken.type === constants.API_TOKEN_TYPE.READ_ONLY) {\n /**\n * If you don't have `full-access` you can only access `find` and `findOne`\n * scopes. If the route has no scope, then you can't get access to it.\n */\n const scopes = castArray(config.scope);\n\n if (config.scope && scopes.every(isReadScope)) {\n return;\n }\n }\n\n // Custom\n else if (apiToken.type === constants.API_TOKEN_TYPE.CUSTOM) {\n if (!ability) {\n throw new ForbiddenError();\n }\n\n const scopes = castArray(config.scope);\n\n const isAllowed = scopes.every((scope) => ability.can(scope));\n\n if (isAllowed) {\n return;\n }\n }\n\n throw new ForbiddenError();\n};\n\nexport const name = 'api-token';\n\nexport default {\n name: 'api-token',\n authenticate,\n verify,\n};\n"],"names":["UnauthorizedError","ForbiddenError","errors","isReadScope","scope","endsWith","extractToken","ctx","request","header","authorization","parts","split","toLowerCase","length","authenticate","apiTokenService","getService","token","authenticated","apiToken","getBy","accessKey","hash","currentDate","Date","isNil","expiresAt","expirationDate","error","hoursSinceLastUsed","differenceInHours","parseISO","lastUsedAt","strapi","db","query","update","where","id","data","type","constants","API_TOKEN_TYPE","CUSTOM","ability","contentAPI","permissions","engine","generateAbility","map","action","credentials","verify","auth","config","FULL_ACCESS","READ_ONLY","scopes","castArray","every","isAllowed","can","name"],"mappings":"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"}
1
+ {"version":3,"file":"api-token.mjs","sources":["../../../../../server/src/strategies/api-token.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport { castArray, isNil } from 'lodash/fp';\nimport { differenceInHours, parseISO } from 'date-fns';\nimport { errors } from '@strapi/utils';\nimport constants from '../services/constants';\nimport { getService } from '../utils';\nimport '@strapi/types';\n\nconst { UnauthorizedError, ForbiddenError } = errors;\n\nconst isReadScope = (scope: any) => scope.endsWith('find') || scope.endsWith('findOne');\n\nconst extractToken = (ctx: Context) => {\n if (ctx.request && ctx.request.header && ctx.request.header.authorization) {\n const parts = ctx.request.header.authorization.split(/\\s+/);\n\n if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {\n return null;\n }\n\n return parts[1];\n }\n\n return null;\n};\n\n/**\n * Authenticate the validity of the token\n */\nexport const authenticate = async (ctx: Context) => {\n const apiTokenService = getService('api-token');\n const token = extractToken(ctx);\n\n if (!token) {\n return { authenticated: false };\n }\n\n const apiToken = await apiTokenService.getBy({\n accessKey: apiTokenService.hash(token),\n });\n\n // token not found\n if (!apiToken) {\n return { authenticated: false };\n }\n\n const currentDate = new Date();\n\n if (!isNil(apiToken.expiresAt)) {\n const expirationDate = new Date(apiToken.expiresAt);\n // token has expired\n if (expirationDate < currentDate) {\n return { authenticated: false, error: new UnauthorizedError('Token expired') };\n }\n }\n\n if (!isNil(apiToken.lastUsedAt)) {\n // update lastUsedAt if the token has not been used in the last hour\n const hoursSinceLastUsed = differenceInHours(currentDate, parseISO(apiToken.lastUsedAt));\n if (hoursSinceLastUsed >= 1) {\n await strapi.db.query('admin::api-token').update({\n where: { id: apiToken.id },\n data: { lastUsedAt: currentDate },\n });\n }\n } else {\n // If lastUsedAt is not set, initialize it to the current date\n await strapi.db.query('admin::api-token').update({\n where: { id: apiToken.id },\n data: { lastUsedAt: currentDate },\n });\n }\n\n if (apiToken.type === constants.API_TOKEN_TYPE.CUSTOM) {\n const ability = await strapi.contentAPI.permissions.engine.generateAbility(\n apiToken.permissions.map((action: any) => ({ action }))\n );\n\n return { authenticated: true, ability, credentials: apiToken };\n }\n\n return { authenticated: true, credentials: apiToken };\n};\n\n/**\n * Verify the token has the required abilities for the requested scope\n *\n * @type {import('.').VerifyFunction}\n */\nexport const verify = (auth: any, config: any) => {\n const { credentials: apiToken, ability } = auth;\n\n if (!apiToken) {\n throw new UnauthorizedError('Token not found');\n }\n\n const currentDate = new Date();\n\n if (!isNil(apiToken.expiresAt)) {\n const expirationDate = new Date(apiToken.expiresAt);\n // token has expired\n if (expirationDate < currentDate) {\n throw new UnauthorizedError('Token expired');\n }\n }\n\n // Full access\n if (apiToken.type === constants.API_TOKEN_TYPE.FULL_ACCESS) {\n return;\n }\n\n // Read only\n if (apiToken.type === constants.API_TOKEN_TYPE.READ_ONLY) {\n /**\n * If you don't have `full-access` you can only access `find` and `findOne`\n * scopes. If the route has no scope, then you can't get access to it.\n */\n const scopes = castArray(config.scope);\n\n if (config.scope && scopes.every(isReadScope)) {\n return;\n }\n }\n\n // Custom\n else if (apiToken.type === constants.API_TOKEN_TYPE.CUSTOM) {\n if (!ability) {\n throw new ForbiddenError();\n }\n\n const scopes = castArray(config.scope);\n\n const isAllowed = scopes.every((scope) => ability.can(scope));\n\n if (isAllowed) {\n return;\n }\n }\n\n throw new ForbiddenError();\n};\n\nexport const name = 'api-token';\n\nexport default {\n name: 'api-token',\n authenticate,\n verify,\n};\n"],"names":["UnauthorizedError","ForbiddenError","errors","isReadScope","scope","endsWith","extractToken","ctx","request","header","authorization","parts","split","toLowerCase","length","authenticate","apiTokenService","getService","token","authenticated","apiToken","getBy","accessKey","hash","currentDate","Date","isNil","expiresAt","expirationDate","error","lastUsedAt","hoursSinceLastUsed","differenceInHours","parseISO","strapi","db","query","update","where","id","data","type","constants","API_TOKEN_TYPE","CUSTOM","ability","contentAPI","permissions","engine","generateAbility","map","action","credentials","verify","auth","config","FULL_ACCESS","READ_ONLY","scopes","castArray","every","isAllowed","can","name"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"guided-tour.d.ts","sourceRoot":"","sources":["../../../../server/src/services/guided-tour.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAG/C,MAAM,MAAM,yBAAyB,GAAG;IACtC,0BAA0B,EAAE,OAAO,CAAC;IACpC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAAC;AACF,MAAM,MAAM,0BAA0B,GAAG,MAAM,yBAAyB,CAAC;AAEzE,eAAO,MAAM,uBAAuB,eAAgB;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;;CA6C1E,CAAC"}
1
+ {"version":3,"file":"guided-tour.d.ts","sourceRoot":"","sources":["../../../../server/src/services/guided-tour.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAG/C,MAAM,MAAM,yBAAyB,GAAG;IACtC,0BAA0B,EAAE,OAAO,CAAC;IACpC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAAC;AACF,MAAM,MAAM,0BAA0B,GAAG,MAAM,yBAAyB,CAAC;AAYzE,eAAO,MAAM,uBAAuB,eAAgB;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;;CAwD1E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../../../server/src/strategies/api-token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAGnC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAGvC,OAAO,eAAe,CAAC;AAoBvB;;GAEG;AACH,eAAO,MAAM,YAAY,QAAe,OAAO;;;;;;;;;;;;;;;;;;;;EA8C9C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,MAAM,SAAU,GAAG,UAAU,GAAG,SAmD5C,CAAC;AAEF,eAAO,MAAM,IAAI,cAAc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;AAEhC,wBAIE"}
1
+ {"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../../../server/src/strategies/api-token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAGnC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAGvC,OAAO,eAAe,CAAC;AAoBvB;;GAEG;AACH,eAAO,MAAM,YAAY,QAAe,OAAO;;;;;;;;;;;;;;;;;;;;EAqD9C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,MAAM,SAAU,GAAG,UAAU,GAAG,SAmD5C,CAAC;AAEF,eAAO,MAAM,IAAI,cAAc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;AAEhC,wBAIE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/admin",
3
- "version": "5.17.0",
3
+ "version": "5.18.0",
4
4
  "description": "Strapi Admin",
5
5
  "repository": {
6
6
  "type": "git",
@@ -84,12 +84,12 @@
84
84
  "@radix-ui/react-context": "1.0.1",
85
85
  "@radix-ui/react-toolbar": "1.0.4",
86
86
  "@reduxjs/toolkit": "1.9.7",
87
- "@strapi/design-system": "2.0.0-rc.27",
88
- "@strapi/icons": "2.0.0-rc.27",
89
- "@strapi/permissions": "5.17.0",
90
- "@strapi/types": "5.17.0",
91
- "@strapi/typescript-utils": "5.17.0",
92
- "@strapi/utils": "5.17.0",
87
+ "@strapi/design-system": "2.0.0-rc.28",
88
+ "@strapi/icons": "2.0.0-rc.28",
89
+ "@strapi/permissions": "5.18.0",
90
+ "@strapi/types": "5.18.0",
91
+ "@strapi/typescript-utils": "5.18.0",
92
+ "@strapi/utils": "5.18.0",
93
93
  "@testing-library/dom": "10.1.0",
94
94
  "@testing-library/react": "15.0.7",
95
95
  "@testing-library/user-event": "14.5.2",
@@ -144,8 +144,8 @@
144
144
  "zod": "3.24.2"
145
145
  },
146
146
  "devDependencies": {
147
- "@strapi/admin-test-utils": "5.17.0",
148
- "@strapi/data-transfer": "5.17.0",
147
+ "@strapi/admin-test-utils": "5.18.0",
148
+ "@strapi/data-transfer": "5.18.0",
149
149
  "@types/codemirror5": "npm:@types/codemirror@^5.60.15",
150
150
  "@types/fs-extra": "11.0.4",
151
151
  "@types/invariant": "2.2.36",