payload-zitadel-plugin 0.1.6 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +52 -57
  2. package/dist/components/Avatar.d.ts +3 -0
  3. package/dist/components/Avatar.d.ts.map +1 -0
  4. package/dist/components/{Avatar/index.js → Avatar.js} +13 -13
  5. package/dist/components/Avatar.js.map +1 -0
  6. package/dist/components/LoginButton.d.ts +3 -0
  7. package/dist/components/LoginButton.d.ts.map +1 -0
  8. package/dist/components/LoginButton.js +19 -0
  9. package/dist/components/LoginButton.js.map +1 -0
  10. package/dist/components/index.d.ts +2 -3
  11. package/dist/components/index.d.ts.map +1 -1
  12. package/dist/components/index.js +2 -3
  13. package/dist/components/index.js.map +1 -1
  14. package/dist/handlers/authorize.d.ts +3 -0
  15. package/dist/handlers/authorize.d.ts.map +1 -0
  16. package/dist/handlers/authorize.js +28 -0
  17. package/dist/handlers/authorize.js.map +1 -0
  18. package/dist/handlers/callback.d.ts +3 -0
  19. package/dist/handlers/callback.d.ts.map +1 -0
  20. package/dist/handlers/callback.js +50 -0
  21. package/dist/handlers/callback.js.map +1 -0
  22. package/dist/handlers/index.d.ts +3 -0
  23. package/dist/handlers/index.d.ts.map +1 -0
  24. package/dist/handlers/index.js +4 -0
  25. package/dist/handlers/index.js.map +1 -0
  26. package/dist/hooks/index.d.ts +2 -0
  27. package/dist/hooks/index.d.ts.map +1 -0
  28. package/dist/hooks/index.js +3 -0
  29. package/dist/hooks/index.js.map +1 -0
  30. package/dist/hooks/user.d.ts +6 -0
  31. package/dist/hooks/user.d.ts.map +1 -0
  32. package/dist/hooks/user.js +12 -0
  33. package/dist/hooks/user.js.map +1 -0
  34. package/dist/index.d.ts +3 -2
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +132 -135
  37. package/dist/index.js.map +1 -1
  38. package/dist/strategy.d.ts.map +1 -1
  39. package/dist/strategy.js +27 -20
  40. package/dist/strategy.js.map +1 -1
  41. package/dist/translations.d.ts +2 -2
  42. package/dist/translations.js +4 -4
  43. package/dist/translations.js.map +1 -1
  44. package/dist/types.d.ts +14 -26
  45. package/dist/types.d.ts.map +1 -1
  46. package/dist/types.js.map +1 -1
  47. package/dist/utils/index.d.ts +2 -0
  48. package/dist/utils/index.d.ts.map +1 -0
  49. package/dist/utils/index.js +3 -0
  50. package/dist/utils/index.js.map +1 -0
  51. package/dist/utils/user.d.ts +5 -0
  52. package/dist/utils/user.d.ts.map +1 -0
  53. package/dist/utils/user.js +15 -0
  54. package/dist/utils/user.js.map +1 -0
  55. package/package.json +17 -12
  56. package/dist/components/Avatar/index.d.ts +0 -5
  57. package/dist/components/Avatar/index.d.ts.map +0 -1
  58. package/dist/components/Avatar/index.js.map +0 -1
  59. package/dist/components/LoginButton/button.d.ts +0 -6
  60. package/dist/components/LoginButton/button.d.ts.map +0 -1
  61. package/dist/components/LoginButton/button.js +0 -19
  62. package/dist/components/LoginButton/button.js.map +0 -1
  63. package/dist/components/LoginButton/index.d.ts +0 -6
  64. package/dist/components/LoginButton/index.d.ts.map +0 -1
  65. package/dist/components/LoginButton/index.js +0 -8
  66. package/dist/components/LoginButton/index.js.map +0 -1
  67. package/dist/components/Session/index.d.ts +0 -4
  68. package/dist/components/Session/index.d.ts.map +0 -1
  69. package/dist/components/Session/index.js +0 -6
  70. package/dist/components/Session/index.js.map +0 -1
  71. package/dist/options.d.ts +0 -3
  72. package/dist/options.d.ts.map +0 -1
  73. package/dist/options.js +0 -54
  74. package/dist/options.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,155 +1,152 @@
1
- import NextAuth, { getServerSession } from 'next-auth';
2
- import { signOut } from 'next-auth/react';
3
- import { authOptions } from './options.js';
4
1
  import { zitadelStrategy } from './strategy.js';
5
2
  import { translations } from './translations.js';
6
- import { Avatar, LoginButton, Session } from './components/index.js';
7
- export const ZitadelPluginProvider = ({ authSlug = 'users', associatedIdFieldName = 'idp_id', disableAvatar, disableLocalStrategy, disableDefaultLoginButton, internalProviderName = 'zitadel', externalProviderName = 'ZITADEL', issuerUrl, clientId, enableAPI, apiClientId, apiKeyId, apiKey })=>{
8
- if ((issuerUrl ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: ISSUER-URL IS EMPTY');
3
+ import { Avatar, LoginButton } from './components/index.js';
4
+ import { authorize, callback } from './handlers/index.js';
5
+ import { cookies } from 'next/headers.js';
6
+ 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
9
  if ((clientId ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: CLIENT-ID IS EMPTY');
10
10
  if (enableAPI) {
11
11
  if ((apiClientId ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: API ENABLED, BUT API-CLIENT-ID IS EMPTY');
12
12
  if ((apiKeyId ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: API ENABLED, BUT API-KEY-ID IS EMPTY');
13
13
  if ((apiKey ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: API ENABLED, BUT API-KEY IS EMPTY');
14
14
  }
15
- const authOptionsProps = {
16
- internalProviderName: internalProviderName,
17
- issuerUrl: issuerUrl,
18
- clientId: clientId
19
- };
20
- return {
21
- zitadelPlugin: (incomingConfig)=>({
22
- ...incomingConfig,
23
- admin: {
24
- ...incomingConfig.admin,
25
- ...disableAvatar ? {} : {
26
- avatar: Avatar
27
- },
28
- components: {
29
- ...incomingConfig.admin?.components,
30
- afterLogin: [
31
- ...incomingConfig.admin?.components?.afterLogin || [],
32
- ...disableDefaultLoginButton ? [] : [
33
- LoginButton({
34
- internalProviderName,
35
- externalProviderName
36
- })
37
- ]
38
- ],
39
- providers: [
40
- Session
15
+ return (incomingConfig)=>({
16
+ ...incomingConfig,
17
+ admin: {
18
+ ...incomingConfig.admin,
19
+ ...disableAvatar ? {} : {
20
+ avatar: Avatar
21
+ },
22
+ components: {
23
+ ...incomingConfig.admin?.components,
24
+ afterLogin: [
25
+ ...incomingConfig.admin?.components?.afterLogin || [],
26
+ ...disableDefaultLoginButton ? [] : [
27
+ LoginButton
41
28
  ]
42
- }
29
+ ]
43
30
  },
44
- collections: (incomingConfig.collections || []).map((collection)=>({
45
- ...collection,
46
- ...collection.slug == authSlug ? {
47
- auth: {
48
- ...typeof collection.auth == 'boolean' ? {} : collection.auth,
49
- disableLocalStrategy: disableLocalStrategy ? disableLocalStrategy : (typeof collection.auth == 'boolean' ? {} : collection.auth)?.disableLocalStrategy,
50
- strategies: [
51
- ...(typeof collection.auth == 'boolean' ? {} : collection.auth)?.strategies ?? [],
52
- zitadelStrategy({
53
- authSlug,
54
- associatedIdFieldName,
55
- ...authOptionsProps,
56
- ...enableAPI ? {
57
- enableAPI: true,
58
- apiClientId: apiClientId,
59
- apiKeyId: apiClientId,
60
- apiKey: apiKey
61
- } : {
62
- enableAPI: undefined
63
- }
64
- })
65
- ]
66
- },
67
- fields: [
68
- ...collection.fields,
69
- {
70
- name: associatedIdFieldName,
71
- type: 'text',
72
- unique: true,
73
- required: true
74
- },
75
- {
76
- name: 'email',
77
- type: 'email',
78
- admin: {
79
- readOnly: true
80
- },
81
- access: {},
82
- hooks: {
83
- afterRead: [
84
- async ()=>(await getServerSession())?.user?.email
85
- ]
31
+ custom: {
32
+ zitadel: {
33
+ issuerURL,
34
+ clientId,
35
+ redirectURL: `${incomingConfig.serverURL ?? 'http://localhost'}/api/${incomingConfig.admin?.user ?? 'users'}/callback`,
36
+ label
37
+ }
38
+ }
39
+ },
40
+ collections: (incomingConfig.collections || []).map((collection)=>({
41
+ ...collection,
42
+ ...collection.slug == (incomingConfig.admin?.user ?? 'users') ? {
43
+ auth: {
44
+ ...typeof collection.auth == 'boolean' ? {} : collection.auth,
45
+ disableLocalStrategy: true,
46
+ strategies: [
47
+ ...(typeof collection.auth == 'boolean' ? {} : collection.auth)?.strategies ?? [],
48
+ zitadelStrategy({
49
+ authSlug: incomingConfig.admin?.user ?? 'users',
50
+ associatedIdFieldName,
51
+ strategyName: strategyName,
52
+ issuerURL: issuerURL,
53
+ clientId: clientId,
54
+ ...enableAPI ? {
55
+ enableAPI: true,
56
+ apiClientId: apiClientId,
57
+ apiKeyId: apiClientId,
58
+ apiKey: apiKey
59
+ } : {
60
+ enableAPI: undefined
86
61
  }
62
+ })
63
+ ]
64
+ },
65
+ hooks: {
66
+ afterLogout: [
67
+ ()=>cookies().delete('id_token')
68
+ ]
69
+ },
70
+ endpoints: [
71
+ {
72
+ path: '/authorize',
73
+ method: 'get',
74
+ handler: authorize
75
+ },
76
+ {
77
+ path: '/callback',
78
+ method: 'get',
79
+ handler: callback
80
+ }
81
+ ],
82
+ fields: [
83
+ ...collection.fields,
84
+ {
85
+ name: associatedIdFieldName,
86
+ type: 'text',
87
+ admin: {
88
+ readOnly: true
87
89
  },
88
- {
89
- name: 'name',
90
- type: 'text',
91
- admin: {
92
- readOnly: true
93
- },
94
- access: {},
95
- hooks: {
96
- afterRead: [
97
- async ()=>(await getServerSession())?.user?.name
98
- ]
99
- }
90
+ unique: true,
91
+ required: true
92
+ },
93
+ {
94
+ name: 'email',
95
+ type: 'email',
96
+ admin: {
97
+ readOnly: true
98
+ }
99
+ },
100
+ {
101
+ name: 'name',
102
+ type: 'text',
103
+ admin: {
104
+ readOnly: true
105
+ }
106
+ },
107
+ {
108
+ name: 'image',
109
+ type: 'text',
110
+ admin: {
111
+ readOnly: true
100
112
  }
101
- ],
102
- hooks: {
103
- afterLogout: [
104
- ()=>signOut()
105
- ]
106
- }
107
- } : {}
108
- })),
109
- //would be a more developer-friendly alternative
110
- //currently not working, maybe in future update
111
- /*endpoints: [
112
- ...incomingConfig.endpoints || [],
113
- ...['get', 'post'].map(method => ({
114
- handler: NextAuth.default(authOptions(authOptionsProps)),
115
- method: method as 'get' | 'post',
116
- path: 'api/auth/*'
117
- }))
118
- ],*/ //current work around on creating a non-functional first user
119
- async onInit (payload) {
120
- if (incomingConfig.onInit) await incomingConfig.onInit(payload);
121
- const existingUsers = await payload.find({
122
- collection: authSlug,
123
- limit: 1
124
- });
125
- if (existingUsers.docs.length === 0) {
126
- await payload.create({
127
- collection: authSlug,
128
- data: {
129
- email: 'delete.me@now.com',
130
- password: 'password',
131
- [associatedIdFieldName]: 'DELETE_ME'
132
113
  }
133
- });
134
- }
135
- },
136
- i18n: {
137
- ...incomingConfig.i18n,
138
- translations: {
139
- ...incomingConfig.i18n?.translations,
140
- de: {
141
- ...incomingConfig.i18n?.translations?.de,
142
- ...translations.de
143
- },
144
- en: {
145
- ...incomingConfig.i18n?.translations?.en,
146
- ...translations.en
114
+ ]
115
+ } : {}
116
+ })),
117
+ //current work around on creating a non-functional first user
118
+ async onInit (payload) {
119
+ if (incomingConfig.onInit) await incomingConfig.onInit(payload);
120
+ const existingUsers = await payload.find({
121
+ collection: incomingConfig.admin?.user ?? 'users',
122
+ limit: 1
123
+ });
124
+ if (existingUsers.docs.length === 0) {
125
+ await payload.create({
126
+ collection: incomingConfig.admin?.user ?? 'users',
127
+ data: {
128
+ email: 'delete.me@now.com',
129
+ password: 'password',
130
+ [associatedIdFieldName]: 'DELETE_ME'
147
131
  }
132
+ });
133
+ }
134
+ },
135
+ i18n: {
136
+ ...incomingConfig.i18n,
137
+ translations: {
138
+ ...incomingConfig.i18n?.translations,
139
+ de: {
140
+ ...incomingConfig.i18n?.translations?.de,
141
+ ...translations.de
142
+ },
143
+ en: {
144
+ ...incomingConfig.i18n?.translations?.en,
145
+ ...translations.en
148
146
  }
149
147
  }
150
- }),
151
- nextauthHandler: NextAuth.default(authOptions(authOptionsProps))
152
- };
148
+ }
149
+ });
153
150
  };
154
151
 
155
152
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import NextAuth, {getServerSession} from 'next-auth'\nimport {signOut} from 'next-auth/react'\nimport {authOptions} from './options.js'\nimport {zitadelStrategy} from './strategy.js'\nimport {ZitadelAuthOptionsProps, ZitadelPluginProviderType} from './types.js'\nimport {translations} from './translations.js'\nimport {Avatar, LoginButton, Session} from './components/index.js'\n\nexport const ZitadelPluginProvider: ZitadelPluginProviderType = ({\n authSlug = 'users',\n associatedIdFieldName = 'idp_id',\n disableAvatar,\n disableLocalStrategy,\n disableDefaultLoginButton,\n internalProviderName = 'zitadel',\n externalProviderName = '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 const authOptionsProps: ZitadelAuthOptionsProps = {\n internalProviderName: internalProviderName,\n issuerUrl: issuerUrl!,\n clientId: clientId!\n }\n return {\n zitadelPlugin: (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 internalProviderName,\n externalProviderName\n })])\n ],\n providers: [\n Session\n ]\n }\n },\n collections: (incomingConfig.collections || []).map((collection) => ({\n ...collection,\n ...collection.slug == authSlug ? {\n auth: {\n ...(typeof collection.auth == 'boolean' ? {} : collection.auth),\n disableLocalStrategy: disableLocalStrategy ? disableLocalStrategy : (typeof collection.auth == 'boolean' ? {} : collection.auth)?.disableLocalStrategy,\n strategies: [\n ...(typeof collection.auth == 'boolean' ? {} : collection.auth)?.strategies ?? [],\n zitadelStrategy({\n authSlug,\n associatedIdFieldName,\n ...authOptionsProps,\n ...(enableAPI ? {\n enableAPI: true,\n apiClientId: apiClientId!,\n apiKeyId: apiClientId!,\n apiKey: apiKey!\n } : {enableAPI: undefined})\n })\n ]\n },\n fields: [\n ...collection.fields,\n {\n name: associatedIdFieldName,\n type: 'text',\n unique: true,\n required: true\n },\n {\n name: 'email',\n type: 'email',\n admin: {\n readOnly: true\n },\n access: {},\n hooks: {\n afterRead: [\n async () => (await getServerSession())?.user?.email\n ]\n }\n },\n {\n name: 'name',\n type: 'text',\n admin: {\n readOnly: true\n },\n access: {},\n hooks: {\n afterRead: [\n async () => (await getServerSession())?.user?.name\n ]\n }\n }\n ],\n hooks: {\n afterLogout: [\n () => signOut()\n ]\n }\n } : {}\n })),\n //would be a more developer-friendly alternative\n //currently not working, maybe in future update\n /*endpoints: [\n ...incomingConfig.endpoints || [],\n ...['get', 'post'].map(method => ({\n handler: NextAuth.default(authOptions(authOptionsProps)),\n method: method as 'get' | 'post',\n path: 'api/auth/*'\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: 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@now.com',\n password: 'password',\n [associatedIdFieldName]: 'DELETE_ME'\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 nextauthHandler: NextAuth.default(authOptions(authOptionsProps))\n }\n}"],"names":["NextAuth","getServerSession","signOut","authOptions","zitadelStrategy","translations","Avatar","LoginButton","Session","ZitadelPluginProvider","authSlug","associatedIdFieldName","disableAvatar","disableLocalStrategy","disableDefaultLoginButton","internalProviderName","externalProviderName","issuerUrl","clientId","enableAPI","apiClientId","apiKeyId","apiKey","length","Error","authOptionsProps","zitadelPlugin","incomingConfig","admin","avatar","components","afterLogin","providers","collections","map","collection","slug","auth","strategies","undefined","fields","name","type","unique","required","readOnly","access","hooks","afterRead","user","email","afterLogout","onInit","payload","existingUsers","find","limit","docs","create","data","password","i18n","de","en","nextauthHandler","default"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
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 +1 @@
1
- {"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../src/strategy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,mBAAmB,EAAC,MAAM,YAAY,CAAA;AAE9C,eAAO,MAAM,eAAe,EAAE,mBA+E5B,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,mBA4F5B,CAAA"}
package/dist/strategy.js CHANGED
@@ -1,15 +1,15 @@
1
- import { getServerSession } from 'next-auth';
2
- import { authOptions } from './options.js';
3
1
  import jwt from 'jsonwebtoken';
4
- export const zitadelStrategy = ({ authSlug, associatedIdFieldName, internalProviderName, issuerUrl, clientId, enableAPI, apiClientId, apiKeyId, apiKey })=>({
5
- name: internalProviderName,
2
+ import { cookies } from 'next/headers.js';
3
+ export const zitadelStrategy = ({ authSlug, associatedIdFieldName, strategyName, issuerURL, enableAPI, apiClientId, apiKeyId, apiKey })=>({
4
+ name: strategyName,
6
5
  authenticate: async ({ headers, payload })=>{
7
- let idp_id;
6
+ let id, idp_id, id_token;
7
+ const cookieStore = cookies();
8
8
  if (enableAPI) {
9
9
  // in case of incoming API call from the app
10
10
  const authHeader = headers.get('Authorization');
11
11
  if (authHeader?.includes('Bearer')) {
12
- const introspect = await fetch(`${process.env.ZITADEL_URL}/oauth/v2/introspect`, {
12
+ const introspect = await fetch(`${issuerURL}/oauth/v2/introspect`, {
13
13
  method: 'post',
14
14
  headers: {
15
15
  'Content-Type': 'application/x-www-form-urlencoded'
@@ -18,7 +18,7 @@ export const zitadelStrategy = ({ authSlug, associatedIdFieldName, internalProvi
18
18
  'client_assertion_type': 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
19
19
  'client_assertion': jwt.sign({}, apiKey, {
20
20
  algorithm: 'RS256',
21
- audience: issuerUrl,
21
+ audience: issuerURL,
22
22
  expiresIn: '1h',
23
23
  issuer: apiClientId,
24
24
  keyid: apiKeyId,
@@ -36,13 +36,9 @@ export const zitadelStrategy = ({ authSlug, associatedIdFieldName, internalProvi
36
36
  }
37
37
  }
38
38
  // in case of normal browsing
39
- if (!idp_id) {
40
- const session = await getServerSession(authOptions({
41
- internalProviderName,
42
- issuerUrl,
43
- clientId
44
- }));
45
- if (session?.user) idp_id = (session?.user).id;
39
+ if (!idp_id && cookieStore.has('id_token')) {
40
+ id_token = jwt.verify(cookieStore.get('id_token')?.value ?? '', payload.config.secret);
41
+ idp_id = id_token.sub;
46
42
  }
47
43
  // search for associated user; if not found, create one
48
44
  if (idp_id) {
@@ -54,20 +50,31 @@ export const zitadelStrategy = ({ authSlug, associatedIdFieldName, internalProvi
54
50
  }
55
51
  }
56
52
  });
57
- const id = docs.length ? docs[0].id : (await payload.create({
53
+ id = docs.length ? docs[0].id : (await payload.create({
58
54
  collection: authSlug,
59
55
  data: {
60
56
  [associatedIdFieldName]: idp_id
61
57
  }
62
58
  })).id;
63
- return {
59
+ }
60
+ // update user information if possible
61
+ if (id && id_token) {
62
+ await payload.update({
64
63
  collection: authSlug,
65
64
  id,
66
- email: ''
67
- };
65
+ data: {
66
+ email: id_token.email,
67
+ name: id_token.name,
68
+ image: id_token.picture
69
+ }
70
+ });
68
71
  }
69
- // Authentication failed
70
- return null;
72
+ return {
73
+ user: id ? {
74
+ collection: authSlug,
75
+ id
76
+ } : null
77
+ };
71
78
  }
72
79
  });
73
80
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/strategy.ts"],"sourcesContent":["import {getServerSession, User} from 'next-auth'\nimport {authOptions} from './options.js'\nimport jwt from 'jsonwebtoken'\nimport {ZitadelStrategyType} from './types.js'\n\nexport const zitadelStrategy: ZitadelStrategyType = ({\n authSlug,\n associatedIdFieldName,\n internalProviderName,\n issuerUrl,\n clientId,\n enableAPI,\n apiClientId,\n apiKeyId,\n apiKey\n }) => ({\n name: internalProviderName,\n authenticate: async ({headers, payload}) => {\n let idp_id\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(`${process.env.ZITADEL_URL}/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) {\n const session = await getServerSession(authOptions({internalProviderName, issuerUrl, clientId}))\n if (session?.user)\n idp_id = (session?.user as User & { id: string }).id\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 const id = docs.length ? docs[0].id : (await payload.create({\n collection: authSlug,\n data: {\n [associatedIdFieldName]: idp_id\n }\n })).id\n return {\n collection: authSlug,\n id,\n email: ''\n }\n }\n\n // Authentication failed\n return null\n }\n})"],"names":["getServerSession","authOptions","jwt","zitadelStrategy","authSlug","associatedIdFieldName","internalProviderName","issuerUrl","clientId","enableAPI","apiClientId","apiKeyId","apiKey","name","authenticate","headers","payload","idp_id","authHeader","get","includes","introspect","fetch","process","env","ZITADEL_URL","method","body","URLSearchParams","sign","algorithm","audience","expiresIn","issuer","keyid","subject","split","ok","data","json","active","sub","session","user","id","docs","find","collection","where","equals","length","create","email"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAAQA,gBAAgB,QAAa,YAAW;AAChD,SAAQC,WAAW,QAAO,eAAc;AACxC,OAAOC,SAAS,eAAc;AAG9B,OAAO,MAAMC,kBAAuC,CAAC,EACIC,QAAQ,EACRC,qBAAqB,EACrBC,oBAAoB,EACpBC,SAAS,EACTC,QAAQ,EACRC,SAAS,EACTC,WAAW,EACXC,QAAQ,EACRC,MAAM,EACT,GAAM,CAAA;QACxDC,MAAMP;QACNQ,cAAc,OAAO,EAACC,OAAO,EAAEC,OAAO,EAAC;YACnC,IAAIC;YAEJ,IAAIR,WAAW;gBACX,4CAA4C;gBAC5C,MAAMS,aAAaH,QAAQI,GAAG,CAAC;gBAC/B,IAAID,YAAYE,SAAS,WAAW;oBAChC,MAAMC,aAAa,MAAMC,MAAM,CAAC,EAAEC,QAAQC,GAAG,CAACC,WAAW,CAAC,oBAAoB,CAAC,EAAE;wBAC7EC,QAAQ;wBACRX,SAAS;4BACL,gBAAgB;wBACpB;wBACAY,MAAM,IAAIC,gBAAgB;4BACtB,yBAAyB;4BACzB,oBAAoB1B,IAAI2B,IAAI,CAAC,CAAC,GAAGjB,QAAQ;gCACrCkB,WAAW;gCACXC,UAAUxB;gCACVyB,WAAW;gCACXC,QAAQvB;gCACRwB,OAAOvB;gCACPwB,SAASzB;4BACb;4BACA,SAASQ,WAAWkB,KAAK,CAAC,IAAI,CAAC,EAAE;wBACrC;oBACJ;oBACA,IAAIf,WAAWgB,EAAE,EAAE;wBACf,MAAMC,OAAO,MAAMjB,WAAWkB,IAAI;wBAClC,IAAID,MAAME,QAAQ;4BACdvB,SAASqB,KAAKG,GAAG;wBACrB;oBACJ;gBACJ;YACJ;YAEA,6BAA6B;YAC7B,IAAI,CAACxB,QAAQ;gBACT,MAAMyB,UAAU,MAAM1C,iBAAiBC,YAAY;oBAACK;oBAAsBC;oBAAWC;gBAAQ;gBAC7F,IAAIkC,SAASC,MACT1B,SAAS,AAACyB,CAAAA,SAASC,IAAG,EAA4BC,EAAE;YAC5D;YAEA,uDAAuD;YACvD,IAAI3B,QAAQ;gBACR,MAAM,EAAC4B,IAAI,EAAC,GAAG,MAAM7B,QAAQ8B,IAAI,CAAC;oBAC9BC,YAAY3C;oBACZ4C,OAAO;wBACH,CAAC3C,sBAAsB,EAAE;4BACrB4C,QAAQhC;wBACZ;oBACJ;gBACJ;gBACA,MAAM2B,KAAKC,KAAKK,MAAM,GAAGL,IAAI,CAAC,EAAE,CAACD,EAAE,GAAG,AAAC,CAAA,MAAM5B,QAAQmC,MAAM,CAAC;oBACxDJ,YAAY3C;oBACZkC,MAAM;wBACF,CAACjC,sBAAsB,EAAEY;oBAC7B;gBACJ,EAAC,EAAG2B,EAAE;gBACN,OAAO;oBACHG,YAAY3C;oBACZwC;oBACAQ,OAAO;gBACX;YACJ;YAEA,wBAAwB;YACxB,OAAO;QACX;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 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,11 +1,11 @@
1
1
  export declare const translations: {
2
2
  de: {
3
- zitadelPlugin: {
3
+ oidcPlugin: {
4
4
  signIn: string;
5
5
  };
6
6
  };
7
7
  en: {
8
- zitadelPlugin: {
8
+ oidcPlugin: {
9
9
  signIn: string;
10
10
  };
11
11
  };
@@ -1,12 +1,12 @@
1
1
  export const translations = {
2
2
  de: {
3
- zitadelPlugin: {
4
- signIn: 'Mit {{externalProviderName}} anmelden'
3
+ oidcPlugin: {
4
+ signIn: 'Mit {{label}} anmelden'
5
5
  }
6
6
  },
7
7
  en: {
8
- zitadelPlugin: {
9
- signIn: 'sign-in with {{externalProviderName}}'
8
+ oidcPlugin: {
9
+ signIn: 'sign in with {{label}}'
10
10
  }
11
11
  }
12
12
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/translations.ts"],"sourcesContent":["export const translations = {\n de: {\n zitadelPlugin: {\n signIn: 'Mit {{externalProviderName}} anmelden'\n }\n },\n en: {\n zitadelPlugin: {\n signIn: 'sign-in with {{externalProviderName}}'\n }\n }\n}"],"names":["translations","de","zitadelPlugin","signIn","en"],"rangeMappings":";;;;;;;;;;;","mappings":"AAAA,OAAO,MAAMA,eAAe;IACxBC,IAAI;QACAC,eAAe;YACXC,QAAQ;QACZ;IACJ;IACAC,IAAI;QACAF,eAAe;YACXC,QAAQ;QACZ;IACJ;AACJ,EAAC"}
1
+ {"version":3,"sources":["../src/translations.ts"],"sourcesContent":["export const translations = {\n de: {\n oidcPlugin: {\n signIn: 'Mit {{label}} anmelden'\n }\n },\n en: {\n oidcPlugin: {\n signIn: 'sign in with {{label}}'\n }\n }\n}"],"names":["translations","de","oidcPlugin","signIn","en"],"mappings":"AAAA,OAAO,MAAMA,eAAe;IACxBC,IAAI;QACAC,YAAY;YACRC,QAAQ;QACZ;IACJ;IACAC,IAAI;QACAF,YAAY;YACRC,QAAQ;QACZ;IACJ;AACJ,EAAC"}
package/dist/types.d.ts CHANGED
@@ -1,44 +1,32 @@
1
- import { Awaitable, NextAuthOptions, Session } from 'next-auth';
2
- import { AuthStrategy } from 'payload';
3
- import { Config } from 'payload';
4
- import { JWT } from 'next-auth/jwt';
1
+ import { AuthStrategy, Config } from 'payload';
5
2
  export type ZitadelPluginProps = {
6
3
  disableAvatar?: true | undefined;
7
- disableLocalStrategy?: true | undefined;
8
4
  disableDefaultLoginButton?: true | undefined;
9
5
  defaultLoginButtonTitle?: string;
10
- externalProviderName?: string;
6
+ label?: string;
11
7
  } & Partial<ZitadelStrategyProps>;
12
- export type ZitadelPluginProviderType = (props: ZitadelPluginProps) => {
13
- zitadelPlugin: (incomingConfig: Config) => Config;
14
- nextauthHandler: any;
15
- };
16
- export type ZitadelAuthOptionsProps = {
17
- internalProviderName: string;
18
- issuerUrl: string;
19
- clientId: string;
20
- };
21
- export type ZitadelAuthOptionsType = (props: ZitadelAuthOptionsProps) => NextAuthOptions & {
22
- callbacks: {
23
- session: (props: {
24
- session: Session;
25
- token: JWT & {
26
- user: any;
27
- };
28
- }) => Awaitable<Session>;
29
- };
30
- };
8
+ export type ZitadelPluginType = (props: ZitadelPluginProps) => (config: Config) => Config;
31
9
  export type ZitadelAPIProps = {
32
10
  enableAPI: true;
33
11
  apiClientId: string;
34
12
  apiKeyId: string;
35
13
  apiKey: string;
36
14
  };
37
- export type ZitadelStrategyProps = ZitadelAuthOptionsProps & {
15
+ export type ZitadelStrategyProps = {
16
+ strategyName: string;
17
+ issuerURL: string;
18
+ clientId: string;
19
+ } & {
38
20
  authSlug: string;
39
21
  associatedIdFieldName: string;
40
22
  } & (ZitadelAPIProps | {
41
23
  enableAPI?: undefined;
42
24
  } & Partial<ZitadelAPIProps>);
43
25
  export type ZitadelStrategyType = (props: ZitadelStrategyProps) => AuthStrategy;
26
+ export type ZitadelIdToken = Partial<{
27
+ sub: string;
28
+ name: string;
29
+ email: string;
30
+ picture: string;
31
+ }>;
44
32
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,eAAe,EAAE,OAAO,EAAC,MAAM,WAAW,CAAA;AAC7D,OAAO,EAAC,YAAY,EAAC,MAAM,SAAS,CAAA;AACpC,OAAO,EAAC,MAAM,EAAC,MAAM,SAAS,CAAA;AAC9B,OAAO,EAAC,GAAG,EAAC,MAAM,eAAe,CAAA;AAEjC,MAAM,MAAM,kBAAkB,GAAG;IAC7B,aAAa,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;IAChC,oBAAoB,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;IACvC,yBAAyB,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;IAC5C,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAChC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;AAEjC,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK;IACnE,aAAa,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,eAAe,EAAE,GAAG,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IAClC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,uBAAuB,KAAK,eAAe,GAAG;IACvF,SAAS,EAAE;QAAE,OAAO,EAAE,CAAC,KAAK,EAAE;YAAE,OAAO,EAAE,OAAO,CAAC;YAAC,KAAK,EAAE,GAAG,GAAG;gBAAE,IAAI,EAAE,GAAG,CAAA;aAAE,CAAA;SAAE,KAAK,SAAS,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;CAC1G,CAAA;AAED,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,uBAAuB,GAAG;IACzD,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"}
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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import {Awaitable, NextAuthOptions, Session} from 'next-auth'\nimport {AuthStrategy} from 'payload'\nimport {Config} from 'payload'\nimport {JWT} from 'next-auth/jwt'\n\nexport type ZitadelPluginProps = {\n disableAvatar?: true | undefined\n disableLocalStrategy?: true | undefined\n disableDefaultLoginButton?: true | undefined\n defaultLoginButtonTitle?: string\n externalProviderName?: string\n} & Partial<ZitadelStrategyProps>\n\nexport type ZitadelPluginProviderType = (props: ZitadelPluginProps) => {\n zitadelPlugin: (incomingConfig: Config) => Config,\n nextauthHandler: any\n}\n\nexport type ZitadelAuthOptionsProps = {\n internalProviderName: string,\n issuerUrl: string,\n clientId: string\n}\n\nexport type ZitadelAuthOptionsType = (props: ZitadelAuthOptionsProps) => NextAuthOptions & {\n callbacks: { session: (props: { session: Session, token: JWT & { user: any } }) => Awaitable<Session> }\n}\n\nexport type ZitadelAPIProps = {\n enableAPI: true\n apiClientId: string,\n apiKeyId: string,\n apiKey: string\n}\n\nexport type ZitadelStrategyProps = ZitadelAuthOptionsProps & {\n authSlug: string,\n associatedIdFieldName: string,\n} & (ZitadelAPIProps | {\n enableAPI?: undefined\n} & Partial<ZitadelAPIProps>)\n\nexport type ZitadelStrategyType = (props: ZitadelStrategyProps) => AuthStrategy"],"names":[],"rangeMappings":"","mappings":"AA0CA,WAA+E"}
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"}
@@ -0,0 +1,2 @@
1
+ export { getCurrentUser } from './user.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,WAAW,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { getCurrentUser } from './user.js';
2
+
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export {getCurrentUser} from './user.js'"],"names":["getCurrentUser"],"mappings":"AAAA,SAAQA,cAAc,QAAO,YAAW"}
@@ -0,0 +1,5 @@
1
+ import { SanitizedConfig } from 'payload';
2
+ export declare const getCurrentUser: ({ config }: {
3
+ config: Promise<SanitizedConfig>;
4
+ }) => Promise<(Record<string, unknown> & import("payload").TypeWithID) | null>;
5
+ //# sourceMappingURL=user.d.ts.map
@@ -0,0 +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"}