@payloadcms/figma 0.0.1-alpha.6 → 0.0.1-alpha.61
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/api/control-plane.d.ts +52 -6
- package/dist/api/control-plane.js +174 -72
- package/dist/api/figma-api.d.ts +22 -1
- package/dist/api/figma-api.js +78 -25
- package/dist/auth/callback-server.js +2 -1
- package/dist/auth/credentials.d.ts +21 -0
- package/dist/auth/credentials.js +21 -0
- package/dist/auth/crypto-utils.d.ts +6 -0
- package/dist/auth/crypto-utils.js +16 -14
- package/dist/auth/jwt-validator.d.ts +2 -1
- package/dist/auth/jwt-validator.js +2 -2
- package/dist/auth/oauth-flow.d.ts +17 -3
- package/dist/auth/oauth-flow.js +63 -16
- package/dist/auth/project-token.js +16 -11
- package/dist/auth/refresh.d.ts +2 -1
- package/dist/auth/refresh.js +25 -12
- package/dist/auth/token-store.d.ts +42 -1
- package/dist/auth/token-store.js +118 -14
- package/dist/auth/types.d.ts +17 -4
- package/dist/cli.js +68 -5
- package/dist/commands/build-lambda-zip.d.ts +5 -0
- package/dist/commands/build-lambda-zip.js +19 -0
- package/dist/commands/debug.d.ts +8 -0
- package/dist/commands/debug.js +176 -0
- package/dist/commands/deploy.d.ts +9 -0
- package/dist/commands/deploy.js +178 -151
- package/dist/commands/env.d.ts +13 -0
- package/dist/commands/env.js +88 -0
- package/dist/commands/init.d.ts +3 -5
- package/dist/commands/init.js +165 -148
- package/dist/commands/list-tokens.d.ts +3 -3
- package/dist/commands/list-tokens.js +22 -7
- package/dist/commands/login.d.ts +8 -1
- package/dist/commands/login.js +33 -15
- package/dist/commands/logout.d.ts +5 -4
- package/dist/commands/logout.js +56 -13
- package/dist/commands/upgrade.d.ts +5 -0
- package/dist/commands/upgrade.js +331 -0
- package/dist/config/oauth.d.ts +4 -14
- package/dist/config/oauth.js +18 -40
- package/dist/constants.d.ts +44 -19
- package/dist/constants.js +73 -20
- package/dist/db-content-api/README.md +98 -0
- package/dist/db-content-api/generated/content-api-types.d.ts +3972 -0
- package/dist/db-content-api/generated/content-api-types.js +7 -0
- package/dist/db-content-api/index.d.ts +21 -0
- package/dist/db-content-api/index.js +914 -0
- package/dist/db-content-api/temp-utilities/slug.d.ts +2 -0
- package/dist/db-content-api/temp-utilities/slug.js +3 -0
- package/dist/db-content-api/temp-utilities/sorting.d.ts +3 -0
- package/dist/db-content-api/temp-utilities/sorting.js +39 -0
- package/dist/db-content-api/temp-utilities/types.d.ts +22 -0
- package/dist/db-content-api/temp-utilities/types.js +15 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts +39 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.js +59 -0
- package/dist/db-content-api/utilities/auth.d.ts +30 -0
- package/dist/db-content-api/utilities/auth.js +81 -0
- package/dist/db-content-api/utilities/data/applyDefaults.d.ts +7 -0
- package/dist/db-content-api/utilities/data/applyDefaults.js +75 -0
- package/dist/db-content-api/utilities/data/castFieldValue.d.ts +11 -0
- package/dist/db-content-api/utilities/data/castFieldValue.js +68 -0
- package/dist/db-content-api/utilities/data/index.d.ts +49 -0
- package/dist/db-content-api/utilities/data/index.js +301 -0
- package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts +12 -0
- package/dist/db-content-api/utilities/data/removeVirtualFields.js +54 -0
- package/dist/db-content-api/utilities/data/stripFields.d.ts +48 -0
- package/dist/db-content-api/utilities/data/stripFields.js +195 -0
- package/dist/db-content-api/utilities/data/transformPublishedLocale.d.ts +23 -0
- package/dist/db-content-api/utilities/data/transformPublishedLocale.js +42 -0
- package/dist/db-content-api/utilities/joins.d.ts +53 -0
- package/dist/db-content-api/utilities/joins.js +139 -0
- package/dist/db-content-api/utilities/locale/index.d.ts +10 -0
- package/dist/db-content-api/utilities/locale/index.js +21 -0
- package/dist/db-content-api/utilities/meta/buildLocalizedPaths.d.ts +11 -0
- package/dist/db-content-api/utilities/meta/buildLocalizedPaths.js +74 -0
- package/dist/db-content-api/utilities/meta/buildMeta.d.ts +42 -0
- package/dist/db-content-api/utilities/meta/buildMeta.js +41 -0
- package/dist/db-content-api/utilities/meta/buildPathTypes.d.ts +17 -0
- package/dist/db-content-api/utilities/meta/buildPathTypes.js +244 -0
- package/dist/db-content-api/utilities/meta/buildUniquePaths.d.ts +13 -0
- package/dist/db-content-api/utilities/meta/buildUniquePaths.js +62 -0
- package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.d.ts +10 -0
- package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.js +102 -0
- package/dist/db-content-api/utilities/where.d.ts +20 -0
- package/dist/db-content-api/utilities/where.js +108 -0
- package/dist/deploy/schedule-extract-plugin.d.ts +11 -0
- package/dist/deploy/schedule-extract-plugin.js +34 -0
- package/dist/endpoints/health.d.ts +3 -0
- package/dist/endpoints/health.js +11 -0
- package/dist/endpoints/schema.d.ts +3 -0
- package/dist/endpoints/schema.js +29 -0
- package/dist/exports/client.d.ts +3 -0
- package/dist/exports/client.js +3 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/oauth/components/FigmaAvatar/index.d.ts +4 -0
- package/dist/oauth/components/FigmaAvatar/index.js +27 -0
- package/dist/oauth/components/FigmaAvatar/index.scss +12 -0
- package/dist/oauth/components/FigmaAvatarCell/index.d.ts +5 -0
- package/dist/oauth/components/FigmaAvatarCell/index.js +25 -0
- package/dist/oauth/components/FigmaAvatarCell/index.scss +5 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.d.ts +9 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.js +37 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.scss +28 -0
- package/dist/oauth/components/LoginButton/index.js +50 -6
- package/dist/oauth/components/LoginButton/index.scss +50 -3
- package/dist/oauth/components/LogoutButton/index.js +5 -4
- package/dist/oauth/defaults.js +67 -10
- package/dist/oauth/endpoints/getLoginEndpoint.js +77 -24
- package/dist/oauth/endpoints/getLogoutEndpoint.js +7 -4
- package/dist/oauth/index.js +40 -13
- package/dist/oauth/strategy/index.d.ts +0 -2
- package/dist/oauth/strategy/index.js +40 -17
- package/dist/oauth/types.d.ts +6 -6
- package/dist/oauth/utilities/isDuplicateKeyError.d.ts +7 -0
- package/dist/oauth/utilities/isDuplicateKeyError.js +14 -0
- package/dist/oauth/utilities/refreshTokens.js +6 -3
- package/dist/plugin/build-config.d.ts +18 -15
- package/dist/plugin/build-config.js +213 -18
- package/dist/storage-content-api/api-types.d.ts +168 -0
- package/dist/storage-content-api/api-types.js +6 -0
- package/dist/storage-content-api/client-uploads/ClientUploadHandler.d.ts +9 -0
- package/dist/storage-content-api/client-uploads/ClientUploadHandler.js +42 -0
- package/dist/storage-content-api/client-uploads/generateSignedURL.d.ts +13 -0
- package/dist/storage-content-api/client-uploads/generateSignedURL.js +39 -0
- package/dist/storage-content-api/client.d.ts +6 -0
- package/dist/storage-content-api/client.js +36 -0
- package/dist/storage-content-api/generateURL.d.ts +7 -0
- package/dist/storage-content-api/generateURL.js +8 -0
- package/dist/storage-content-api/handleDelete.d.ts +8 -0
- package/dist/storage-content-api/handleDelete.js +17 -0
- package/dist/storage-content-api/handleUpload.d.ts +11 -0
- package/dist/storage-content-api/handleUpload.js +144 -0
- package/dist/storage-content-api/index.d.ts +5 -0
- package/dist/storage-content-api/index.js +31 -0
- package/dist/storage-content-api/staticHandler.d.ts +10 -0
- package/dist/storage-content-api/staticHandler.js +56 -0
- package/dist/storage-content-api/types.d.ts +10 -0
- package/dist/storage-content-api/types.js +3 -0
- package/dist/storage-content-api/utilities/getSafeFilename.d.ts +12 -0
- package/dist/storage-content-api/utilities/getSafeFilename.js +61 -0
- package/dist/storage-content-api/utilities/index.d.ts +2 -0
- package/dist/storage-content-api/utilities/index.js +3 -0
- package/dist/templates/.env.example +5 -0
- package/dist/templates/README.md +19 -0
- package/dist/types/config.d.ts +2 -1
- package/dist/types/config.js +0 -2
- package/dist/types.d.ts +8 -1
- package/dist/utils/adapters/nextjs.d.ts +9 -0
- package/dist/utils/adapters/nextjs.js +64 -0
- package/dist/utils/adapters/nitro.d.ts +9 -0
- package/dist/utils/adapters/nitro.js +169 -0
- package/dist/utils/adapters/vite.d.ts +10 -0
- package/dist/utils/adapters/vite.js +33 -0
- package/dist/utils/asset-collection.d.ts +27 -6
- package/dist/utils/asset-collection.js +59 -30
- package/dist/utils/build-detection.d.ts +5 -11
- package/dist/utils/build-detection.js +74 -11
- package/dist/utils/build-lambda-zip.d.ts +14 -0
- package/dist/utils/build-lambda-zip.js +81 -0
- package/dist/utils/cache-bootstrap.d.ts +8 -0
- package/dist/utils/cache-bootstrap.js +18 -0
- package/dist/utils/config.js +1 -1
- package/dist/utils/deploy-adapter.d.ts +40 -0
- package/dist/utils/deploy-adapter.js +58 -0
- package/dist/utils/download-template.js +3 -2
- package/dist/utils/env-management.d.ts +24 -7
- package/dist/utils/env-management.js +119 -64
- package/dist/utils/format-env-suffix.d.ts +12 -0
- package/dist/utils/format-env-suffix.js +13 -0
- package/dist/utils/formatter.js +23 -11
- package/dist/utils/fs-utils.d.ts +6 -0
- package/dist/utils/fs-utils.js +27 -0
- package/dist/utils/handle-upgrade.d.ts +9 -0
- package/dist/utils/handle-upgrade.js +41 -0
- package/dist/utils/lambda-config.d.ts +3 -1
- package/dist/utils/lambda-config.js +75 -78
- package/dist/utils/messages.d.ts +1 -2
- package/dist/utils/messages.js +29 -11
- package/dist/utils/package-manager.d.ts +24 -0
- package/dist/utils/package-manager.js +53 -0
- package/dist/utils/payload-config-ast.d.ts +27 -6
- package/dist/utils/payload-config-ast.js +106 -58
- package/dist/utils/payload-config-finder.d.ts +2 -2
- package/dist/utils/payload-config-finder.js +48 -9
- package/dist/utils/payload-config-modifier.d.ts +1 -1
- package/dist/utils/payload-config-modifier.js +70 -11
- package/dist/utils/payload-package-check.d.ts +12 -1
- package/dist/utils/payload-package-check.js +63 -5
- package/dist/utils/project.d.ts +3 -2
- package/dist/utils/project.js +29 -15
- package/dist/utils/resolve-environment.d.ts +14 -0
- package/dist/utils/resolve-environment.js +31 -0
- package/dist/utils/s3-upload.d.ts +7 -2
- package/dist/utils/s3-upload.js +39 -6
- package/dist/utils/token-display.js +11 -5
- package/dist/utils/typescript-validator.js +4 -6
- package/dist/utils/version-check.d.ts +3 -0
- package/dist/utils/version-check.js +38 -0
- package/package.json +33 -15
- package/dist/api/control-plane.d.ts.map +0 -1
- package/dist/api/control-plane.js.map +0 -1
- package/dist/api/figma-api.d.ts.map +0 -1
- package/dist/api/figma-api.js.map +0 -1
- package/dist/auth/browser.d.ts.map +0 -1
- package/dist/auth/browser.js.map +0 -1
- package/dist/auth/callback-server.d.ts.map +0 -1
- package/dist/auth/callback-server.js.map +0 -1
- package/dist/auth/crypto-utils.d.ts.map +0 -1
- package/dist/auth/crypto-utils.js.map +0 -1
- package/dist/auth/jwt-validator.d.ts.map +0 -1
- package/dist/auth/jwt-validator.js.map +0 -1
- package/dist/auth/oauth-flow.d.ts.map +0 -1
- package/dist/auth/oauth-flow.js.map +0 -1
- package/dist/auth/pkce.d.ts.map +0 -1
- package/dist/auth/pkce.js.map +0 -1
- package/dist/auth/project-token.d.ts.map +0 -1
- package/dist/auth/project-token.js.map +0 -1
- package/dist/auth/refresh.d.ts.map +0 -1
- package/dist/auth/refresh.js.map +0 -1
- package/dist/auth/token-store.d.ts.map +0 -1
- package/dist/auth/token-store.js.map +0 -1
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/deploy.d.ts.map +0 -1
- package/dist/commands/deploy.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/list-tokens.d.ts.map +0 -1
- package/dist/commands/list-tokens.js.map +0 -1
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts.map +0 -1
- package/dist/commands/logout.js.map +0 -1
- package/dist/config/oauth.d.ts.map +0 -1
- package/dist/config/oauth.js.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/exports/client.d.ts.map +0 -1
- package/dist/exports/client.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/oauth/components/LoginButton/index.d.ts.map +0 -1
- package/dist/oauth/components/LoginButton/index.js.map +0 -1
- package/dist/oauth/components/LogoutButton/index.d.ts.map +0 -1
- package/dist/oauth/components/LogoutButton/index.js.map +0 -1
- package/dist/oauth/defaults.d.ts.map +0 -1
- package/dist/oauth/defaults.js.map +0 -1
- package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getLoginEndpoint.js.map +0 -1
- package/dist/oauth/endpoints/getLogoutEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getLogoutEndpoint.js.map +0 -1
- package/dist/oauth/endpoints/getMetaEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getMetaEndpoint.js.map +0 -1
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js.map +0 -1
- package/dist/oauth/exports/client.d.ts.map +0 -1
- package/dist/oauth/exports/client.js.map +0 -1
- package/dist/oauth/hooks/afterLogout.d.ts.map +0 -1
- package/dist/oauth/hooks/afterLogout.js.map +0 -1
- package/dist/oauth/hooks/me.d.ts.map +0 -1
- package/dist/oauth/hooks/me.js.map +0 -1
- package/dist/oauth/hooks/refresh.d.ts.map +0 -1
- package/dist/oauth/hooks/refresh.js.map +0 -1
- package/dist/oauth/index.d.ts.map +0 -1
- package/dist/oauth/index.js.map +0 -1
- package/dist/oauth/strategy/index.d.ts.map +0 -1
- package/dist/oauth/strategy/index.js.map +0 -1
- package/dist/oauth/types.d.ts.map +0 -1
- package/dist/oauth/types.js.map +0 -1
- package/dist/oauth/utilities/clearCookie.d.ts.map +0 -1
- package/dist/oauth/utilities/clearCookie.js.map +0 -1
- package/dist/oauth/utilities/createCookieOptions.d.ts.map +0 -1
- package/dist/oauth/utilities/createCookieOptions.js.map +0 -1
- package/dist/oauth/utilities/createDebugLogger.d.ts.map +0 -1
- package/dist/oauth/utilities/createDebugLogger.js.map +0 -1
- package/dist/oauth/utilities/extractOrigin.d.ts.map +0 -1
- package/dist/oauth/utilities/extractOrigin.js.map +0 -1
- package/dist/oauth/utilities/getAdminCollectionSlug.d.ts.map +0 -1
- package/dist/oauth/utilities/getAdminCollectionSlug.js.map +0 -1
- package/dist/oauth/utilities/getAdminPath.d.ts +0 -8
- package/dist/oauth/utilities/getAdminPath.d.ts.map +0 -1
- package/dist/oauth/utilities/getAdminPath.js +0 -9
- package/dist/oauth/utilities/getAdminPath.js.map +0 -1
- package/dist/oauth/utilities/getAuthorizeURL.d.ts.map +0 -1
- package/dist/oauth/utilities/getAuthorizeURL.js.map +0 -1
- package/dist/oauth/utilities/getCookieExpiration.d.ts.map +0 -1
- package/dist/oauth/utilities/getCookieExpiration.js.map +0 -1
- package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts.map +0 -1
- package/dist/oauth/utilities/getSecondsFromTokenExp.js.map +0 -1
- package/dist/oauth/utilities/getTokenExp.d.ts.map +0 -1
- package/dist/oauth/utilities/getTokenExp.js.map +0 -1
- package/dist/oauth/utilities/getUsernameField.d.ts.map +0 -1
- package/dist/oauth/utilities/getUsernameField.js.map +0 -1
- package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts.map +0 -1
- package/dist/oauth/utilities/hasUserTokenPropsChanged.js.map +0 -1
- package/dist/oauth/utilities/mergeHeaders.d.ts.map +0 -1
- package/dist/oauth/utilities/mergeHeaders.js.map +0 -1
- package/dist/oauth/utilities/refreshTokens.d.ts.map +0 -1
- package/dist/oauth/utilities/refreshTokens.js.map +0 -1
- package/dist/plugin/adapter.d.ts.map +0 -1
- package/dist/plugin/adapter.js.map +0 -1
- package/dist/plugin/build-config.d.ts.map +0 -1
- package/dist/plugin/build-config.js.map +0 -1
- package/dist/types/config.d.ts.map +0 -1
- package/dist/types/config.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/asset-collection.d.ts.map +0 -1
- package/dist/utils/asset-collection.js.map +0 -1
- package/dist/utils/build-detection.d.ts.map +0 -1
- package/dist/utils/build-detection.js.map +0 -1
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/download-template.d.ts.map +0 -1
- package/dist/utils/download-template.js.map +0 -1
- package/dist/utils/env-management.d.ts.map +0 -1
- package/dist/utils/env-management.js.map +0 -1
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/formatter.d.ts.map +0 -1
- package/dist/utils/formatter.js.map +0 -1
- package/dist/utils/git.d.ts.map +0 -1
- package/dist/utils/git.js.map +0 -1
- package/dist/utils/is-debug.d.ts.map +0 -1
- package/dist/utils/is-debug.js.map +0 -1
- package/dist/utils/lambda-config.d.ts.map +0 -1
- package/dist/utils/lambda-config.js.map +0 -1
- package/dist/utils/log.d.ts.map +0 -1
- package/dist/utils/log.js.map +0 -1
- package/dist/utils/messages.d.ts.map +0 -1
- package/dist/utils/messages.js.map +0 -1
- package/dist/utils/package-manager.d.ts.map +0 -1
- package/dist/utils/package-manager.js.map +0 -1
- package/dist/utils/payload-config-ast.d.ts.map +0 -1
- package/dist/utils/payload-config-ast.js.map +0 -1
- package/dist/utils/payload-config-finder.d.ts.map +0 -1
- package/dist/utils/payload-config-finder.js.map +0 -1
- package/dist/utils/payload-config-modifier.d.ts.map +0 -1
- package/dist/utils/payload-config-modifier.js.map +0 -1
- package/dist/utils/payload-package-check.d.ts.map +0 -1
- package/dist/utils/payload-package-check.js.map +0 -1
- package/dist/utils/project.d.ts.map +0 -1
- package/dist/utils/project.js.map +0 -1
- package/dist/utils/s3-upload.d.ts.map +0 -1
- package/dist/utils/s3-upload.js.map +0 -1
- package/dist/utils/token-display.d.ts.map +0 -1
- package/dist/utils/token-display.js.map +0 -1
- package/dist/utils/typescript-validator.d.ts.map +0 -1
- package/dist/utils/typescript-validator.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import jwt from 'jsonwebtoken';
|
|
2
2
|
import { parseCookies } from 'payload';
|
|
3
|
+
import { formatAdminURL } from 'payload/shared';
|
|
3
4
|
import { clearCookie } from '../utilities/clearCookie.js';
|
|
4
5
|
import { createCookieOptions } from '../utilities/createCookieOptions.js';
|
|
5
6
|
import { createDebugLogger } from '../utilities/createDebugLogger.js';
|
|
6
|
-
import { getAdminPath } from '../utilities/getAdminPath.js';
|
|
7
7
|
export const getLogoutEndpoint = ({ collection, endpointSlug, pluginOptions, strategy })=>({
|
|
8
8
|
handler: async (req)=>{
|
|
9
9
|
const debugLogger = createDebugLogger(req.payload, pluginOptions.debug);
|
|
@@ -23,12 +23,15 @@ export const getLogoutEndpoint = ({ collection, endpointSlug, pluginOptions, str
|
|
|
23
23
|
}
|
|
24
24
|
try {
|
|
25
25
|
await strategy.ensureMeta();
|
|
26
|
-
const
|
|
27
|
-
let successfulLogoutRedirectDest =
|
|
26
|
+
const redirectServerlURL = pluginOptions.redirectServerURL || config.serverURL;
|
|
27
|
+
let successfulLogoutRedirectDest = formatAdminURL({
|
|
28
|
+
adminRoute: config.routes?.admin || '/admin',
|
|
29
|
+
serverURL: redirectServerlURL
|
|
30
|
+
});
|
|
28
31
|
if (typeof req.query.redirect === 'string') {
|
|
29
32
|
successfulLogoutRedirectDest = req.query.redirect;
|
|
30
33
|
}
|
|
31
|
-
if (!
|
|
34
|
+
if (!redirectServerlURL && !req.query.redirect) {
|
|
32
35
|
debugLogger.error({
|
|
33
36
|
msg: 'No redirect URL provided',
|
|
34
37
|
path: req.pathname
|
package/dist/oauth/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fieldAffectsData } from 'payload/shared';
|
|
1
2
|
import { defaultVerify } from './defaults.js';
|
|
2
3
|
import { getLoginEndpoint } from './endpoints/getLoginEndpoint.js';
|
|
3
4
|
import { getLogoutEndpoint } from './endpoints/getLogoutEndpoint.js';
|
|
@@ -84,23 +85,46 @@ export const oAuth2Plugin = (pluginOptions)=>(config)=>{
|
|
|
84
85
|
if (collectionOptions.usePayloadJWT) {
|
|
85
86
|
cookieName = `${config.cookiePrefix || 'payload'}-token`;
|
|
86
87
|
}
|
|
87
|
-
const usernameField = getUsernameField({
|
|
88
|
-
collection: existingCollection,
|
|
89
|
-
collectionOptions
|
|
90
|
-
});
|
|
91
88
|
// Check if email field exists, if not add it
|
|
92
89
|
const hasEmailField = existingCollection.fields.some((field)=>'name' in field && field.name === 'email');
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
90
|
+
// Add email field to collection before getting username field
|
|
91
|
+
// This ensures getUsernameField can find the email field if it's configured as the username
|
|
92
|
+
const collectionWithEmail = hasEmailField ? existingCollection : {
|
|
93
|
+
...existingCollection,
|
|
94
|
+
fields: [
|
|
95
|
+
...existingCollection.fields,
|
|
99
96
|
{
|
|
100
97
|
name: 'email',
|
|
101
|
-
type: 'email'
|
|
98
|
+
type: 'email',
|
|
99
|
+
admin: {
|
|
100
|
+
description: 'Managed by Figma',
|
|
101
|
+
readOnly: true
|
|
102
|
+
},
|
|
103
|
+
unique: true
|
|
102
104
|
}
|
|
103
|
-
]
|
|
105
|
+
]
|
|
106
|
+
};
|
|
107
|
+
const usernameField = getUsernameField({
|
|
108
|
+
collection: collectionWithEmail,
|
|
109
|
+
collectionOptions
|
|
110
|
+
});
|
|
111
|
+
// Make username field readOnly (and add description for email fields)
|
|
112
|
+
const readOnlyUsernameField = {
|
|
113
|
+
...usernameField,
|
|
114
|
+
admin: {
|
|
115
|
+
...usernameField.admin || {},
|
|
116
|
+
...usernameField.name === 'email' ? {
|
|
117
|
+
description: 'Managed by Figma'
|
|
118
|
+
} : {},
|
|
119
|
+
readOnly: true
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const isUsernameFieldString = typeof adminCollectionOptions.usernameField === 'string';
|
|
123
|
+
const fields = [
|
|
124
|
+
...collectionWithEmail.fields.map((field)=>fieldAffectsData(field) && field.name === usernameField.name ? readOnlyUsernameField : field),
|
|
125
|
+
...isUsernameFieldString ? [] : [
|
|
126
|
+
readOnlyUsernameField
|
|
127
|
+
]
|
|
104
128
|
];
|
|
105
129
|
if (disabled) {
|
|
106
130
|
return {
|
|
@@ -110,7 +134,6 @@ export const oAuth2Plugin = (pluginOptions)=>(config)=>{
|
|
|
110
134
|
}
|
|
111
135
|
const strategy = new Strategy({
|
|
112
136
|
clientID: collectionOptions.clientID,
|
|
113
|
-
clientSecret: collectionOptions.clientSecret,
|
|
114
137
|
collection: existingCollection,
|
|
115
138
|
collectionOptions,
|
|
116
139
|
cookieName,
|
|
@@ -142,6 +165,10 @@ export const oAuth2Plugin = (pluginOptions)=>(config)=>{
|
|
|
142
165
|
}
|
|
143
166
|
return {
|
|
144
167
|
...existingCollection,
|
|
168
|
+
access: {
|
|
169
|
+
...existingCollection.access || {},
|
|
170
|
+
create: ()=>false
|
|
171
|
+
},
|
|
145
172
|
auth: {
|
|
146
173
|
...typeof existingCollection.auth === 'object' ? existingCollection.auth : {},
|
|
147
174
|
disableLocalStrategy,
|
|
@@ -4,7 +4,6 @@ import * as jose from 'jose';
|
|
|
4
4
|
import type { CollectionOptions, PluginOptions, VerifyFunction } from '../types.js';
|
|
5
5
|
export interface Options {
|
|
6
6
|
clientID: string;
|
|
7
|
-
clientSecret?: string;
|
|
8
7
|
collection: CollectionConfig;
|
|
9
8
|
collectionOptions: CollectionOptions;
|
|
10
9
|
cookieName: string;
|
|
@@ -16,7 +15,6 @@ export interface Options {
|
|
|
16
15
|
}
|
|
17
16
|
export declare class Strategy {
|
|
18
17
|
clientID: string;
|
|
19
|
-
clientSecret?: string;
|
|
20
18
|
collection: CollectionConfig;
|
|
21
19
|
collectionOptions: CollectionOptions;
|
|
22
20
|
cookieName: string;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import * as jose from 'jose';
|
|
2
2
|
import { APIError, parseCookies } from 'payload';
|
|
3
|
-
import { validateProjectToken } from '../../auth/jwt-validator.js';
|
|
4
|
-
import {
|
|
3
|
+
import { JWTValidationError, validateProjectToken } from '../../auth/jwt-validator.js';
|
|
4
|
+
import { getInfraEnvironment } from '../../constants.js';
|
|
5
5
|
import { createDebugLogger } from '../utilities/createDebugLogger.js';
|
|
6
6
|
import { getTokenExp } from '../utilities/getTokenExp.js';
|
|
7
7
|
import { mergeHeaders } from '../utilities/mergeHeaders.js';
|
|
8
8
|
import { refreshTokens } from '../utilities/refreshTokens.js';
|
|
9
9
|
export class Strategy {
|
|
10
10
|
clientID;
|
|
11
|
-
clientSecret;
|
|
12
11
|
collection;
|
|
13
12
|
collectionOptions;
|
|
14
13
|
cookieName;
|
|
@@ -28,7 +27,6 @@ export class Strategy {
|
|
|
28
27
|
this.verify = options.verify;
|
|
29
28
|
this.cookieName = options.cookieName;
|
|
30
29
|
this.clientID = options.clientID;
|
|
31
|
-
this.clientSecret = options.clientSecret;
|
|
32
30
|
this.identityMetadataURL = options.identityMetadata;
|
|
33
31
|
this.name = options.strategyName;
|
|
34
32
|
this.collection = options.collection;
|
|
@@ -63,7 +61,11 @@ export class Strategy {
|
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
63
|
if (!oauthToken) {
|
|
66
|
-
|
|
64
|
+
// Attempt refresh even when canSetHeaders=false (e.g., during RSC navigation).
|
|
65
|
+
// This allows authentication to succeed for the current request even when
|
|
66
|
+
// cookies cannot be updated. The cookie will be refreshed on the next
|
|
67
|
+
// full page load when canSetHeaders=true.
|
|
68
|
+
if (refreshToken) {
|
|
67
69
|
debugLogger.info({
|
|
68
70
|
msg: 'No access token found, but refresh token exists. Attempting to refresh...',
|
|
69
71
|
refreshToken
|
|
@@ -83,11 +85,20 @@ export class Strategy {
|
|
|
83
85
|
msg: 'Token refreshed. Verifying...',
|
|
84
86
|
verifyResult
|
|
85
87
|
});
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
// Only return response headers (to set cookies) when canSetHeaders is true.
|
|
89
|
+
// During RSC navigation, canSetHeaders=false because response streaming
|
|
90
|
+
// has already started and cookies cannot be modified.
|
|
91
|
+
if (canSetHeaders) {
|
|
92
|
+
if (verifyResult.responseHeaders) {
|
|
93
|
+
mergeHeaders(verifyResult.responseHeaders, refreshed.headers);
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
responseHeaders: refreshed.headers,
|
|
97
|
+
user: verifyResult.user
|
|
98
|
+
};
|
|
88
99
|
}
|
|
100
|
+
// Authenticate this request without updating cookies
|
|
89
101
|
return {
|
|
90
|
-
responseHeaders: refreshed.headers,
|
|
91
102
|
user: verifyResult.user
|
|
92
103
|
};
|
|
93
104
|
} else {
|
|
@@ -97,11 +108,10 @@ export class Strategy {
|
|
|
97
108
|
refreshToken
|
|
98
109
|
});
|
|
99
110
|
}
|
|
100
|
-
} else {
|
|
101
|
-
return {
|
|
102
|
-
user: null
|
|
103
|
-
};
|
|
104
111
|
}
|
|
112
|
+
return {
|
|
113
|
+
user: null
|
|
114
|
+
};
|
|
105
115
|
}
|
|
106
116
|
let oauthTokenVerifyResult = null;
|
|
107
117
|
// First, try to verify token
|
|
@@ -136,7 +146,10 @@ export class Strategy {
|
|
|
136
146
|
});
|
|
137
147
|
}
|
|
138
148
|
}
|
|
139
|
-
|
|
149
|
+
// Handle expired access token with valid refresh token.
|
|
150
|
+
// Same pattern as above: refresh regardless of canSetHeaders to support RSC navigation,
|
|
151
|
+
// but only update cookies when canSetHeaders=true.
|
|
152
|
+
if (oauthTokenVerifyResult instanceof JWTValidationError && oauthTokenVerifyResult.code === 'EXPIRED' && refreshToken && !this.collectionOptions.usePayloadJWT) {
|
|
140
153
|
const refreshed = await refreshTokens({
|
|
141
154
|
payload,
|
|
142
155
|
refreshToken,
|
|
@@ -157,11 +170,17 @@ export class Strategy {
|
|
|
157
170
|
msg: 'Token refreshed. Verifying...',
|
|
158
171
|
verifyResult
|
|
159
172
|
});
|
|
160
|
-
if (
|
|
161
|
-
|
|
173
|
+
if (canSetHeaders) {
|
|
174
|
+
if (verifyResult.responseHeaders) {
|
|
175
|
+
mergeHeaders(verifyResult.responseHeaders, refreshed.headers);
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
responseHeaders: refreshed.headers,
|
|
179
|
+
user: verifyResult.user
|
|
180
|
+
};
|
|
162
181
|
}
|
|
182
|
+
// Authenticate this request without updating cookies
|
|
163
183
|
return {
|
|
164
|
-
responseHeaders: refreshed.headers,
|
|
165
184
|
user: verifyResult.user
|
|
166
185
|
};
|
|
167
186
|
} else {
|
|
@@ -200,6 +219,10 @@ export class Strategy {
|
|
|
200
219
|
for(let attempt = 1; attempt <= 5; attempt++){
|
|
201
220
|
try {
|
|
202
221
|
this.meta = await fetch(this.identityMetadataURL).then((res)=>res.json());
|
|
222
|
+
if (this.meta) {
|
|
223
|
+
// TODO: This is a hack to get the DefaultLoginButton to work with dynamic OAuth client registration
|
|
224
|
+
this.meta.authorization_endpoint = this.meta?.authorization_endpoint + '/cms';
|
|
225
|
+
}
|
|
203
226
|
this.debugLog(`fetchMeta - success on attempt ${attempt}`);
|
|
204
227
|
if (this.meta?.jwks_uri) {
|
|
205
228
|
this.jwks = await fetch(this.meta.jwks_uri).then((res)=>res.json());
|
|
@@ -259,7 +282,7 @@ export class Strategy {
|
|
|
259
282
|
}
|
|
260
283
|
async jwtVerify({ payload, token }) {
|
|
261
284
|
try {
|
|
262
|
-
const verified = await validateProjectToken(token,
|
|
285
|
+
const verified = await validateProjectToken(token, getInfraEnvironment());
|
|
263
286
|
if (typeof verified !== 'string') {
|
|
264
287
|
return verified;
|
|
265
288
|
}
|
package/dist/oauth/types.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export interface CollectionOptions {
|
|
|
30
30
|
* Set to false to only accept the JWT from cookies
|
|
31
31
|
*/
|
|
32
32
|
disableJWTFromHeader?: boolean;
|
|
33
|
-
disableLocalStrategy?:
|
|
33
|
+
disableLocalStrategy?: false | IncomingAuthType['disableLocalStrategy'];
|
|
34
34
|
/**
|
|
35
35
|
* The logout button will either redirect to the IDP logout screen or
|
|
36
36
|
* automatically log the user out of the IDP depending on provider.
|
|
@@ -112,11 +112,6 @@ export interface PluginOptions {
|
|
|
112
112
|
* @default 'payload-oauth-token'
|
|
113
113
|
*/
|
|
114
114
|
cookieName?: string;
|
|
115
|
-
/**
|
|
116
|
-
* Debug mode will log additional information to the console.
|
|
117
|
-
*
|
|
118
|
-
* NOTE: This will log sensitive information to the console.
|
|
119
|
-
*/
|
|
120
115
|
/**
|
|
121
116
|
* Accepts incoming request and allows for modification of cookie options
|
|
122
117
|
*/
|
|
@@ -125,6 +120,11 @@ export interface PluginOptions {
|
|
|
125
120
|
cookieOptions: CookieOptions;
|
|
126
121
|
headers: Headers;
|
|
127
122
|
}) => CookieOptions;
|
|
123
|
+
/**
|
|
124
|
+
* Debug mode will log additional information to the console.
|
|
125
|
+
*
|
|
126
|
+
* NOTE: This will log sensitive information to the console.
|
|
127
|
+
*/
|
|
128
128
|
debug?: boolean;
|
|
129
129
|
/**
|
|
130
130
|
* Disables the plugin functionality while leaving in types, fields and component modifications.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if an error is a duplicate key/unique constraint violation from Content API.
|
|
3
|
+
*
|
|
4
|
+
* Content API returns HTTP 409 with "conflict" or "already exists" in the message.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isDuplicateKeyError(error: unknown): boolean;
|
|
7
|
+
//# sourceMappingURL=isDuplicateKeyError.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if an error is a duplicate key/unique constraint violation from Content API.
|
|
3
|
+
*
|
|
4
|
+
* Content API returns HTTP 409 with "conflict" or "already exists" in the message.
|
|
5
|
+
*/ export function isDuplicateKeyError(error) {
|
|
6
|
+
if (!error || typeof error !== 'object') {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
const err = error;
|
|
10
|
+
const message = typeof err.message === 'string' ? err.message : '';
|
|
11
|
+
return message.includes('409') || message.toLowerCase().includes('conflict') || message.toLowerCase().includes('already exists');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=isDuplicateKeyError.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { generateCookie } from 'payload';
|
|
2
2
|
import { getProjectToken } from '../../api/figma-api.js';
|
|
3
3
|
import { validateProjectToken } from '../../auth/jwt-validator.js';
|
|
4
|
-
import {
|
|
4
|
+
import { getInfraEnvironment } from '../../constants.js';
|
|
5
5
|
import { createCookieOptions } from './createCookieOptions.js';
|
|
6
6
|
import { createDebugLogger } from './createDebugLogger.js';
|
|
7
7
|
import { getCookieExpiration } from './getCookieExpiration.js';
|
|
@@ -16,7 +16,10 @@ export const refreshTokens = async ({ payload, refreshToken, strategy })=>{
|
|
|
16
16
|
// so we will refresh both tokens
|
|
17
17
|
try {
|
|
18
18
|
// Get another project token
|
|
19
|
-
const { expiresAt, token } = await getProjectToken(
|
|
19
|
+
const { expiresAt, token } = await getProjectToken({
|
|
20
|
+
type: 'oauth',
|
|
21
|
+
token: refreshToken
|
|
22
|
+
}, payload.config.custom.figma.contentSystemId);
|
|
20
23
|
debugLogger.info({
|
|
21
24
|
expiresAt,
|
|
22
25
|
msg: 'Received new tokens from Figma API',
|
|
@@ -48,7 +51,7 @@ export const refreshTokens = async ({ payload, refreshToken, strategy })=>{
|
|
|
48
51
|
value: token
|
|
49
52
|
});
|
|
50
53
|
headers.append('Set-Cookie', tokenCookie);
|
|
51
|
-
const decodedOauthToken = await validateProjectToken(token,
|
|
54
|
+
const decodedOauthToken = await validateProjectToken(token, getInfraEnvironment());
|
|
52
55
|
return {
|
|
53
56
|
decodedOauthToken,
|
|
54
57
|
headers,
|
|
@@ -6,38 +6,41 @@ import type { Config, SanitizedConfig } from 'payload';
|
|
|
6
6
|
* - `db`: Omitted (auto-injected by Figma platform)
|
|
7
7
|
* - `secret`: Omitted (auto-injected by Figma platform)
|
|
8
8
|
* - `editor`: Optional (defaults to lexicalEditor() if not provided)
|
|
9
|
+
* - `contentSystemId`: Optional (resolved automatically from env vars or bootstrap cache)
|
|
9
10
|
*
|
|
10
11
|
* @example
|
|
11
|
-
* // Minimal config
|
|
12
|
+
* // Minimal config (contentSystemId resolved automatically)
|
|
12
13
|
* const config: FigmaConfig = {
|
|
14
|
+
* figma: {},
|
|
13
15
|
* collections: [...]
|
|
14
16
|
* }
|
|
15
17
|
*
|
|
16
18
|
* @example
|
|
17
19
|
* // With custom editor
|
|
18
20
|
* const config: FigmaConfig = {
|
|
21
|
+
* figma: {},
|
|
19
22
|
* collections: [...],
|
|
20
23
|
* editor: lexicalEditor({ features: [...] })
|
|
21
24
|
* }
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Disable Content System (use custom db)
|
|
28
|
+
* const config: FigmaConfig = {
|
|
29
|
+
* figma: {
|
|
30
|
+
* useContentSystem: false
|
|
31
|
+
* },
|
|
32
|
+
* db: mongooseAdapter({ url: process.env.DATABASE_URI }),
|
|
33
|
+
* collections: [...]
|
|
34
|
+
* }
|
|
22
35
|
*/
|
|
23
36
|
export type FigmaConfig = {
|
|
24
37
|
editor?: Config['editor'];
|
|
25
38
|
} & {
|
|
26
39
|
figma: {
|
|
27
|
-
|
|
28
|
-
|
|
40
|
+
contentSystemId?: string;
|
|
41
|
+
storage?: boolean;
|
|
29
42
|
useContentSystem?: boolean;
|
|
30
43
|
};
|
|
31
|
-
} & Omit<Config, '
|
|
32
|
-
|
|
33
|
-
* Figma platform wrapper for Payload's buildConfig.
|
|
34
|
-
* Automatically injects:
|
|
35
|
-
* - Figma database adapter
|
|
36
|
-
* - Secret (platform-provided)
|
|
37
|
-
* - Default lexicalEditor (if no custom editor specified)
|
|
38
|
-
*
|
|
39
|
-
* @param config - Payload configuration (db and secret omitted, editor optional)
|
|
40
|
-
* @returns Promise<SanitizedConfig> - Built Payload configuration
|
|
41
|
-
*/
|
|
42
|
-
export declare function buildConfig(config: FigmaConfig): Promise<SanitizedConfig>;
|
|
44
|
+
} & Omit<Config, 'db' | 'editor' | 'secret'> & Partial<Pick<Config, 'db'>>;
|
|
45
|
+
export declare function buildFigmaConfig(config: FigmaConfig): Promise<SanitizedConfig>;
|
|
43
46
|
//# sourceMappingURL=build-config.d.ts.map
|
|
@@ -1,26 +1,205 @@
|
|
|
1
|
+
import { cloudStoragePlugin } from '@payloadcms/plugin-cloud-storage';
|
|
2
|
+
import { initClientUploads } from '@payloadcms/plugin-cloud-storage/utilities';
|
|
1
3
|
import { lexicalEditor } from '@payloadcms/richtext-lexical';
|
|
2
4
|
import { buildConfig as payloadBuildConfig } from 'payload';
|
|
5
|
+
import { getBootstrapInfo } from '../api/control-plane.js';
|
|
6
|
+
import { getValidCredential } from '../auth/oauth-flow.js';
|
|
7
|
+
import { getTokenStore } from '../auth/token-store.js';
|
|
8
|
+
import { getEnvConfig } from '../constants.js';
|
|
9
|
+
import { contentAPIAdapter } from '../db-content-api/index.js';
|
|
10
|
+
import { scheduleExtractPlugin } from '../deploy/schedule-extract-plugin.js';
|
|
11
|
+
import { health } from '../endpoints/health.js';
|
|
12
|
+
import { schema } from '../endpoints/schema.js';
|
|
3
13
|
import { oAuth2Plugin } from '../oauth/index.js';
|
|
4
|
-
import {
|
|
14
|
+
import { createStorageClient } from '../storage-content-api/client.js';
|
|
15
|
+
import { getGenerateSignedURLHandler } from '../storage-content-api/client-uploads/generateSignedURL.js';
|
|
16
|
+
import { contentApiStorageAdapter } from '../storage-content-api/index.js';
|
|
17
|
+
import { cacheAllEnvironments } from '../utils/cache-bootstrap.js';
|
|
18
|
+
import * as log from '../utils/log.js';
|
|
5
19
|
/**
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
20
|
+
* Fields added to users collection for Figma profile info
|
|
21
|
+
*/ const figmaUserFields = [
|
|
22
|
+
{
|
|
23
|
+
name: 'figmaHandle',
|
|
24
|
+
type: 'text',
|
|
25
|
+
admin: {
|
|
26
|
+
readOnly: true
|
|
27
|
+
},
|
|
28
|
+
label: 'Name'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'figmaImageUrl',
|
|
32
|
+
type: 'text',
|
|
33
|
+
admin: {
|
|
34
|
+
components: {
|
|
35
|
+
Cell: '@payloadcms/figma/client#FigmaAvatarCell'
|
|
36
|
+
},
|
|
37
|
+
disableBulkEdit: true,
|
|
38
|
+
hidden: true,
|
|
39
|
+
readOnly: true
|
|
40
|
+
},
|
|
41
|
+
label: 'Profile Picture'
|
|
42
|
+
}
|
|
43
|
+
];
|
|
44
|
+
function missingOAuthCredential(name) {
|
|
45
|
+
log.warning(`${name} could not be resolved. OAuth login will not work until this is configured. ` + 'Run `npx @payloadcms/figma init` to set up your project.');
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Fetch bootstrap data from the API and cache all environments locally.
|
|
50
|
+
* Returns the requested environment's data, or null if resolution fails.
|
|
51
|
+
*/ async function resolveAndCacheBootstrap(store, projectId, environmentName) {
|
|
52
|
+
try {
|
|
53
|
+
const credential = await getValidCredential(store);
|
|
54
|
+
if (!credential) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const bootstrapInfo = await getBootstrapInfo(credential, projectId);
|
|
58
|
+
cacheAllEnvironments(store, projectId, bootstrapInfo);
|
|
59
|
+
return store.getBootstrapData(projectId, environmentName);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
log.warning(`Failed to resolve bootstrap data: ${error instanceof Error ? error.message : 'Unknown error'}. ` + 'Try running `npx @payloadcms/figma login` to refresh authentication.');
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export async function buildFigmaConfig(config) {
|
|
66
|
+
const envConfig = getEnvConfig();
|
|
67
|
+
// Resolve contentSystemId: config first, env var, then local store fallback (dev)
|
|
68
|
+
let { contentSystemId } = config.figma;
|
|
69
|
+
contentSystemId ??= process.env.FIGMA_CONTENT_API_CONTENT_SYSTEM_ID;
|
|
70
|
+
let bootstrapData = null;
|
|
71
|
+
// Local dev: resolve from project ID + bootstrap cache
|
|
72
|
+
if (!contentSystemId) {
|
|
73
|
+
const projectId = process.env.FIGMA_PROJECT_ID;
|
|
74
|
+
const environmentName = process.env.FIGMA_ENVIRONMENT_NAME;
|
|
75
|
+
if (projectId && environmentName) {
|
|
76
|
+
const store = getTokenStore();
|
|
77
|
+
bootstrapData = store.getBootstrapData(projectId, environmentName);
|
|
78
|
+
// Runtime fallback: fetch from API if not cached (e.g. environment switch without re-init)
|
|
79
|
+
if (!bootstrapData) {
|
|
80
|
+
bootstrapData = await resolveAndCacheBootstrap(store, projectId, environmentName);
|
|
81
|
+
}
|
|
82
|
+
if (bootstrapData) {
|
|
83
|
+
contentSystemId = bootstrapData.contentSystemId;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!contentSystemId) {
|
|
88
|
+
throw new Error('Content System ID could not be resolved. ' + 'Run `npx @payloadcms/figma init` to set up your project.');
|
|
89
|
+
}
|
|
90
|
+
const url = process.env.FIGMA_CONTENT_API_URL || envConfig.contentApiUrl;
|
|
91
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
|
92
|
+
// Determine database adapter based on environment
|
|
93
|
+
let db;
|
|
94
|
+
if (config.figma.useContentSystem === false) {
|
|
95
|
+
db = config.db;
|
|
96
|
+
} else if (process.env.FIGMA_CONTENT_API_ACCESS_KEY) {
|
|
97
|
+
db = contentAPIAdapter({
|
|
98
|
+
auth: {
|
|
99
|
+
apiKey: process.env.FIGMA_CONTENT_API_ACCESS_KEY,
|
|
100
|
+
mode: 'apiKey'
|
|
101
|
+
},
|
|
102
|
+
contentSystemId,
|
|
103
|
+
url
|
|
104
|
+
});
|
|
105
|
+
} else if (process.env.FIGMA_DEV_JWT === 'true') {
|
|
106
|
+
db = contentAPIAdapter({
|
|
107
|
+
auth: {
|
|
108
|
+
mode: 'devJwt'
|
|
109
|
+
},
|
|
110
|
+
contentSystemId,
|
|
111
|
+
url
|
|
112
|
+
});
|
|
113
|
+
} else {
|
|
114
|
+
db = contentAPIAdapter({
|
|
115
|
+
auth: {
|
|
116
|
+
mode: 'tokenStore',
|
|
117
|
+
tokenStore: getTokenStore()
|
|
118
|
+
},
|
|
119
|
+
contentSystemId,
|
|
120
|
+
url
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// Build storage plugin if there are upload collections and storage is not disabled
|
|
124
|
+
const uploadCollections = (config.collections || []).filter((c)=>c.upload);
|
|
125
|
+
let storagePlugin;
|
|
126
|
+
if (uploadCollections.length > 0 && config.figma.storage !== false) {
|
|
127
|
+
const storageConfig = process.env.FIGMA_CONTENT_API_ACCESS_KEY ? {
|
|
128
|
+
baseUrl: url,
|
|
129
|
+
contentApiKey: process.env.FIGMA_CONTENT_API_ACCESS_KEY
|
|
130
|
+
} : process.env.FIGMA_DEV_JWT === 'true' ? {
|
|
131
|
+
auth: {
|
|
132
|
+
mode: 'devJwt'
|
|
133
|
+
},
|
|
134
|
+
baseUrl: url,
|
|
135
|
+
contentSystemId
|
|
136
|
+
} : {
|
|
137
|
+
auth: {
|
|
138
|
+
mode: 'tokenStore',
|
|
139
|
+
tokenStore: getTokenStore()
|
|
140
|
+
},
|
|
141
|
+
baseUrl: url,
|
|
142
|
+
contentSystemId
|
|
143
|
+
};
|
|
144
|
+
const adapter = contentApiStorageAdapter(storageConfig);
|
|
145
|
+
const storageClient = createStorageClient(storageConfig);
|
|
146
|
+
const collectionsMap = uploadCollections.reduce((acc, c)=>{
|
|
147
|
+
acc[c.slug] = {
|
|
148
|
+
adapter,
|
|
149
|
+
disableLocalStorage: true
|
|
150
|
+
};
|
|
151
|
+
return acc;
|
|
152
|
+
}, {});
|
|
153
|
+
initClientUploads({
|
|
154
|
+
clientHandler: '@payloadcms/figma/client#ContentApiClientUploadHandler',
|
|
155
|
+
collections: collectionsMap,
|
|
156
|
+
config: config,
|
|
157
|
+
enabled: true,
|
|
158
|
+
serverHandler: getGenerateSignedURLHandler({
|
|
159
|
+
client: storageClient
|
|
160
|
+
}),
|
|
161
|
+
serverHandlerPath: '/content-api-storage-signed-url'
|
|
162
|
+
});
|
|
163
|
+
storagePlugin = cloudStoragePlugin({
|
|
164
|
+
collections: collectionsMap
|
|
165
|
+
});
|
|
166
|
+
}
|
|
15
167
|
// Build complete config with Figma platform defaults
|
|
16
168
|
const configWithFigmaDefaults = {
|
|
17
169
|
...config,
|
|
18
|
-
|
|
170
|
+
admin: {
|
|
171
|
+
// Auto-refresh tokens before expiry to prevent unexpected logouts.
|
|
172
|
+
autoRefresh: true,
|
|
173
|
+
avatar: {
|
|
174
|
+
Component: '@payloadcms/figma/client#FigmaAvatar'
|
|
175
|
+
},
|
|
176
|
+
...config.admin
|
|
177
|
+
},
|
|
178
|
+
custom: {
|
|
179
|
+
figma: {
|
|
180
|
+
...config.figma,
|
|
181
|
+
contentSystemId
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
db,
|
|
19
185
|
editor: config.editor ?? lexicalEditor(),
|
|
186
|
+
endpoints: [
|
|
187
|
+
...config.endpoints ?? [],
|
|
188
|
+
health,
|
|
189
|
+
schema
|
|
190
|
+
],
|
|
191
|
+
...isProduction && !config.logger ? {
|
|
192
|
+
logger: {
|
|
193
|
+
options: {}
|
|
194
|
+
}
|
|
195
|
+
} : {},
|
|
20
196
|
secret: 'MY_SECRET',
|
|
21
197
|
// Add oauth to plugins if not already present
|
|
22
198
|
plugins: [
|
|
23
199
|
...config.plugins ?? [],
|
|
200
|
+
...storagePlugin ? [
|
|
201
|
+
storagePlugin
|
|
202
|
+
] : [],
|
|
24
203
|
oAuth2Plugin({
|
|
25
204
|
collections: [
|
|
26
205
|
{
|
|
@@ -30,9 +209,9 @@ import { figmaContentSystem } from './adapter.js';
|
|
|
30
209
|
response_mode: 'query',
|
|
31
210
|
response_type: 'code'
|
|
32
211
|
},
|
|
33
|
-
clientID: process.env.FIGMA_OAUTH_CLIENT_ID,
|
|
34
|
-
clientSecret: process.env.FIGMA_OAUTH_CLIENT_SECRET,
|
|
35
|
-
identityMetadata:
|
|
212
|
+
clientID: process.env.FIGMA_OAUTH_CLIENT_ID ?? bootstrapData?.oauthClientId ?? missingOAuthCredential('FIGMA_OAUTH_CLIENT_ID'),
|
|
213
|
+
clientSecret: process.env.FIGMA_OAUTH_CLIENT_SECRET ?? bootstrapData?.oauthClientSecret,
|
|
214
|
+
identityMetadata: envConfig.identityMetadata,
|
|
36
215
|
scope: [
|
|
37
216
|
'current_user:read'
|
|
38
217
|
],
|
|
@@ -40,12 +219,28 @@ import { figmaContentSystem } from './adapter.js';
|
|
|
40
219
|
usernameField: 'email'
|
|
41
220
|
}
|
|
42
221
|
],
|
|
43
|
-
debug:
|
|
44
|
-
disabled: false
|
|
45
|
-
|
|
46
|
-
|
|
222
|
+
debug: !!process.env.DEBUG,
|
|
223
|
+
disabled: false
|
|
224
|
+
}),
|
|
225
|
+
scheduleExtractPlugin()
|
|
47
226
|
]
|
|
48
227
|
};
|
|
228
|
+
// Inject figma fields into users collection
|
|
229
|
+
const collections = configWithFigmaDefaults.collections?.map((col)=>{
|
|
230
|
+
if (col.slug === 'users') {
|
|
231
|
+
return {
|
|
232
|
+
...col,
|
|
233
|
+
fields: [
|
|
234
|
+
...col.fields || [],
|
|
235
|
+
...figmaUserFields
|
|
236
|
+
]
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
return col;
|
|
240
|
+
});
|
|
241
|
+
if (collections) {
|
|
242
|
+
configWithFigmaDefaults.collections = collections;
|
|
243
|
+
}
|
|
49
244
|
// Delegate to Payload's buildConfig
|
|
50
245
|
return await payloadBuildConfig(configWithFigmaDefaults);
|
|
51
246
|
}
|