payload-zitadel-plugin 0.2.2 → 0.2.4

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/README.md CHANGED
@@ -12,7 +12,7 @@ Thus the user collection in PayloadCMS becomes just a shadow of the information
12
12
  ## Install
13
13
 
14
14
  ```shell
15
- pnpm add payload-zitadel-plugin@0.2.1
15
+ pnpm add payload-zitadel-plugin@0.2.4
16
16
  ```
17
17
 
18
18
  ## Configuration
@@ -51,6 +51,10 @@ export default buildConfig({
51
51
  // if you want to specify the field name for the Zitadel User Id in the users collection
52
52
  // associatedIdFieldName: 'idp_id'
53
53
 
54
+ // if you want to manually control what happen after a successful login
55
+ // state contains all URLSearchParams that were send to /authorize
56
+ // onSuccess: (state) => NextResponse.redirect([serverURL, state.get('redirect')].join(''))
57
+
54
58
  // following properties are only needed if you want to authenticate clients for the API
55
59
  // if you are just using the CMS you can ignore all of them
56
60
  // in Zitadel create a new App->API->JWT
@@ -133,7 +137,7 @@ const nextConfig = {
133
137
  return [
134
138
  {
135
139
  source: '/admin/login',
136
- destination: '/api/users/authorize',
140
+ destination: `/api/users/authorize?${new URLSearchParams({redirect: '/profile'})}`,
137
141
  permanent: true
138
142
  }
139
143
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../src/components/Avatar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,eAAO,MAAM,MAAM,yBA6BlB,CAAA"}
1
+ {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../src/components/Avatar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,eAAO,MAAM,MAAM,yBA8BlB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Avatar.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport {DefaultAccountIcon} from '@payloadcms/ui/graphics/Account/Default'\nimport {Image} from 'next/dist/client/image-component.js'\nimport {useAuth} from '@payloadcms/ui'\n\n\nexport const Avatar = () => {\n\n const {user} = useAuth()\n\n return (user?.image ?\n <>\n <style>\n {`\n .avatar {\n position: relative;\n height: 2rem;\n width: 2rem;\n }\n \n .avatar:hover {\n filter: brightness(.8);\n }\n \n .avatar img {\n border-radius: 100%;\n }\n `}\n </style>\n <div className=\"avatar\">\n <Image src={user.image} alt=\"Profile Picture\" fill sizes=\"2rem 2rem\"/>\n </div>\n </> :\n <DefaultAccountIcon active={false}/>\n )\n}"],"names":["React","DefaultAccountIcon","Image","useAuth","Avatar","user","image","style","div","className","src","alt","fill","sizes","active"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAO;AAC9B,SAAQC,kBAAkB,QAAO,0CAAyC;AAC1E,SAAQC,KAAK,QAAO,sCAAqC;AACzD,SAAQC,OAAO,QAAO,iBAAgB;AAGtC,OAAO,MAAMC,SAAS;IAElB,MAAM,EAACC,IAAI,EAAC,GAAGF;IAEf,OAAQE,MAAMC,sBACN,wDACI,oBAACC,eACI,CAAC;;;;;;;;;;;;;;wBAcE,CAAC,iBAET,oBAACC;QAAIC,WAAU;qBACX,oBAACP;QAAMQ,KAAKL,KAAKC,KAAK;QAAEK,KAAI;QAAkBC,MAAAA;QAAKC,OAAM;yBAGjE,oBAACZ;QAAmBa,QAAQ;;AAExC,EAAC"}
1
+ {"version":3,"sources":["../../src/components/Avatar.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport {DefaultAccountIcon} from '@payloadcms/ui/graphics/Account/Default'\nimport {Image} from 'next/dist/client/image-component.js'\nimport {useAuth} from '@payloadcms/ui'\n\n\nexport const Avatar = () => {\n\n const {user} = useAuth()\n\n return (user?.image ?\n <>\n <style>\n {`\n .avatar {\n position: relative;\n height: 2rem;\n width: 2rem;\n }\n \n .avatar:hover {\n filter: brightness(.8);\n }\n \n .avatar img {\n border-radius: 100%;\n }\n `}\n </style>\n <div className=\"avatar\">\n <Image src={user.image} alt=\"Profile Picture\" fill sizes=\"2rem 2rem\"/>\n </div>\n </> :\n <DefaultAccountIcon active={false}/>\n )\n\n}"],"names":["React","DefaultAccountIcon","Image","useAuth","Avatar","user","image","style","div","className","src","alt","fill","sizes","active"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAO;AAC9B,SAAQC,kBAAkB,QAAO,0CAAyC;AAC1E,SAAQC,KAAK,QAAO,sCAAqC;AACzD,SAAQC,OAAO,QAAO,iBAAgB;AAGtC,OAAO,MAAMC,SAAS;IAElB,MAAM,EAACC,IAAI,EAAC,GAAGF;IAEf,OAAQE,MAAMC,sBACN,wDACI,oBAACC,eACI,CAAC;;;;;;;;;;;;;;wBAcE,CAAC,iBAET,oBAACC;QAAIC,WAAU;qBACX,oBAACP;QAAMQ,KAAKL,KAAKC,KAAK;QAAEK,KAAI;QAAkBC,MAAAA;QAAKC,OAAM;yBAGjE,oBAACZ;QAAmBa,QAAQ;;AAGxC,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"LoginButton.d.ts","sourceRoot":"","sources":["../../src/components/LoginButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,eAAO,MAAM,WAAW,yBAcvB,CAAA"}
1
+ {"version":3,"file":"LoginButton.d.ts","sourceRoot":"","sources":["../../src/components/LoginButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,eAAO,MAAM,WAAW,yBAcvB,CAAA"}
@@ -3,14 +3,14 @@ import React from 'react';
3
3
  import { Button, useConfig, useTranslation } from '@payloadcms/ui';
4
4
  export const LoginButton = ()=>{
5
5
  const { t } = useTranslation();
6
- const { admin: { custom: { zitadel: { label } } } } = useConfig();
6
+ const { admin: { custom: { zitadel: { label, authorizeURL } } } } = useConfig();
7
7
  return /*#__PURE__*/ React.createElement("div", {
8
8
  style: {
9
9
  display: 'flex',
10
10
  justifyContent: 'center'
11
11
  }
12
12
  }, /*#__PURE__*/ React.createElement(Button, {
13
- onClick: ()=>open('http://localhost/api/users/authorize', '_self')
13
+ onClick: ()=>open(authorizeURL, '_self')
14
14
  }, t('oidcPlugin:signIn', {
15
15
  label
16
16
  })));
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/LoginButton.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport {NestedKeysStripped} from '@payloadcms/translations'\nimport {Button, useConfig, useTranslation} from '@payloadcms/ui'\nimport {translations} from '../translations.js'\n\nexport const LoginButton = () => {\n\n const {t} = useTranslation<typeof translations.en, NestedKeysStripped<typeof translations.en>>()\n\n const {admin: {custom: {zitadel: {label}}}} = useConfig()\n\n return (\n <div style={{display: 'flex', justifyContent: 'center'}}>\n <Button onClick={() => open('http://localhost/api/users/authorize', '_self')}>\n {t('oidcPlugin:signIn', {label})}\n </Button>\n </div>\n )\n\n}"],"names":["React","Button","useConfig","useTranslation","LoginButton","t","admin","custom","zitadel","label","div","style","display","justifyContent","onClick","open"],"mappings":"AAAA;AAEA,OAAOA,WAAW,QAAO;AAEzB,SAAQC,MAAM,EAAEC,SAAS,EAAEC,cAAc,QAAO,iBAAgB;AAGhE,OAAO,MAAMC,cAAc;IAEvB,MAAM,EAACC,CAAC,EAAC,GAAGF;IAEZ,MAAM,EAACG,OAAO,EAACC,QAAQ,EAACC,SAAS,EAACC,KAAK,EAAC,EAAC,EAAC,EAAC,GAAGP;IAE9C,qBACI,oBAACQ;QAAIC,OAAO;YAACC,SAAS;YAAQC,gBAAgB;QAAQ;qBAClD,oBAACZ;QAAOa,SAAS,IAAMC,KAAK,wCAAwC;OAC/DV,EAAE,qBAAqB;QAACI;IAAK;AAK9C,EAAC"}
1
+ {"version":3,"sources":["../../src/components/LoginButton.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport {NestedKeysStripped} from '@payloadcms/translations'\nimport {Button, useConfig, useTranslation} from '@payloadcms/ui'\nimport {translations} from '../translations.js'\nimport {PayloadConfigWithZitadel} from '../types.js'\n\nexport const LoginButton = () => {\n\n const {t} = useTranslation<typeof translations.en, NestedKeysStripped<typeof translations.en>>()\n\n const {admin: {custom: {zitadel: {label, authorizeURL}}}} = useConfig() as PayloadConfigWithZitadel\n\n return (\n <div style={{display: 'flex', justifyContent: 'center'}}>\n <Button onClick={() => open(authorizeURL, '_self')}>\n {t('oidcPlugin:signIn', {label})}\n </Button>\n </div>\n )\n\n}"],"names":["React","Button","useConfig","useTranslation","LoginButton","t","admin","custom","zitadel","label","authorizeURL","div","style","display","justifyContent","onClick","open"],"mappings":"AAAA;AAEA,OAAOA,WAAW,QAAO;AAEzB,SAAQC,MAAM,EAAEC,SAAS,EAAEC,cAAc,QAAO,iBAAgB;AAIhE,OAAO,MAAMC,cAAc;IAEvB,MAAM,EAACC,CAAC,EAAC,GAAGF;IAEZ,MAAM,EAACG,OAAO,EAACC,QAAQ,EAACC,SAAS,EAACC,KAAK,EAAEC,YAAY,EAAC,EAAC,EAAC,EAAC,GAAGR;IAE5D,qBACI,oBAACS;QAAIC,OAAO;YAACC,SAAS;YAAQC,gBAAgB;QAAQ;qBAClD,oBAACb;QAAOc,SAAS,IAAMC,KAAKN,cAAc;OACrCL,EAAE,qBAAqB;QAACI;IAAK;AAK9C,EAAC"}
@@ -0,0 +1,23 @@
1
+ export declare const ROUTES: {
2
+ authorize: string;
3
+ callback: string;
4
+ };
5
+ export declare const COOKIE_ID_TOKEN = "id_token";
6
+ export declare const DEFAULT_CONFIG: {
7
+ associatedIdFieldName: string;
8
+ strategyName: string;
9
+ label: string;
10
+ };
11
+ export declare const DELETE_ME_USER: {
12
+ email: string;
13
+ password: string;
14
+ associatedId: string;
15
+ };
16
+ export declare const ERROR_MESSAGES: {
17
+ issuerURL: string;
18
+ clientId: string;
19
+ apiClientId: string;
20
+ apiKeyId: string;
21
+ apiKey: string;
22
+ };
23
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM;;;CAGlB,CAAA;AAED,eAAO,MAAM,eAAe,aAAa,CAAA;AAEzC,eAAO,MAAM,cAAc;;;;CAI1B,CAAA;AAED,eAAO,MAAM,cAAc;;;;CAI1B,CAAA;AAED,eAAO,MAAM,cAAc;;;;;;CAM1B,CAAA"}
@@ -0,0 +1,24 @@
1
+ export const ROUTES = {
2
+ authorize: '/authorize',
3
+ callback: '/callback'
4
+ };
5
+ export const COOKIE_ID_TOKEN = 'id_token';
6
+ export const DEFAULT_CONFIG = {
7
+ associatedIdFieldName: 'idp_id',
8
+ strategyName: 'zitadel',
9
+ label: 'Zitadel'
10
+ };
11
+ export const DELETE_ME_USER = {
12
+ email: 'delete.me@now.not-tld',
13
+ password: 'password',
14
+ associatedId: 'DELETE_ME'
15
+ };
16
+ export const ERROR_MESSAGES = {
17
+ issuerURL: 'ZITADEL-PLUGIN: ISSUER-URL IS EMPTY',
18
+ clientId: 'ZITADEL-PLUGIN: CLIENT-ID IS EMPTY',
19
+ apiClientId: 'ZITADEL-PLUGIN: API ENABLED, BUT API-CLIENT-ID IS EMPTY',
20
+ apiKeyId: 'ZITADEL-PLUGIN: API ENABLED, BUT API-KEY-ID IS EMPTY',
21
+ apiKey: 'ZITADEL-PLUGIN: API ENABLED, BUT API-KEY IS EMPTY'
22
+ };
23
+
24
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/constants.ts"],"sourcesContent":["export const ROUTES = {\n authorize: '/authorize',\n callback: '/callback'\n}\n\nexport const COOKIE_ID_TOKEN = 'id_token'\n\nexport const DEFAULT_CONFIG = {\n associatedIdFieldName: 'idp_id',\n strategyName: 'zitadel',\n label: 'Zitadel'\n}\n\nexport const DELETE_ME_USER = {\n email: 'delete.me@now.not-tld',\n password: 'password',\n associatedId: 'DELETE_ME'\n}\n\nexport const ERROR_MESSAGES = {\n issuerURL: 'ZITADEL-PLUGIN: ISSUER-URL IS EMPTY',\n clientId: 'ZITADEL-PLUGIN: CLIENT-ID IS EMPTY',\n apiClientId: 'ZITADEL-PLUGIN: API ENABLED, BUT API-CLIENT-ID IS EMPTY',\n apiKeyId: 'ZITADEL-PLUGIN: API ENABLED, BUT API-KEY-ID IS EMPTY',\n apiKey: 'ZITADEL-PLUGIN: API ENABLED, BUT API-KEY IS EMPTY'\n}"],"names":["ROUTES","authorize","callback","COOKIE_ID_TOKEN","DEFAULT_CONFIG","associatedIdFieldName","strategyName","label","DELETE_ME_USER","email","password","associatedId","ERROR_MESSAGES","issuerURL","clientId","apiClientId","apiKeyId","apiKey"],"mappings":"AAAA,OAAO,MAAMA,SAAS;IAClBC,WAAW;IACXC,UAAU;AACd,EAAC;AAED,OAAO,MAAMC,kBAAkB,WAAU;AAEzC,OAAO,MAAMC,iBAAiB;IAC1BC,uBAAuB;IACvBC,cAAc;IACdC,OAAO;AACX,EAAC;AAED,OAAO,MAAMC,iBAAiB;IAC1BC,OAAO;IACPC,UAAU;IACVC,cAAc;AAClB,EAAC;AAED,OAAO,MAAMC,iBAAiB;IAC1BC,WAAW;IACXC,UAAU;IACVC,aAAa;IACbC,UAAU;IACVC,QAAQ;AACZ,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/handlers/authorize.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,cAAc,EAAC,MAAM,SAAS,CAAA;AAwBtC,eAAO,MAAM,SAAS,EAAE,cAuBJ,CAAA"}
1
+ {"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/handlers/authorize.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,cAAc,EAAC,MAAM,SAAS,CAAA;AAsBtC,eAAO,MAAM,SAAS,EAAE,cAcvB,CAAA"}
@@ -15,14 +15,17 @@ const genCodeChallenge = async ()=>{
15
15
  });
16
16
  return Buffer.from(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(code_verifier))).toString('base64url');
17
17
  };
18
- export const authorize = async ({ payload: { config: { admin: { custom: { zitadel: { issuerURL, clientId, redirectURL } } } } } })=>NextResponse.redirect(`${issuerURL}/oauth/v2/authorize?${new URLSearchParams({
18
+ export const authorize = async ({ searchParams, payload: { config } })=>{
19
+ const { admin: { custom: { zitadel: { issuerURL, clientId, callbackURL } } } } = config;
20
+ return NextResponse.redirect(`${issuerURL}/oauth/v2/authorize?${new URLSearchParams({
19
21
  client_id: clientId,
20
- redirect_uri: redirectURL,
22
+ redirect_uri: callbackURL,
21
23
  response_type: 'code',
22
24
  scope: 'openid email profile',
23
- state: '',
25
+ state: btoa(searchParams.toString()),
24
26
  code_challenge: await genCodeChallenge(),
25
27
  code_challenge_method: 'S256'
26
- }).toString()}`);
28
+ })}`);
29
+ };
27
30
 
28
31
  //# sourceMappingURL=authorize.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/handlers/authorize.ts"],"sourcesContent":["'use server'\n\nimport {cookies} from 'next/headers.js'\nimport process from 'node:process'\nimport {PayloadHandler} from 'payload'\nimport {NextResponse} from 'next/server.js'\n\nconst genCodeChallenge = async () => {\n\n const code_verifier = Buffer.from(crypto.getRandomValues(new Uint8Array(24)))\n .toString('base64url')\n\n cookies().set({\n name: 'pkce_code_verifier',\n value: code_verifier,\n httpOnly: true,\n sameSite: 'lax',\n path: '/',\n maxAge: 300,\n secure: process.env.NODE_ENV == 'production'\n })\n\n return Buffer.from(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(code_verifier)))\n .toString('base64url')\n\n}\n\n\nexport const authorize: PayloadHandler = async ({\n payload: {\n config: {\n admin: {\n custom: {\n zitadel: {\n issuerURL,\n clientId,\n redirectURL\n }\n }\n }\n }\n }\n }) =>\n NextResponse.redirect(`${issuerURL}/oauth/v2/authorize?${new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectURL,\n response_type: 'code',\n scope: 'openid email profile',\n state: '',\n code_challenge: await genCodeChallenge(),\n code_challenge_method: 'S256'\n }).toString()}`)"],"names":["cookies","process","NextResponse","genCodeChallenge","code_verifier","Buffer","from","crypto","getRandomValues","Uint8Array","toString","set","name","value","httpOnly","sameSite","path","maxAge","secure","env","NODE_ENV","subtle","digest","TextEncoder","encode","authorize","payload","config","admin","custom","zitadel","issuerURL","clientId","redirectURL","redirect","URLSearchParams","client_id","redirect_uri","response_type","scope","state","code_challenge","code_challenge_method"],"mappings":"AAAA;AAEA,SAAQA,OAAO,QAAO,kBAAiB;AACvC,OAAOC,aAAa,eAAc;AAElC,SAAQC,YAAY,QAAO,iBAAgB;AAE3C,MAAMC,mBAAmB;IAErB,MAAMC,gBAAgBC,OAAOC,IAAI,CAACC,OAAOC,eAAe,CAAC,IAAIC,WAAW,MACnEC,QAAQ,CAAC;IAEdV,UAAUW,GAAG,CAAC;QACVC,MAAM;QACNC,OAAOT;QACPU,UAAU;QACVC,UAAU;QACVC,MAAM;QACNC,QAAQ;QACRC,QAAQjB,QAAQkB,GAAG,CAACC,QAAQ,IAAI;IACpC;IAEA,OAAOf,OAAOC,IAAI,CAAC,MAAMC,OAAOc,MAAM,CAACC,MAAM,CAAC,WAAW,IAAIC,cAAcC,MAAM,CAACpB,iBAC7EM,QAAQ,CAAC;AAElB;AAGA,OAAO,MAAMe,YAA4B,OAAO,EACIC,SAAS,EACLC,QAAQ,EACJC,OAAO,EACHC,QAAQ,EACJC,SAAS,EACLC,SAAS,EACTC,QAAQ,EACRC,WAAW,EACd,EACJ,EACJ,EACJ,EACJ,EACJ,GAC7C/B,aAAagC,QAAQ,CAAC,CAAC,EAAEH,UAAU,oBAAoB,EAAE,IAAII,gBAAgB;QACzEC,WAAWJ;QACXK,cAAcJ;QACdK,eAAe;QACfC,OAAO;QACPC,OAAO;QACPC,gBAAgB,MAAMtC;QACtBuC,uBAAuB;IAC3B,GAAGhC,QAAQ,GAAG,CAAC,EAAC"}
1
+ {"version":3,"sources":["../../src/handlers/authorize.ts"],"sourcesContent":["'use server'\n\nimport {cookies} from 'next/headers.js'\nimport process from 'node:process'\nimport {PayloadHandler} from 'payload'\nimport {NextResponse} from 'next/server.js'\nimport {PayloadConfigWithZitadel} from '../types.js'\n\nconst genCodeChallenge = async () => {\n\n const code_verifier = Buffer.from(crypto.getRandomValues(new Uint8Array(24))).toString('base64url')\n\n cookies().set({\n name: 'pkce_code_verifier',\n value: code_verifier,\n httpOnly: true,\n sameSite: 'lax',\n path: '/',\n maxAge: 300,\n secure: process.env.NODE_ENV == 'production'\n })\n\n return Buffer.from(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(code_verifier))).toString('base64url')\n\n}\n\nexport const authorize: PayloadHandler = async ({searchParams, payload: {config}}) => {\n\n const {admin: {custom: {zitadel: {issuerURL, clientId, callbackURL}}}} = config as PayloadConfigWithZitadel\n\n return NextResponse.redirect(`${issuerURL}/oauth/v2/authorize?${new URLSearchParams({\n client_id: clientId,\n redirect_uri: callbackURL,\n response_type: 'code',\n scope: 'openid email profile',\n state: btoa(searchParams.toString()),\n code_challenge: await genCodeChallenge(),\n code_challenge_method: 'S256'\n })}`)\n\n}\n"],"names":["cookies","process","NextResponse","genCodeChallenge","code_verifier","Buffer","from","crypto","getRandomValues","Uint8Array","toString","set","name","value","httpOnly","sameSite","path","maxAge","secure","env","NODE_ENV","subtle","digest","TextEncoder","encode","authorize","searchParams","payload","config","admin","custom","zitadel","issuerURL","clientId","callbackURL","redirect","URLSearchParams","client_id","redirect_uri","response_type","scope","state","btoa","code_challenge","code_challenge_method"],"mappings":"AAAA;AAEA,SAAQA,OAAO,QAAO,kBAAiB;AACvC,OAAOC,aAAa,eAAc;AAElC,SAAQC,YAAY,QAAO,iBAAgB;AAG3C,MAAMC,mBAAmB;IAErB,MAAMC,gBAAgBC,OAAOC,IAAI,CAACC,OAAOC,eAAe,CAAC,IAAIC,WAAW,MAAMC,QAAQ,CAAC;IAEvFV,UAAUW,GAAG,CAAC;QACVC,MAAM;QACNC,OAAOT;QACPU,UAAU;QACVC,UAAU;QACVC,MAAM;QACNC,QAAQ;QACRC,QAAQjB,QAAQkB,GAAG,CAACC,QAAQ,IAAI;IACpC;IAEA,OAAOf,OAAOC,IAAI,CAAC,MAAMC,OAAOc,MAAM,CAACC,MAAM,CAAC,WAAW,IAAIC,cAAcC,MAAM,CAACpB,iBAAiBM,QAAQ,CAAC;AAEhH;AAEA,OAAO,MAAMe,YAA4B,OAAO,EAACC,YAAY,EAAEC,SAAS,EAACC,MAAM,EAAC,EAAC;IAE7E,MAAM,EAACC,OAAO,EAACC,QAAQ,EAACC,SAAS,EAACC,SAAS,EAAEC,QAAQ,EAAEC,WAAW,EAAC,EAAC,EAAC,EAAC,GAAGN;IAEzE,OAAO1B,aAAaiC,QAAQ,CAAC,CAAC,EAAEH,UAAU,oBAAoB,EAAE,IAAII,gBAAgB;QAChFC,WAAWJ;QACXK,cAAcJ;QACdK,eAAe;QACfC,OAAO;QACPC,OAAOC,KAAKhB,aAAahB,QAAQ;QACjCiC,gBAAgB,MAAMxC;QACtByC,uBAAuB;IAC3B,GAAG,CAAC;AAER,EAAC"}
@@ -1,3 +1,4 @@
1
1
  import { PayloadHandler } from 'payload';
2
- export declare const callback: PayloadHandler;
2
+ import { ZitadelOnSuccess } from '../types.js';
3
+ export declare const callback: (onSuccess: ZitadelOnSuccess) => PayloadHandler;
3
4
  //# sourceMappingURL=callback.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../src/handlers/callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,SAAS,CAAA;AAMtC,eAAO,MAAM,QAAQ,EAAE,cAyDtB,CAAA"}
1
+ {"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../src/handlers/callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,SAAS,CAAA;AAItC,OAAO,EAA2C,gBAAgB,EAAC,MAAM,aAAa,CAAA;AAEtF,eAAO,MAAM,QAAQ,cAAe,gBAAgB,KAAG,cA+DtD,CAAA"}
@@ -1,50 +1,50 @@
1
1
  import { cookies } from 'next/headers.js';
2
2
  import process from 'node:process';
3
3
  import jwt from 'jsonwebtoken';
4
- export const callback = async ({ payload, query: { code } })=>{
5
- const { secret, admin: { custom: { zitadel: { issuerURL, clientId, redirectURL } } } } = payload.config;
6
- const cookieStore = cookies();
7
- const code_verifier = cookieStore.get('pkce_code_verifier')?.value;
8
- if (code_verifier) {
9
- const response = await fetch(new URL(`${issuerURL}/oauth/v2/token`), {
10
- method: 'POST',
11
- body: new URLSearchParams({
12
- grant_type: 'authorization_code',
13
- code: code,
14
- redirect_uri: redirectURL,
15
- client_id: clientId,
16
- code_verifier
17
- })
18
- });
19
- if (response.ok) {
20
- const { id_token } = await response.json();
21
- if (id_token) {
22
- cookieStore.set({
23
- name: 'id_token',
24
- value: jwt.sign(jwt.decode(id_token), secret),
25
- httpOnly: true,
26
- path: '/',
27
- sameSite: 'strict',
28
- maxAge: 900,
29
- secure: process.env.NODE_ENV == 'production'
4
+ export const callback = (onSuccess)=>async ({ payload, query: { code, state } })=>{
5
+ const { secret, admin: { custom: { zitadel: { issuerURL, clientId, callbackURL } } } } = payload.config;
6
+ const cookieStore = cookies();
7
+ const code_verifier = cookieStore.get('pkce_code_verifier')?.value;
8
+ if (code_verifier) {
9
+ const response = await fetch(new URL(`${issuerURL}/oauth/v2/token`), {
10
+ method: 'POST',
11
+ body: new URLSearchParams({
12
+ grant_type: 'authorization_code',
13
+ code: code,
14
+ redirect_uri: callbackURL,
15
+ client_id: clientId,
16
+ code_verifier
17
+ })
18
+ });
19
+ if (response.ok) {
20
+ const { id_token } = await response.json();
21
+ if (id_token) {
22
+ cookieStore.set({
23
+ name: 'id_token',
24
+ value: jwt.sign(jwt.decode(id_token), secret),
25
+ httpOnly: true,
26
+ path: '/',
27
+ sameSite: 'strict',
28
+ maxAge: 900,
29
+ secure: process.env.NODE_ENV == 'production'
30
+ });
31
+ cookieStore.delete('pkce_code_verifier');
32
+ return onSuccess(new URLSearchParams(atob(state ?? '')));
33
+ }
34
+ return Response.json({
35
+ status: 'error',
36
+ message: 'token could not be retrieved from the response'
30
37
  });
31
- cookieStore.delete('pkce_code_verifier');
32
- return Response.redirect(new URL(redirectURL).origin);
33
38
  }
34
39
  return Response.json({
35
40
  status: 'error',
36
- message: 'token could not be retrieved from the response'
41
+ message: 'error while communicating with token endpoint'
37
42
  });
38
43
  }
39
44
  return Response.json({
40
45
  status: 'error',
41
- message: 'error while communicating with token endpoint'
46
+ message: 'code verifier not found (associated http-only cookie is empty)'
42
47
  });
43
- }
44
- return Response.json({
45
- status: 'error',
46
- message: 'code verifier not found (associated http-only cookie is empty)'
47
- });
48
- };
48
+ };
49
49
 
50
50
  //# sourceMappingURL=callback.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/handlers/callback.ts"],"sourcesContent":["import {PayloadHandler} from 'payload'\nimport {cookies} from 'next/headers.js'\nimport process from 'node:process'\nimport jwt from 'jsonwebtoken'\nimport {ZitadelIdToken} from '../types.js'\n\nexport const callback: PayloadHandler = async ({payload, query: {code}}) => {\n\n const {secret, admin: {custom: {zitadel: {issuerURL, clientId, redirectURL}}}} = payload.config\n\n const cookieStore = cookies()\n\n const code_verifier = cookieStore.get('pkce_code_verifier')?.value\n\n if (code_verifier) {\n\n const response = await fetch(new URL(`${issuerURL}/oauth/v2/token`), {\n method: 'POST',\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n code: code as string,\n redirect_uri: redirectURL,\n client_id: clientId,\n code_verifier\n })\n })\n\n if (response.ok) {\n const {id_token} = await response.json()\n\n if (id_token) {\n cookieStore.set({\n name: 'id_token',\n value: jwt.sign(jwt.decode(id_token) as ZitadelIdToken, secret),\n httpOnly: true,\n path: '/',\n sameSite: 'strict',\n maxAge: 900,\n secure: process.env.NODE_ENV == 'production'\n })\n cookieStore.delete('pkce_code_verifier')\n\n return Response.redirect(new URL(redirectURL).origin)\n }\n\n return Response.json({\n status: 'error',\n message: 'token could not be retrieved from the response'\n })\n }\n\n return Response.json({\n status: 'error',\n message: 'error while communicating with token endpoint'\n })\n\n }\n\n return Response.json({\n status: 'error',\n message: 'code verifier not found (associated http-only cookie is empty)'\n })\n\n}"],"names":["cookies","process","jwt","callback","payload","query","code","secret","admin","custom","zitadel","issuerURL","clientId","redirectURL","config","cookieStore","code_verifier","get","value","response","fetch","URL","method","body","URLSearchParams","grant_type","redirect_uri","client_id","ok","id_token","json","set","name","sign","decode","httpOnly","path","sameSite","maxAge","secure","env","NODE_ENV","delete","Response","redirect","origin","status","message"],"mappings":"AACA,SAAQA,OAAO,QAAO,kBAAiB;AACvC,OAAOC,aAAa,eAAc;AAClC,OAAOC,SAAS,eAAc;AAG9B,OAAO,MAAMC,WAA2B,OAAO,EAACC,OAAO,EAAEC,OAAO,EAACC,IAAI,EAAC,EAAC;IAEnE,MAAM,EAACC,MAAM,EAAEC,OAAO,EAACC,QAAQ,EAACC,SAAS,EAACC,SAAS,EAAEC,QAAQ,EAAEC,WAAW,EAAC,EAAC,EAAC,EAAC,GAAGT,QAAQU,MAAM;IAE/F,MAAMC,cAAcf;IAEpB,MAAMgB,gBAAgBD,YAAYE,GAAG,CAAC,uBAAuBC;IAE7D,IAAIF,eAAe;QAEf,MAAMG,WAAW,MAAMC,MAAM,IAAIC,IAAI,CAAC,EAAEV,UAAU,eAAe,CAAC,GAAG;YACjEW,QAAQ;YACRC,MAAM,IAAIC,gBAAgB;gBACtBC,YAAY;gBACZnB,MAAMA;gBACNoB,cAAcb;gBACdc,WAAWf;gBACXI;YACJ;QACJ;QAEA,IAAIG,SAASS,EAAE,EAAE;YACb,MAAM,EAACC,QAAQ,EAAC,GAAG,MAAMV,SAASW,IAAI;YAEtC,IAAID,UAAU;gBACVd,YAAYgB,GAAG,CAAC;oBACZC,MAAM;oBACNd,OAAOhB,IAAI+B,IAAI,CAAC/B,IAAIgC,MAAM,CAACL,WAA6BtB;oBACxD4B,UAAU;oBACVC,MAAM;oBACNC,UAAU;oBACVC,QAAQ;oBACRC,QAAQtC,QAAQuC,GAAG,CAACC,QAAQ,IAAI;gBACpC;gBACA1B,YAAY2B,MAAM,CAAC;gBAEnB,OAAOC,SAASC,QAAQ,CAAC,IAAIvB,IAAIR,aAAagC,MAAM;YACxD;YAEA,OAAOF,SAASb,IAAI,CAAC;gBACjBgB,QAAQ;gBACRC,SAAS;YACb;QACJ;QAEA,OAAOJ,SAASb,IAAI,CAAC;YACjBgB,QAAQ;YACRC,SAAS;QACb;IAEJ;IAEA,OAAOJ,SAASb,IAAI,CAAC;QACjBgB,QAAQ;QACRC,SAAS;IACb;AAEJ,EAAC"}
1
+ {"version":3,"sources":["../../src/handlers/callback.ts"],"sourcesContent":["import {PayloadHandler} from 'payload'\nimport {cookies} from 'next/headers.js'\nimport process from 'node:process'\nimport jwt from 'jsonwebtoken'\nimport {PayloadConfigWithZitadel, ZitadelIdToken, ZitadelOnSuccess} from '../types.js'\n\nexport const callback = (onSuccess: ZitadelOnSuccess): PayloadHandler => async ({payload, query: {code, state}}) => {\n\n const {\n secret,\n admin: {custom: {zitadel: {issuerURL, clientId, callbackURL}}}\n } = payload.config as PayloadConfigWithZitadel\n\n const cookieStore = cookies()\n\n const code_verifier = cookieStore.get('pkce_code_verifier')?.value\n\n if (code_verifier) {\n\n const response = await fetch(new URL(`${issuerURL}/oauth/v2/token`), {\n method: 'POST',\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n code: code as string,\n redirect_uri: callbackURL,\n client_id: clientId,\n code_verifier\n })\n })\n\n if (response.ok) {\n\n const {id_token} = await response.json()\n\n if (id_token) {\n cookieStore.set({\n name: 'id_token',\n value: jwt.sign(jwt.decode(id_token) as ZitadelIdToken, secret),\n httpOnly: true,\n path: '/',\n sameSite: 'strict',\n maxAge: 900,\n secure: process.env.NODE_ENV == 'production'\n })\n cookieStore.delete('pkce_code_verifier')\n\n return onSuccess(new URLSearchParams(atob(state as string ?? '')))\n\n }\n\n return Response.json({\n status: 'error',\n message: 'token could not be retrieved from the response'\n })\n\n }\n\n return Response.json({\n status: 'error',\n message: 'error while communicating with token endpoint'\n })\n\n }\n\n return Response.json({\n status: 'error',\n message: 'code verifier not found (associated http-only cookie is empty)'\n })\n\n}"],"names":["cookies","process","jwt","callback","onSuccess","payload","query","code","state","secret","admin","custom","zitadel","issuerURL","clientId","callbackURL","config","cookieStore","code_verifier","get","value","response","fetch","URL","method","body","URLSearchParams","grant_type","redirect_uri","client_id","ok","id_token","json","set","name","sign","decode","httpOnly","path","sameSite","maxAge","secure","env","NODE_ENV","delete","atob","Response","status","message"],"mappings":"AACA,SAAQA,OAAO,QAAO,kBAAiB;AACvC,OAAOC,aAAa,eAAc;AAClC,OAAOC,SAAS,eAAc;AAG9B,OAAO,MAAMC,WAAW,CAACC,YAAgD,OAAO,EAACC,OAAO,EAAEC,OAAO,EAACC,IAAI,EAAEC,KAAK,EAAC,EAAC;QAE3G,MAAM,EACFC,MAAM,EACNC,OAAO,EAACC,QAAQ,EAACC,SAAS,EAACC,SAAS,EAAEC,QAAQ,EAAEC,WAAW,EAAC,EAAC,EAAC,EACjE,GAAGV,QAAQW,MAAM;QAElB,MAAMC,cAAcjB;QAEpB,MAAMkB,gBAAgBD,YAAYE,GAAG,CAAC,uBAAuBC;QAE7D,IAAIF,eAAe;YAEf,MAAMG,WAAW,MAAMC,MAAM,IAAIC,IAAI,CAAC,EAAEV,UAAU,eAAe,CAAC,GAAG;gBACjEW,QAAQ;gBACRC,MAAM,IAAIC,gBAAgB;oBACtBC,YAAY;oBACZpB,MAAMA;oBACNqB,cAAcb;oBACdc,WAAWf;oBACXI;gBACJ;YACJ;YAEA,IAAIG,SAASS,EAAE,EAAE;gBAEb,MAAM,EAACC,QAAQ,EAAC,GAAG,MAAMV,SAASW,IAAI;gBAEtC,IAAID,UAAU;oBACVd,YAAYgB,GAAG,CAAC;wBACZC,MAAM;wBACNd,OAAOlB,IAAIiC,IAAI,CAACjC,IAAIkC,MAAM,CAACL,WAA6BtB;wBACxD4B,UAAU;wBACVC,MAAM;wBACNC,UAAU;wBACVC,QAAQ;wBACRC,QAAQxC,QAAQyC,GAAG,CAACC,QAAQ,IAAI;oBACpC;oBACA1B,YAAY2B,MAAM,CAAC;oBAEnB,OAAOxC,UAAU,IAAIsB,gBAAgBmB,KAAKrC,SAAmB;gBAEjE;gBAEA,OAAOsC,SAASd,IAAI,CAAC;oBACjBe,QAAQ;oBACRC,SAAS;gBACb;YAEJ;YAEA,OAAOF,SAASd,IAAI,CAAC;gBACjBe,QAAQ;gBACRC,SAAS;YACb;QAEJ;QAEA,OAAOF,SAASd,IAAI,CAAC;YACjBe,QAAQ;YACRC,SAAS;QACb;IAEJ,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/hooks/user.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc;;;;CAQ1B,CAAA"}
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/hooks/user.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc;;;;CAU1B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/user.ts"],"sourcesContent":["'use client'\n\nimport {usePayloadAPI} from '@payloadcms/ui'\n\nexport const useCurrentUser = () => {\n const {data: {user}, isError, isLoading} = usePayloadAPI('/api/users/me')[0]\n\n return {\n user,\n isError,\n isLoading\n }\n}"],"names":["usePayloadAPI","useCurrentUser","data","user","isError","isLoading"],"mappings":"AAAA;AAEA,SAAQA,aAAa,QAAO,iBAAgB;AAE5C,OAAO,MAAMC,iBAAiB;IAC1B,MAAM,EAACC,MAAM,EAACC,IAAI,EAAC,EAAEC,OAAO,EAAEC,SAAS,EAAC,GAAGL,cAAc,gBAAgB,CAAC,EAAE;IAE5E,OAAO;QACHG;QACAC;QACAC;IACJ;AACJ,EAAC"}
1
+ {"version":3,"sources":["../../src/hooks/user.ts"],"sourcesContent":["'use client'\n\nimport {usePayloadAPI} from '@payloadcms/ui'\n\nexport const useCurrentUser = () => {\n\n const {data: {user}, isError, isLoading} = usePayloadAPI('/api/users/me')[0]\n\n return {\n user,\n isError,\n isLoading\n }\n\n}"],"names":["usePayloadAPI","useCurrentUser","data","user","isError","isLoading"],"mappings":"AAAA;AAEA,SAAQA,aAAa,QAAO,iBAAgB;AAE5C,OAAO,MAAMC,iBAAiB;IAE1B,MAAM,EAACC,MAAM,EAACC,IAAI,EAAC,EAAEC,OAAO,EAAEC,SAAS,EAAC,GAAGL,cAAc,gBAAgB,CAAC,EAAE;IAE5E,OAAO;QACHG;QACAC;QACAC;IACJ;AAEJ,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAM5C,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAA;AAE/C,eAAO,MAAM,aAAa,EAAE,iBA8J3B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAmB,iBAAiB,EAAC,MAAM,YAAY,CAAA;AAI9D,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAA;AAE/C,eAAO,MAAM,aAAa,EAAE,iBAqM3B,CAAA"}
package/dist/index.js CHANGED
@@ -1,18 +1,28 @@
1
- import { zitadelStrategy } from './strategy.js';
2
- import { translations } from './translations.js';
1
+ import { cookies } from 'next/headers.js';
3
2
  import { Avatar, LoginButton } from './components/index.js';
3
+ import { COOKIE_ID_TOKEN, DEFAULT_CONFIG, DELETE_ME_USER, ERROR_MESSAGES, ROUTES } from './constants.js';
4
4
  import { authorize, callback } from './handlers/index.js';
5
- import { cookies } from 'next/headers.js';
5
+ import { zitadelStrategy } from './strategy.js';
6
+ import { translations } from './translations.js';
7
+ import { NextResponse } from 'next/server.js';
6
8
  export { getCurrentUser } from './utils/index.js';
7
- export const ZitadelPlugin = ({ associatedIdFieldName = 'idp_id', disableAvatar, disableDefaultLoginButton, strategyName = 'zitadel', label = 'Zitadel', issuerURL, clientId, enableAPI, apiClientId, apiKeyId, apiKey })=>{
8
- if ((issuerURL ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: ISSUER-URL IS EMPTY');
9
- if ((clientId ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: CLIENT-ID IS EMPTY');
9
+ export const ZitadelPlugin = ({ associatedIdFieldName = DEFAULT_CONFIG.associatedIdFieldName, disableAvatar, disableDefaultLoginButton, strategyName = DEFAULT_CONFIG.strategyName, label = DEFAULT_CONFIG.label, issuerURL, clientId, enableAPI, apiClientId, apiKeyId, apiKey, onSuccess })=>{
10
+ if (!issuerURL) throw new Error(ERROR_MESSAGES.issuerURL);
11
+ if (!clientId) throw new Error(ERROR_MESSAGES.clientId);
10
12
  if (enableAPI) {
11
- if ((apiClientId ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: API ENABLED, BUT API-CLIENT-ID IS EMPTY');
12
- if ((apiKeyId ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: API ENABLED, BUT API-KEY-ID IS EMPTY');
13
- if ((apiKey ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: API ENABLED, BUT API-KEY IS EMPTY');
13
+ if (!apiClientId) throw new Error(ERROR_MESSAGES.apiClientId);
14
+ if (!apiKeyId) throw new Error(ERROR_MESSAGES.apiKey);
15
+ if (!apiKey) throw new Error(ERROR_MESSAGES.apiKey);
14
16
  }
15
- return (incomingConfig)=>({
17
+ return (incomingConfig)=>{
18
+ const serverURL = incomingConfig.serverURL ?? 'http://localhost';
19
+ const authSlug = incomingConfig.admin?.user ?? 'users';
20
+ const authBaseURL = `${serverURL}/api/${authSlug}`;
21
+ const defaultOnSuccess = (state)=>NextResponse.redirect([
22
+ serverURL,
23
+ state.get('redirect')
24
+ ].join(''));
25
+ return {
16
26
  ...incomingConfig,
17
27
  admin: {
18
28
  ...incomingConfig.admin,
@@ -32,21 +42,24 @@ export const ZitadelPlugin = ({ associatedIdFieldName = 'idp_id', disableAvatar,
32
42
  zitadel: {
33
43
  issuerURL,
34
44
  clientId,
35
- redirectURL: `${incomingConfig.serverURL ?? 'http://localhost'}/api/${incomingConfig.admin?.user ?? 'users'}/callback`,
36
- label
45
+ label,
46
+ authorizeURL: authBaseURL + ROUTES.authorize,
47
+ callbackURL: authBaseURL + ROUTES.callback
37
48
  }
38
49
  }
39
50
  },
40
- collections: (incomingConfig.collections || []).map((collection)=>({
51
+ collections: (incomingConfig.collections || []).map((collection)=>{
52
+ const authConfig = typeof collection.auth == 'boolean' ? {} : collection.auth;
53
+ return {
41
54
  ...collection,
42
- ...collection.slug == (incomingConfig.admin?.user ?? 'users') ? {
55
+ ...collection.slug == authSlug ? {
43
56
  auth: {
44
- ...typeof collection.auth == 'boolean' ? {} : collection.auth,
57
+ ...authConfig,
45
58
  disableLocalStrategy: true,
46
59
  strategies: [
47
- ...(typeof collection.auth == 'boolean' ? {} : collection.auth)?.strategies ?? [],
60
+ ...authConfig?.strategies ?? [],
48
61
  zitadelStrategy({
49
- authSlug: incomingConfig.admin?.user ?? 'users',
62
+ authSlug,
50
63
  associatedIdFieldName,
51
64
  strategyName: strategyName,
52
65
  issuerURL: issuerURL,
@@ -64,19 +77,38 @@ export const ZitadelPlugin = ({ associatedIdFieldName = 'idp_id', disableAvatar,
64
77
  },
65
78
  hooks: {
66
79
  afterLogout: [
67
- ()=>cookies().delete('id_token')
80
+ ()=>cookies().delete(COOKIE_ID_TOKEN)
81
+ ],
82
+ // current work around (see onInit)
83
+ afterChange: [
84
+ async ({ req })=>{
85
+ const response = await req.payload.find({
86
+ collection: authSlug
87
+ });
88
+ // to minimize unnecessary checks after the first two real users
89
+ if (response.totalDocs == 2) {
90
+ await req.payload.delete({
91
+ collection: authSlug,
92
+ where: {
93
+ [associatedIdFieldName]: {
94
+ equals: DELETE_ME_USER.associatedId
95
+ }
96
+ }
97
+ });
98
+ }
99
+ }
68
100
  ]
69
101
  },
70
102
  endpoints: [
71
103
  {
72
- path: '/authorize',
104
+ path: ROUTES.authorize,
73
105
  method: 'get',
74
106
  handler: authorize
75
107
  },
76
108
  {
77
- path: '/callback',
109
+ path: ROUTES.callback,
78
110
  method: 'get',
79
- handler: callback
111
+ handler: callback(onSuccess ?? defaultOnSuccess)
80
112
  }
81
113
  ],
82
114
  fields: [
@@ -113,21 +145,22 @@ export const ZitadelPlugin = ({ associatedIdFieldName = 'idp_id', disableAvatar,
113
145
  }
114
146
  ]
115
147
  } : {}
116
- })),
117
- //current work around on creating a non-functional first user
148
+ };
149
+ }),
150
+ // current work around on creating a non-functional first user, which will be deleted after first login
118
151
  async onInit (payload) {
119
152
  if (incomingConfig.onInit) await incomingConfig.onInit(payload);
120
153
  const existingUsers = await payload.find({
121
- collection: incomingConfig.admin?.user ?? 'users',
154
+ collection: authSlug,
122
155
  limit: 1
123
156
  });
124
157
  if (existingUsers.docs.length === 0) {
125
158
  await payload.create({
126
- collection: incomingConfig.admin?.user ?? 'users',
159
+ collection: authSlug,
127
160
  data: {
128
- email: 'delete.me@now.com',
129
- password: 'password',
130
- [associatedIdFieldName]: 'DELETE_ME'
161
+ email: DELETE_ME_USER.email,
162
+ password: DELETE_ME_USER.password,
163
+ [associatedIdFieldName]: DELETE_ME_USER.associatedId
131
164
  }
132
165
  });
133
166
  }
@@ -146,7 +179,8 @@ export const ZitadelPlugin = ({ associatedIdFieldName = 'idp_id', disableAvatar,
146
179
  }
147
180
  }
148
181
  }
149
- });
182
+ };
183
+ };
150
184
  };
151
185
 
152
186
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {zitadelStrategy} from './strategy.js'\nimport {ZitadelPluginType} from './types.js'\nimport {translations} from './translations.js'\nimport {Avatar, LoginButton} from './components/index.js'\nimport {authorize, callback} from './handlers/index.js'\nimport {cookies} from 'next/headers.js'\n\nexport {getCurrentUser} from './utils/index.js'\n\nexport const ZitadelPlugin: ZitadelPluginType = ({\n associatedIdFieldName = 'idp_id',\n disableAvatar,\n disableDefaultLoginButton,\n strategyName = 'zitadel',\n label = 'Zitadel',\n issuerURL,\n clientId,\n enableAPI,\n apiClientId,\n apiKeyId,\n apiKey\n }) => {\n if ((issuerURL ?? '').length == 0)\n throw new Error('ZITADEL-PLUGIN: ISSUER-URL IS EMPTY')\n if ((clientId ?? '').length == 0)\n throw new Error('ZITADEL-PLUGIN: CLIENT-ID IS EMPTY')\n if (enableAPI) {\n if ((apiClientId ?? '').length == 0)\n throw new Error('ZITADEL-PLUGIN: API ENABLED, BUT API-CLIENT-ID IS EMPTY')\n if ((apiKeyId ?? '').length == 0)\n throw new Error('ZITADEL-PLUGIN: API ENABLED, BUT API-KEY-ID IS EMPTY')\n if ((apiKey ?? '').length == 0)\n throw new Error('ZITADEL-PLUGIN: API ENABLED, BUT API-KEY IS EMPTY')\n }\n\n return (incomingConfig) => ({\n ...incomingConfig,\n admin: {\n ...incomingConfig.admin,\n ...(disableAvatar ? {} : {avatar: Avatar}),\n components: {\n ...incomingConfig.admin?.components,\n afterLogin: [\n ...incomingConfig.admin?.components?.afterLogin || [],\n ...(disableDefaultLoginButton ? [] : [LoginButton])\n ]\n },\n custom: {\n zitadel: {\n issuerURL,\n clientId,\n redirectURL: `${incomingConfig.serverURL ?? 'http://localhost'}/api/${incomingConfig.admin?.user ?? 'users'}/callback`,\n label\n }\n }\n },\n collections: (incomingConfig.collections || []).map((collection) => ({\n ...collection,\n ...collection.slug == (incomingConfig.admin?.user ?? 'users') ? {\n auth: {\n ...(typeof collection.auth == 'boolean' ? {} : collection.auth),\n disableLocalStrategy: true,\n strategies: [\n ...(typeof collection.auth == 'boolean' ? {} : collection.auth)?.strategies ?? [],\n zitadelStrategy({\n authSlug: incomingConfig.admin?.user ?? 'users',\n associatedIdFieldName,\n strategyName: strategyName,\n issuerURL: issuerURL as string,\n clientId: clientId as string,\n ...(enableAPI ? {\n enableAPI: true,\n apiClientId: apiClientId!,\n apiKeyId: apiClientId!,\n apiKey: apiKey!\n } : {enableAPI: undefined})\n })\n ]\n },\n hooks: {\n afterLogout: [() => cookies().delete('id_token')]\n },\n endpoints: [\n {\n path: '/authorize',\n method: 'get',\n handler: authorize\n },\n {\n path: '/callback',\n method: 'get',\n handler: callback\n }\n ],\n fields: [\n ...collection.fields,\n {\n name: associatedIdFieldName,\n type: 'text',\n admin: {\n readOnly: true\n },\n unique: true,\n required: true\n },\n {\n name: 'email',\n type: 'email',\n admin: {\n readOnly: true\n }\n },\n {\n name: 'name',\n type: 'text',\n admin: {\n readOnly: true\n }\n },\n {\n name: 'image',\n type: 'text',\n admin: {\n readOnly: true\n }\n }\n ]\n } : {}\n })),\n\n //current work around on creating a non-functional first user\n async onInit(payload) {\n if (incomingConfig.onInit)\n await incomingConfig.onInit(payload)\n\n const existingUsers = await payload.find({\n collection: incomingConfig.admin?.user ?? 'users',\n limit: 1\n })\n\n if (existingUsers.docs.length === 0) {\n await payload.create({\n collection: incomingConfig.admin?.user ?? 'users',\n data: {\n email: 'delete.me@now.com',\n password: 'password',\n [associatedIdFieldName]: 'DELETE_ME'\n }\n })\n }\n },\n\n i18n: {\n ...incomingConfig.i18n,\n translations: {\n ...incomingConfig.i18n?.translations,\n de: {\n ...incomingConfig.i18n?.translations?.de,\n ...translations.de\n },\n en: {\n ...incomingConfig.i18n?.translations?.en,\n ...translations.en\n }\n }\n }\n })\n}"],"names":["zitadelStrategy","translations","Avatar","LoginButton","authorize","callback","cookies","getCurrentUser","ZitadelPlugin","associatedIdFieldName","disableAvatar","disableDefaultLoginButton","strategyName","label","issuerURL","clientId","enableAPI","apiClientId","apiKeyId","apiKey","length","Error","incomingConfig","admin","avatar","components","afterLogin","custom","zitadel","redirectURL","serverURL","user","collections","map","collection","slug","auth","disableLocalStrategy","strategies","authSlug","undefined","hooks","afterLogout","delete","endpoints","path","method","handler","fields","name","type","readOnly","unique","required","onInit","payload","existingUsers","find","limit","docs","create","data","email","password","i18n","de","en"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {cookies} from 'next/headers.js'\nimport {Avatar, LoginButton} from './components/index.js'\nimport {COOKIE_ID_TOKEN, DEFAULT_CONFIG, DELETE_ME_USER, ERROR_MESSAGES, ROUTES} from './constants.js'\nimport {authorize, callback} from './handlers/index.js'\nimport {zitadelStrategy} from './strategy.js'\nimport {ZitadelOnSuccess, ZitadelPluginType} from './types.js'\nimport {translations} from './translations.js'\nimport {NextResponse} from 'next/server.js'\n\nexport {getCurrentUser} from './utils/index.js'\n\nexport const ZitadelPlugin: ZitadelPluginType = ({\n associatedIdFieldName = DEFAULT_CONFIG.associatedIdFieldName,\n disableAvatar,\n disableDefaultLoginButton,\n strategyName = DEFAULT_CONFIG.strategyName,\n label = DEFAULT_CONFIG.label,\n issuerURL,\n clientId,\n enableAPI,\n apiClientId,\n apiKeyId,\n apiKey,\n onSuccess\n }) => {\n\n if (!issuerURL)\n throw new Error(ERROR_MESSAGES.issuerURL)\n if (!clientId)\n throw new Error(ERROR_MESSAGES.clientId)\n if (enableAPI) {\n if (!apiClientId)\n throw new Error(ERROR_MESSAGES.apiClientId)\n if (!apiKeyId)\n throw new Error(ERROR_MESSAGES.apiKey)\n if (!apiKey)\n throw new Error(ERROR_MESSAGES.apiKey)\n }\n\n return (incomingConfig) => {\n\n const serverURL = incomingConfig.serverURL ?? 'http://localhost'\n\n const authSlug = incomingConfig.admin?.user ?? 'users'\n\n const authBaseURL = `${serverURL}/api/${authSlug}`\n\n const defaultOnSuccess: ZitadelOnSuccess = (state) =>\n NextResponse.redirect([serverURL, state.get('redirect')].join(''))\n\n return {\n ...incomingConfig,\n admin: {\n ...incomingConfig.admin,\n ...(disableAvatar ? {} : {avatar: Avatar}),\n components: {\n ...incomingConfig.admin?.components,\n afterLogin: [\n ...incomingConfig.admin?.components?.afterLogin || [],\n ...(disableDefaultLoginButton ? [] : [LoginButton])\n ]\n },\n custom: {\n zitadel: {\n issuerURL,\n clientId,\n label,\n authorizeURL: authBaseURL + ROUTES.authorize,\n callbackURL: authBaseURL + ROUTES.callback\n }\n }\n },\n collections: (incomingConfig.collections || []).map((collection) => {\n\n const authConfig = typeof collection.auth == 'boolean' ? {} : collection.auth\n\n return {\n ...collection,\n ...collection.slug == authSlug ? {\n auth: {\n ...authConfig,\n disableLocalStrategy: true,\n strategies: [\n ...authConfig?.strategies ?? [],\n zitadelStrategy({\n authSlug,\n associatedIdFieldName,\n strategyName: strategyName,\n issuerURL: issuerURL as string,\n clientId: clientId as string,\n ...(enableAPI ? {\n enableAPI: true,\n apiClientId: apiClientId!,\n apiKeyId: apiClientId!,\n apiKey: apiKey!\n } : {enableAPI: undefined})\n })\n ]\n },\n hooks: {\n\n afterLogout: [() => cookies().delete(COOKIE_ID_TOKEN)],\n\n // current work around (see onInit)\n afterChange: [async ({req}) => {\n const response = await req.payload.find({collection: authSlug})\n // to minimize unnecessary checks after the first two real users\n if (response.totalDocs == 2) {\n await req.payload.delete({\n collection: authSlug,\n where: {\n [associatedIdFieldName]: {\n equals: DELETE_ME_USER.associatedId\n }\n }\n })\n }\n }]\n\n },\n endpoints: [\n {\n path: ROUTES.authorize,\n method: 'get',\n handler: authorize\n },\n {\n path: ROUTES.callback,\n method: 'get',\n handler: callback(onSuccess ?? defaultOnSuccess)\n }\n ],\n fields: [\n ...collection.fields,\n {\n name: associatedIdFieldName,\n type: 'text',\n admin: {\n readOnly: true\n },\n unique: true,\n required: true\n },\n {\n name: 'email',\n type: 'email',\n admin: {\n readOnly: true\n }\n },\n {\n name: 'name',\n type: 'text',\n admin: {\n readOnly: true\n }\n },\n {\n name: 'image',\n type: 'text',\n admin: {\n readOnly: true\n }\n }\n ]\n } : {}\n }\n }),\n\n // current work around on creating a non-functional first user, which will be deleted after first login\n async onInit(payload) {\n if (incomingConfig.onInit)\n await incomingConfig.onInit(payload)\n\n const existingUsers = await payload.find({\n collection: authSlug,\n limit: 1\n })\n\n if (existingUsers.docs.length === 0) {\n await payload.create({\n collection: authSlug,\n data: {\n email: DELETE_ME_USER.email,\n password: DELETE_ME_USER.password,\n [associatedIdFieldName]: DELETE_ME_USER.associatedId\n }\n })\n }\n },\n\n i18n: {\n ...incomingConfig.i18n,\n translations: {\n ...incomingConfig.i18n?.translations,\n de: {\n ...incomingConfig.i18n?.translations?.de,\n ...translations.de\n },\n en: {\n ...incomingConfig.i18n?.translations?.en,\n ...translations.en\n }\n }\n }\n }\n }\n\n}"],"names":["cookies","Avatar","LoginButton","COOKIE_ID_TOKEN","DEFAULT_CONFIG","DELETE_ME_USER","ERROR_MESSAGES","ROUTES","authorize","callback","zitadelStrategy","translations","NextResponse","getCurrentUser","ZitadelPlugin","associatedIdFieldName","disableAvatar","disableDefaultLoginButton","strategyName","label","issuerURL","clientId","enableAPI","apiClientId","apiKeyId","apiKey","onSuccess","Error","incomingConfig","serverURL","authSlug","admin","user","authBaseURL","defaultOnSuccess","state","redirect","get","join","avatar","components","afterLogin","custom","zitadel","authorizeURL","callbackURL","collections","map","collection","authConfig","auth","slug","disableLocalStrategy","strategies","undefined","hooks","afterLogout","delete","afterChange","req","response","payload","find","totalDocs","where","equals","associatedId","endpoints","path","method","handler","fields","name","type","readOnly","unique","required","onInit","existingUsers","limit","docs","length","create","data","email","password","i18n","de","en"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../src/strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,mBAAmB,EAAC,MAAM,YAAY,CAAA;AAI9D,eAAO,MAAM,eAAe,EAAE,mBA4F5B,CAAA"}
1
+ {"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../src/strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,mBAAmB,EAAC,MAAM,YAAY,CAAA;AAI9D,eAAO,MAAM,eAAe,EAAE,mBA6F5B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/strategy.ts"],"sourcesContent":["import {ZitadelIdToken, ZitadelStrategyType} from './types.js'\nimport jwt from 'jsonwebtoken'\nimport {cookies} from 'next/headers.js'\n\nexport const zitadelStrategy: ZitadelStrategyType = ({\n authSlug,\n associatedIdFieldName,\n strategyName,\n issuerURL,\n enableAPI,\n apiClientId,\n apiKeyId,\n apiKey\n }) => ({\n name: strategyName,\n authenticate: async ({headers, payload}) => {\n let id, idp_id, id_token\n\n const cookieStore = cookies()\n\n if (enableAPI) {\n // in case of incoming API call from the app\n const authHeader = headers.get('Authorization')\n if (authHeader?.includes('Bearer')) {\n const introspect = await fetch(`${issuerURL}/oauth/v2/introspect`, {\n method: 'post',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams({\n 'client_assertion_type': 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',\n 'client_assertion': jwt.sign({}, apiKey, {\n algorithm: 'RS256',\n audience: issuerURL,\n expiresIn: '1h',\n issuer: apiClientId,\n keyid: apiKeyId,\n subject: apiClientId\n }),\n 'token': authHeader.split(' ')[1]\n })\n })\n if (introspect.ok) {\n const data = await introspect.json()\n if (data?.active) {\n idp_id = data.sub\n }\n }\n }\n }\n\n // in case of normal browsing\n if (!idp_id && cookieStore.has('id_token')) {\n id_token = jwt.verify(cookieStore.get('id_token')?.value ?? '', payload.config.secret) as ZitadelIdToken\n idp_id = id_token.sub\n }\n\n // search for associated user; if not found, create one\n if (idp_id) {\n const {docs} = await payload.find({\n collection: authSlug,\n where: {\n [associatedIdFieldName]: {\n equals: idp_id\n }\n }\n })\n id = docs.length ? docs[0].id : (await payload.create({\n collection: authSlug,\n data: {\n [associatedIdFieldName]: idp_id\n }\n })).id\n }\n\n // update user information if possible\n if (id && id_token) {\n await payload.update({\n collection: authSlug,\n id,\n data: {\n email: id_token.email,\n name: id_token.name,\n image: id_token.picture\n }\n })\n }\n\n return {\n user: id ? {\n collection: authSlug,\n id\n } : null\n }\n\n }\n})"],"names":["jwt","cookies","zitadelStrategy","authSlug","associatedIdFieldName","strategyName","issuerURL","enableAPI","apiClientId","apiKeyId","apiKey","name","authenticate","headers","payload","id","idp_id","id_token","cookieStore","authHeader","get","includes","introspect","fetch","method","body","URLSearchParams","sign","algorithm","audience","expiresIn","issuer","keyid","subject","split","ok","data","json","active","sub","has","verify","value","config","secret","docs","find","collection","where","equals","length","create","update","email","image","picture","user"],"mappings":"AACA,OAAOA,SAAS,eAAc;AAC9B,SAAQC,OAAO,QAAO,kBAAiB;AAEvC,OAAO,MAAMC,kBAAuC,CAAC,EACIC,QAAQ,EACRC,qBAAqB,EACrBC,YAAY,EACZC,SAAS,EACTC,SAAS,EACTC,WAAW,EACXC,QAAQ,EACRC,MAAM,EACT,GAAM,CAAA;QACxDC,MAAMN;QACNO,cAAc,OAAO,EAACC,OAAO,EAAEC,OAAO,EAAC;YACnC,IAAIC,IAAIC,QAAQC;YAEhB,MAAMC,cAAcjB;YAEpB,IAAIM,WAAW;gBACX,4CAA4C;gBAC5C,MAAMY,aAAaN,QAAQO,GAAG,CAAC;gBAC/B,IAAID,YAAYE,SAAS,WAAW;oBAChC,MAAMC,aAAa,MAAMC,MAAM,CAAC,EAAEjB,UAAU,oBAAoB,CAAC,EAAE;wBAC/DkB,QAAQ;wBACRX,SAAS;4BACL,gBAAgB;wBACpB;wBACAY,MAAM,IAAIC,gBAAgB;4BACtB,yBAAyB;4BACzB,oBAAoB1B,IAAI2B,IAAI,CAAC,CAAC,GAAGjB,QAAQ;gCACrCkB,WAAW;gCACXC,UAAUvB;gCACVwB,WAAW;gCACXC,QAAQvB;gCACRwB,OAAOvB;gCACPwB,SAASzB;4BACb;4BACA,SAASW,WAAWe,KAAK,CAAC,IAAI,CAAC,EAAE;wBACrC;oBACJ;oBACA,IAAIZ,WAAWa,EAAE,EAAE;wBACf,MAAMC,OAAO,MAAMd,WAAWe,IAAI;wBAClC,IAAID,MAAME,QAAQ;4BACdtB,SAASoB,KAAKG,GAAG;wBACrB;oBACJ;gBACJ;YACJ;YAEA,6BAA6B;YAC7B,IAAI,CAACvB,UAAUE,YAAYsB,GAAG,CAAC,aAAa;gBACxCvB,WAAWjB,IAAIyC,MAAM,CAACvB,YAAYE,GAAG,CAAC,aAAasB,SAAS,IAAI5B,QAAQ6B,MAAM,CAACC,MAAM;gBACrF5B,SAASC,SAASsB,GAAG;YACzB;YAEA,uDAAuD;YACvD,IAAIvB,QAAQ;gBACR,MAAM,EAAC6B,IAAI,EAAC,GAAG,MAAM/B,QAAQgC,IAAI,CAAC;oBAC9BC,YAAY5C;oBACZ6C,OAAO;wBACH,CAAC5C,sBAAsB,EAAE;4BACrB6C,QAAQjC;wBACZ;oBACJ;gBACJ;gBACAD,KAAK8B,KAAKK,MAAM,GAAGL,IAAI,CAAC,EAAE,CAAC9B,EAAE,GAAG,AAAC,CAAA,MAAMD,QAAQqC,MAAM,CAAC;oBAClDJ,YAAY5C;oBACZiC,MAAM;wBACF,CAAChC,sBAAsB,EAAEY;oBAC7B;gBACJ,EAAC,EAAGD,EAAE;YACV;YAEA,sCAAsC;YACtC,IAAIA,MAAME,UAAU;gBAChB,MAAMH,QAAQsC,MAAM,CAAC;oBACjBL,YAAY5C;oBACZY;oBACAqB,MAAM;wBACFiB,OAAOpC,SAASoC,KAAK;wBACrB1C,MAAMM,SAASN,IAAI;wBACnB2C,OAAOrC,SAASsC,OAAO;oBAC3B;gBACJ;YACJ;YAEA,OAAO;gBACHC,MAAMzC,KAAK;oBACPgC,YAAY5C;oBACZY;gBACJ,IAAI;YACR;QAEJ;IACJ,CAAA,EAAE"}
1
+ {"version":3,"sources":["../src/strategy.ts"],"sourcesContent":["import {ZitadelIdToken, ZitadelStrategyType} from './types.js'\nimport jwt from 'jsonwebtoken'\nimport {cookies} from 'next/headers.js'\n\nexport const zitadelStrategy: ZitadelStrategyType = ({\n authSlug,\n associatedIdFieldName,\n strategyName,\n issuerURL,\n enableAPI,\n apiClientId,\n apiKeyId,\n apiKey\n }) => ({\n name: strategyName,\n authenticate: async ({headers, payload}) => {\n\n let id, idp_id, id_token\n\n const cookieStore = cookies()\n\n if (enableAPI) {\n // in case of incoming API call from the app\n const authHeader = headers.get('Authorization')\n if (authHeader?.includes('Bearer')) {\n const introspect = await fetch(`${issuerURL}/oauth/v2/introspect`, {\n method: 'post',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams({\n 'client_assertion_type': 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',\n 'client_assertion': jwt.sign({}, apiKey, {\n algorithm: 'RS256',\n audience: issuerURL,\n expiresIn: '1h',\n issuer: apiClientId,\n keyid: apiKeyId,\n subject: apiClientId\n }),\n 'token': authHeader.split(' ')[1]\n })\n })\n if (introspect.ok) {\n const data = await introspect.json()\n if (data?.active) {\n idp_id = data.sub\n }\n }\n }\n }\n\n // in case of normal browsing\n if (!idp_id && cookieStore.has('id_token')) {\n id_token = jwt.verify(cookieStore.get('id_token')?.value ?? '', payload.config.secret) as ZitadelIdToken\n idp_id = id_token.sub\n }\n\n // search for associated user; if not found, create one\n if (idp_id) {\n const {docs} = await payload.find({\n collection: authSlug,\n where: {\n [associatedIdFieldName]: {\n equals: idp_id\n }\n }\n })\n id = docs.length ? docs[0].id : (await payload.create({\n collection: authSlug,\n data: {\n [associatedIdFieldName]: idp_id\n }\n })).id\n }\n\n // update user information if possible\n if (id && id_token) {\n await payload.update({\n collection: authSlug,\n id,\n data: {\n email: id_token.email,\n name: id_token.name,\n image: id_token.picture\n }\n })\n }\n\n return {\n user: id ? {\n collection: authSlug,\n id\n } : null\n }\n\n }\n})"],"names":["jwt","cookies","zitadelStrategy","authSlug","associatedIdFieldName","strategyName","issuerURL","enableAPI","apiClientId","apiKeyId","apiKey","name","authenticate","headers","payload","id","idp_id","id_token","cookieStore","authHeader","get","includes","introspect","fetch","method","body","URLSearchParams","sign","algorithm","audience","expiresIn","issuer","keyid","subject","split","ok","data","json","active","sub","has","verify","value","config","secret","docs","find","collection","where","equals","length","create","update","email","image","picture","user"],"mappings":"AACA,OAAOA,SAAS,eAAc;AAC9B,SAAQC,OAAO,QAAO,kBAAiB;AAEvC,OAAO,MAAMC,kBAAuC,CAAC,EACIC,QAAQ,EACRC,qBAAqB,EACrBC,YAAY,EACZC,SAAS,EACTC,SAAS,EACTC,WAAW,EACXC,QAAQ,EACRC,MAAM,EACT,GAAM,CAAA;QACxDC,MAAMN;QACNO,cAAc,OAAO,EAACC,OAAO,EAAEC,OAAO,EAAC;YAEnC,IAAIC,IAAIC,QAAQC;YAEhB,MAAMC,cAAcjB;YAEpB,IAAIM,WAAW;gBACX,4CAA4C;gBAC5C,MAAMY,aAAaN,QAAQO,GAAG,CAAC;gBAC/B,IAAID,YAAYE,SAAS,WAAW;oBAChC,MAAMC,aAAa,MAAMC,MAAM,CAAC,EAAEjB,UAAU,oBAAoB,CAAC,EAAE;wBAC/DkB,QAAQ;wBACRX,SAAS;4BACL,gBAAgB;wBACpB;wBACAY,MAAM,IAAIC,gBAAgB;4BACtB,yBAAyB;4BACzB,oBAAoB1B,IAAI2B,IAAI,CAAC,CAAC,GAAGjB,QAAQ;gCACrCkB,WAAW;gCACXC,UAAUvB;gCACVwB,WAAW;gCACXC,QAAQvB;gCACRwB,OAAOvB;gCACPwB,SAASzB;4BACb;4BACA,SAASW,WAAWe,KAAK,CAAC,IAAI,CAAC,EAAE;wBACrC;oBACJ;oBACA,IAAIZ,WAAWa,EAAE,EAAE;wBACf,MAAMC,OAAO,MAAMd,WAAWe,IAAI;wBAClC,IAAID,MAAME,QAAQ;4BACdtB,SAASoB,KAAKG,GAAG;wBACrB;oBACJ;gBACJ;YACJ;YAEA,6BAA6B;YAC7B,IAAI,CAACvB,UAAUE,YAAYsB,GAAG,CAAC,aAAa;gBACxCvB,WAAWjB,IAAIyC,MAAM,CAACvB,YAAYE,GAAG,CAAC,aAAasB,SAAS,IAAI5B,QAAQ6B,MAAM,CAACC,MAAM;gBACrF5B,SAASC,SAASsB,GAAG;YACzB;YAEA,uDAAuD;YACvD,IAAIvB,QAAQ;gBACR,MAAM,EAAC6B,IAAI,EAAC,GAAG,MAAM/B,QAAQgC,IAAI,CAAC;oBAC9BC,YAAY5C;oBACZ6C,OAAO;wBACH,CAAC5C,sBAAsB,EAAE;4BACrB6C,QAAQjC;wBACZ;oBACJ;gBACJ;gBACAD,KAAK8B,KAAKK,MAAM,GAAGL,IAAI,CAAC,EAAE,CAAC9B,EAAE,GAAG,AAAC,CAAA,MAAMD,QAAQqC,MAAM,CAAC;oBAClDJ,YAAY5C;oBACZiC,MAAM;wBACF,CAAChC,sBAAsB,EAAEY;oBAC7B;gBACJ,EAAC,EAAGD,EAAE;YACV;YAEA,sCAAsC;YACtC,IAAIA,MAAME,UAAU;gBAChB,MAAMH,QAAQsC,MAAM,CAAC;oBACjBL,YAAY5C;oBACZY;oBACAqB,MAAM;wBACFiB,OAAOpC,SAASoC,KAAK;wBACrB1C,MAAMM,SAASN,IAAI;wBACnB2C,OAAOrC,SAASsC,OAAO;oBAC3B;gBACJ;YACJ;YAEA,OAAO;gBACHC,MAAMzC,KAAK;oBACPgC,YAAY5C;oBACZY;gBACJ,IAAI;YACR;QAEJ;IACJ,CAAA,EAAE"}
package/dist/types.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- import { AuthStrategy, Config } from 'payload';
2
- export type ZitadelPluginProps = {
3
- disableAvatar?: true | undefined;
4
- disableDefaultLoginButton?: true | undefined;
5
- defaultLoginButtonTitle?: string;
6
- label?: string;
7
- } & Partial<ZitadelStrategyProps>;
8
- export type ZitadelPluginType = (props: ZitadelPluginProps) => (config: Config) => Config;
1
+ import { AuthStrategy, Config, PayloadHandler, SanitizedConfig } from 'payload';
2
+ export type ZitadelPluginProps = Partial<{
3
+ disableAvatar: true;
4
+ disableDefaultLoginButton: true;
5
+ defaultLoginButtonTitle: string;
6
+ label: string;
7
+ onSuccess: ZitadelOnSuccess;
8
+ }> & Partial<ZitadelStrategyProps>;
9
+ export type ZitadelPluginType = (props: ZitadelPluginProps) => (config: Config) => PayloadConfigWithZitadel;
9
10
  export type ZitadelAPIProps = {
10
11
  enableAPI: true;
11
12
  apiClientId: string;
@@ -29,4 +30,18 @@ export type ZitadelIdToken = Partial<{
29
30
  email: string;
30
31
  picture: string;
31
32
  }>;
33
+ export type ZitadelOnSuccess = (state: URLSearchParams) => ReturnType<PayloadHandler>;
34
+ export type PayloadConfigWithZitadel = (Config | SanitizedConfig) & {
35
+ admin: {
36
+ custom: {
37
+ zitadel: {
38
+ issuerURL: string;
39
+ clientId: string;
40
+ label: string;
41
+ authorizeURL: string;
42
+ callbackURL: string;
43
+ };
44
+ };
45
+ };
46
+ };
32
47
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,MAAM,EAAC,MAAM,SAAS,CAAA;AAE5C,MAAM,MAAM,kBAAkB,GAAG;IAC7B,aAAa,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;IAChC,yBAAyB,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;IAC5C,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;AAEjC,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAA;AAEzF,MAAM,MAAM,eAAe,GAAG;IAC1B,SAAS,EAAE,IAAI,CAAA;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAA;CACnB,GAAG;IACA,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;CACjC,GAAG,CAAC,eAAe,GAAG;IACnB,SAAS,CAAC,EAAE,SAAS,CAAA;CACxB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAA;AAE7B,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,oBAAoB,KAAK,YAAY,CAAA;AAE/E,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAA;CAClB,CAAC,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAC,MAAM,SAAS,CAAA;AAE7E,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC;IACrC,aAAa,EAAE,IAAI,CAAA;IACnB,yBAAyB,EAAE,IAAI,CAAA;IAC/B,uBAAuB,EAAE,MAAM,CAAA;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,gBAAgB,CAAA;CAC9B,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;AAElC,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,CAAC,MAAM,EAAE,MAAM,KAAK,wBAAwB,CAAA;AAE3G,MAAM,MAAM,eAAe,GAAG;IAC1B,SAAS,EAAE,IAAI,CAAA;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAA;CACnB,GAAG;IACA,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;CACjC,GAAG,CAAC,eAAe,GAAG;IACnB,SAAS,CAAC,EAAE,SAAS,CAAA;CACxB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAA;AAE7B,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,oBAAoB,KAAK,YAAY,CAAA;AAE/E,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAA;CAClB,CAAC,CAAA;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,UAAU,CAAC,cAAc,CAAC,CAAA;AAErF,MAAM,MAAM,wBAAwB,GAAG,CAAC,MAAM,GAAG,eAAe,CAAC,GAAG;IAChE,KAAK,EAAE;QACH,MAAM,EAAE;YACJ,OAAO,EAAE;gBACL,SAAS,EAAE,MAAM,CAAA;gBACjB,QAAQ,EAAE,MAAM,CAAA;gBAChB,KAAK,EAAE,MAAM,CAAA;gBACb,YAAY,EAAE,MAAM,CAAA;gBACpB,WAAW,EAAE,MAAM,CAAA;aACtB,CAAA;SACJ,CAAA;KACJ,CAAA;CACJ,CAAA"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import {AuthStrategy, Config} from 'payload'\n\nexport type ZitadelPluginProps = {\n disableAvatar?: true | undefined\n disableDefaultLoginButton?: true | undefined\n defaultLoginButtonTitle?: string\n label?: string\n} & Partial<ZitadelStrategyProps>\n\nexport type ZitadelPluginType = (props: ZitadelPluginProps) => (config: Config) => Config\n\nexport type ZitadelAPIProps = {\n enableAPI: true\n apiClientId: string,\n apiKeyId: string,\n apiKey: string\n}\n\nexport type ZitadelStrategyProps = {\n strategyName: string,\n issuerURL: string,\n clientId: string\n} & {\n authSlug: string,\n associatedIdFieldName: string,\n} & (ZitadelAPIProps | {\n enableAPI?: undefined\n} & Partial<ZitadelAPIProps>)\n\nexport type ZitadelStrategyType = (props: ZitadelStrategyProps) => AuthStrategy\n\nexport type ZitadelIdToken = Partial<{\n sub: string,\n name: string,\n email: string,\n picture: string\n}>\n"],"names":[],"mappings":"AA+BA,WAKE"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import {AuthStrategy, Config, PayloadHandler, SanitizedConfig} from 'payload'\n\nexport type ZitadelPluginProps = Partial<{\n disableAvatar: true\n disableDefaultLoginButton: true\n defaultLoginButtonTitle: string\n label: string\n onSuccess: ZitadelOnSuccess\n}> & Partial<ZitadelStrategyProps>\n\nexport type ZitadelPluginType = (props: ZitadelPluginProps) => (config: Config) => PayloadConfigWithZitadel\n\nexport type ZitadelAPIProps = {\n enableAPI: true\n apiClientId: string,\n apiKeyId: string,\n apiKey: string\n}\n\nexport type ZitadelStrategyProps = {\n strategyName: string,\n issuerURL: string,\n clientId: string\n} & {\n authSlug: string,\n associatedIdFieldName: string,\n} & (ZitadelAPIProps | {\n enableAPI?: undefined\n} & Partial<ZitadelAPIProps>)\n\nexport type ZitadelStrategyType = (props: ZitadelStrategyProps) => AuthStrategy\n\nexport type ZitadelIdToken = Partial<{\n sub: string,\n name: string,\n email: string,\n picture: string\n}>\n\nexport type ZitadelOnSuccess = (state: URLSearchParams) => ReturnType<PayloadHandler>\n\nexport type PayloadConfigWithZitadel = (Config | SanitizedConfig) & {\n admin: {\n custom: {\n zitadel: {\n issuerURL: string\n clientId: string\n label: string\n authorizeURL: string\n callbackURL: string\n }\n }\n }\n}"],"names":[],"mappings":"AAyCA,WAYC"}
@@ -1 +1 @@
1
- {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/utils/user.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,eAAe,EAAC,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,cAAc,eAAoB;IAAE,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,CAAA;CAAE,6EAIlF,CAAA"}
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/utils/user.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,eAAe,EAAC,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,cAAc,eAAoB;IAAE,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,CAAA;CAAE,6EAQlF,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/user.ts"],"sourcesContent":["import {getPayloadHMR} from '@payloadcms/next/utilities'\nimport {headers} from 'next/headers.js'\nimport {SanitizedConfig} from 'payload'\n\nexport const getCurrentUser = async ({config}: { config: Promise<SanitizedConfig> }) => {\n const payload = await getPayloadHMR({config})\n const {user} = await payload.auth({headers: headers()})\n return user ? await payload.findByID({...user}) : null\n}"],"names":["getPayloadHMR","headers","getCurrentUser","config","payload","user","auth","findByID"],"mappings":"AAAA,SAAQA,aAAa,QAAO,6BAA4B;AACxD,SAAQC,OAAO,QAAO,kBAAiB;AAGvC,OAAO,MAAMC,iBAAiB,OAAO,EAACC,MAAM,EAAuC;IAC/E,MAAMC,UAAU,MAAMJ,cAAc;QAACG;IAAM;IAC3C,MAAM,EAACE,IAAI,EAAC,GAAG,MAAMD,QAAQE,IAAI,CAAC;QAACL,SAASA;IAAS;IACrD,OAAOI,OAAO,MAAMD,QAAQG,QAAQ,CAAC;QAAC,GAAGF,IAAI;IAAA,KAAK;AACtD,EAAC"}
1
+ {"version":3,"sources":["../../src/utils/user.ts"],"sourcesContent":["import {getPayloadHMR} from '@payloadcms/next/utilities'\nimport {headers} from 'next/headers.js'\nimport {SanitizedConfig} from 'payload'\n\nexport const getCurrentUser = async ({config}: { config: Promise<SanitizedConfig> }) => {\n\n const payload = await getPayloadHMR({config})\n\n const {user} = await payload.auth({headers: headers()})\n\n return user ? await payload.findByID({...user}) : null\n\n}"],"names":["getPayloadHMR","headers","getCurrentUser","config","payload","user","auth","findByID"],"mappings":"AAAA,SAAQA,aAAa,QAAO,6BAA4B;AACxD,SAAQC,OAAO,QAAO,kBAAiB;AAGvC,OAAO,MAAMC,iBAAiB,OAAO,EAACC,MAAM,EAAuC;IAE/E,MAAMC,UAAU,MAAMJ,cAAc;QAACG;IAAM;IAE3C,MAAM,EAACE,IAAI,EAAC,GAAG,MAAMD,QAAQE,IAAI,CAAC;QAACL,SAASA;IAAS;IAErD,OAAOI,OAAO,MAAMD,QAAQG,QAAQ,CAAC;QAAC,GAAGF,IAAI;IAAA,KAAK;AAEtD,EAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payload-zitadel-plugin",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "plugin for Payload CMS, which enables authentication via Zitadel IdP",
5
5
  "type": "module",
6
6
  "license": "MIT",