payload-zitadel-plugin 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -0
- package/dist/LoginButton/button.d.ts +3 -0
- package/dist/LoginButton/button.d.ts.map +1 -0
- package/dist/LoginButton/button.js +20 -0
- package/dist/LoginButton/button.js.map +1 -0
- package/dist/LoginButton/index.d.ts +6 -0
- package/dist/LoginButton/index.d.ts.map +1 -0
- package/dist/LoginButton/index.js +8 -0
- package/dist/LoginButton/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +123 -0
- package/dist/index.js.map +1 -0
- package/dist/options.d.ts +3 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +45 -0
- package/dist/options.js.map +1 -0
- package/dist/strategy.d.ts +3 -0
- package/dist/strategy.d.ts.map +1 -0
- package/dist/strategy.js +74 -0
- package/dist/strategy.js.map +1 -0
- package/dist/translations.d.ts +13 -0
- package/dist/translations.d.ts.map +1 -0
- package/dist/translations.js +14 -0
- package/dist/translations.js.map +1 -0
- package/dist/types.d.ts +33 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +83 -0
package/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# payload-zitadel-plugin
|
2
|
+
|
3
|
+
[](https://npmjs.org/package/payload-zitadel-plugin)
|
4
|
+
|
5
|
+
plugin for [Payload CMS](https://payloadcms.com), which enables authentication via Zitadel IdP. It uses [NextAuth.js](https://next-auth.js.org) under the hood.
|
6
|
+
|
7
|
+
:boom: :boom: :boom: works :100: with PayloadCMS version :three: :boom: :boom: :boom:
|
8
|
+
|
9
|
+
## Install
|
10
|
+
|
11
|
+
```shell
|
12
|
+
pnpm add payload-zitadel-plugin@0.1.0
|
13
|
+
```
|
14
|
+
|
15
|
+
## Configuration
|
16
|
+
|
17
|
+
Initialize the plugin in Payload Config File. Change the parameters to connect to your Zitadel Instance.
|
18
|
+
|
19
|
+
#### payload.config.ts
|
20
|
+
|
21
|
+
```typescript
|
22
|
+
import {buildConfig} from 'payload/config'
|
23
|
+
import {ZitadelPluginProvider} from 'payload-zitadel-plugin'
|
24
|
+
|
25
|
+
export const {zitadelPlugin, nextauthHandler} = ZitadelPluginProvider({
|
26
|
+
// interpolation text for the Login Button
|
27
|
+
externalProviderName: 'Test-IdP',
|
28
|
+
|
29
|
+
// set to true if you want users to only be able to sign in via Zitadel
|
30
|
+
disableLocalStrategy: true,
|
31
|
+
|
32
|
+
// in Zitadel create a new App->Web->PKCE
|
33
|
+
issuerUrl: process.env.ZITADEL_URL,
|
34
|
+
clientId: process.env.ZITADEL_CLIENT_ID,
|
35
|
+
|
36
|
+
// following properties are only needed if you want to authenticate clients for the API
|
37
|
+
// if you are just using the CMS you can ignore all of them
|
38
|
+
|
39
|
+
// in Zitadel create a new App->API->JWT
|
40
|
+
enableAPI: true,
|
41
|
+
apiClientId: process.env.ZITADEL_API_CLIENT_ID,
|
42
|
+
apiKeyId: process.env.ZITADEL_API_KEY_ID,
|
43
|
+
apiKey: process.env.ZITADEL_API_KEY
|
44
|
+
})
|
45
|
+
|
46
|
+
export default buildConfig({
|
47
|
+
...,
|
48
|
+
plugins: [
|
49
|
+
zitadelPlugin
|
50
|
+
],
|
51
|
+
...
|
52
|
+
})
|
53
|
+
```
|
54
|
+
|
55
|
+
Optionally you could use an `.env.local` file for parameters:
|
56
|
+
#### .env.local
|
57
|
+
```dotenv
|
58
|
+
ZITADEL_URL: 'https://idp.zitadel.url',
|
59
|
+
ZITADEL_CLIENT_ID: '123456789012345678@project_name',
|
60
|
+
ZITADEL_API_CLIENT_ID: '123456789123456789@project_name',
|
61
|
+
ZITADEL_API_KEY_ID: '123456789012345678',
|
62
|
+
ZITADEL_API_KEY: '-----BEGIN RSA PRIVATE KEY----- ... ----END RSA PRIVATE KEY-----'
|
63
|
+
```
|
64
|
+
|
65
|
+
### create route
|
66
|
+
Unfortunately you need to manually create the following NextAuth.js route in your Next.js App (using App Router):
|
67
|
+
|
68
|
+
### (nextauth)/api/auth/[...nextauth]/route.ts
|
69
|
+
```typescript
|
70
|
+
import {nextauthHandler} from '@payload-config'
|
71
|
+
|
72
|
+
export {nextauthHandler as GET, nextauthHandler as POST}
|
73
|
+
```
|
74
|
+
|
75
|
+
## For an example look in this repository at the `dev` directory!
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/LoginButton/button.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAC,eAAe,EAAC,MAAM,gBAAgB,CAAA;AAM9C,eAAO,MAAM,YAAY,EAAE,eAa1B,CAAA"}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
'use client';
|
2
|
+
import React from 'react';
|
3
|
+
import { signIn } from 'next-auth/react';
|
4
|
+
import { Button } from '@payloadcms/ui/elements';
|
5
|
+
import { useTranslation } from '@payloadcms/ui/providers/Translation';
|
6
|
+
export const _LoginButton = ({ internalProviderName, externalProviderName })=>{
|
7
|
+
const { t } = useTranslation();
|
8
|
+
return /*#__PURE__*/ React.createElement("div", {
|
9
|
+
style: {
|
10
|
+
display: 'flex',
|
11
|
+
justifyContent: 'center'
|
12
|
+
}
|
13
|
+
}, /*#__PURE__*/ React.createElement(Button, {
|
14
|
+
onClick: ()=>signIn(internalProviderName)
|
15
|
+
}, t('zitadelPlugin:signIn', {
|
16
|
+
externalProviderName
|
17
|
+
})));
|
18
|
+
};
|
19
|
+
|
20
|
+
//# sourceMappingURL=button.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../src/LoginButton/button.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport {signIn} from 'next-auth/react'\nimport {CustomComponent} from 'payload/config'\nimport {NestedKeysStripped} from '@payloadcms/translations'\nimport {Button} from '@payloadcms/ui/elements'\nimport {useTranslation} from '@payloadcms/ui/providers/Translation'\nimport {translations} from '../translations.js'\n\nexport const _LoginButton: CustomComponent = ({internalProviderName, externalProviderName}: {\n internalProviderName: string,\n externalProviderName: string\n}) => {\n const {t} = useTranslation<typeof translations.en, NestedKeysStripped<typeof translations.en>>()\n\n return (\n <div style={{display: 'flex', justifyContent: 'center'}}>\n <Button onClick={() => signIn(internalProviderName)}>\n {t('zitadelPlugin:signIn', {externalProviderName})}\n </Button>\n </div>\n )\n}"],"names":["React","signIn","Button","useTranslation","_LoginButton","internalProviderName","externalProviderName","t","div","style","display","justifyContent","onClick"],"rangeMappings":";;;;;;;;;;;;;;;;;","mappings":"AAAA;AAEA,OAAOA,WAAW,QAAO;AACzB,SAAQC,MAAM,QAAO,kBAAiB;AAGtC,SAAQC,MAAM,QAAO,0BAAyB;AAC9C,SAAQC,cAAc,QAAO,uCAAsC;AAGnE,OAAO,MAAMC,eAAgC,CAAC,EAACC,oBAAoB,EAAEC,oBAAoB,EAGxF;IACG,MAAM,EAACC,CAAC,EAAC,GAAGJ;IAEZ,qBACI,oBAACK;QAAIC,OAAO;YAACC,SAAS;YAAQC,gBAAgB;QAAQ;qBAClD,oBAACT;QAAOU,SAAS,IAAMX,OAAOI;OACzBE,EAAE,wBAAwB;QAACD;IAAoB;AAIhE,EAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/LoginButton/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,eAAO,MAAM,WAAW,mDAAkD;IACtE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAA;CAC/B,4BAAkH,CAAA"}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { _LoginButton } from './button.js';
|
3
|
+
export const LoginButton = ({ internalProviderName, externalProviderName })=>()=>/*#__PURE__*/ React.createElement(_LoginButton, {
|
4
|
+
internalProviderName: internalProviderName,
|
5
|
+
externalProviderName: externalProviderName
|
6
|
+
});
|
7
|
+
|
8
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../src/LoginButton/index.tsx"],"sourcesContent":["import React from 'react'\nimport {_LoginButton} from './button.js'\n\nexport const LoginButton = ({internalProviderName, externalProviderName}: {\n internalProviderName: string,\n externalProviderName: string\n}) => () => <_LoginButton internalProviderName={internalProviderName} externalProviderName={externalProviderName}/>"],"names":["React","_LoginButton","LoginButton","internalProviderName","externalProviderName"],"rangeMappings":";;;;;","mappings":"AAAA,OAAOA,WAAW,QAAO;AACzB,SAAQC,YAAY,QAAO,cAAa;AAExC,OAAO,MAAMC,cAAc,CAAC,EAACC,oBAAoB,EAAEC,oBAAoB,EAGtE,GAAK,kBAAM,oBAACH;YAAaE,sBAAsBA;YAAsBC,sBAAsBA;WAAuB"}
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,WAAW,EAAC,MAAM,wBAAwB,CAAA;AAGlD,OAAO,EAA0B,yBAAyB,EAAC,MAAM,YAAY,CAAA;AAI7E,OAAO,EAAC,WAAW,EAAC,CAAA;AAEpB,eAAO,MAAM,qBAAqB,EAAE,yBAoInC,CAAA"}
|
package/dist/index.js
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
import NextAuth from 'next-auth';
|
2
|
+
import { signOut } from 'next-auth/react';
|
3
|
+
import { LoginButton } from './LoginButton/index.js';
|
4
|
+
import { authOptions } from './options.js';
|
5
|
+
import { zitadelStrategy } from './strategy.js';
|
6
|
+
import { translations } from './translations.js';
|
7
|
+
export { LoginButton };
|
8
|
+
export const ZitadelPluginProvider = ({ authSlug = 'users', associatedIdFieldName = 'idp_id', disableLocalStrategy, disableDefaultLoginButton, internalProviderName = 'zitadel', externalProviderName = 'ZITADEL', issuerUrl, clientId, enableAPI, apiClientId, apiKeyId, apiKey })=>{
|
9
|
+
if ((issuerUrl ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: ISSUER-URL IS EMPTY');
|
10
|
+
if ((clientId ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: CLIENT-ID IS EMPTY');
|
11
|
+
if (enableAPI) {
|
12
|
+
if ((apiClientId ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: API ENABLED, BUT API-CLIENT-ID IS EMPTY');
|
13
|
+
if ((apiKeyId ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: API ENABLED, BUT API-KEY-ID IS EMPTY');
|
14
|
+
if ((apiKey ?? '').length == 0) throw new Error('ZITADEL-PLUGIN: API ENABLED, BUT API-KEY IS EMPTY');
|
15
|
+
}
|
16
|
+
const authOptionsProps = {
|
17
|
+
internalProviderName: internalProviderName,
|
18
|
+
issuerUrl: issuerUrl,
|
19
|
+
clientId: clientId
|
20
|
+
};
|
21
|
+
return {
|
22
|
+
zitadelPlugin: (incomingConfig)=>({
|
23
|
+
...incomingConfig,
|
24
|
+
admin: {
|
25
|
+
...incomingConfig.admin,
|
26
|
+
components: {
|
27
|
+
...incomingConfig.admin?.components,
|
28
|
+
afterLogin: [
|
29
|
+
...incomingConfig.admin?.components?.afterLogin || [],
|
30
|
+
...disableDefaultLoginButton ? [] : [
|
31
|
+
LoginButton({
|
32
|
+
internalProviderName,
|
33
|
+
externalProviderName
|
34
|
+
})
|
35
|
+
]
|
36
|
+
]
|
37
|
+
}
|
38
|
+
},
|
39
|
+
collections: (incomingConfig.collections || []).map((collection)=>({
|
40
|
+
...collection,
|
41
|
+
...collection.slug == authSlug ? {
|
42
|
+
auth: {
|
43
|
+
...typeof collection.auth == 'boolean' ? {} : collection.auth,
|
44
|
+
disableLocalStrategy: disableLocalStrategy ? disableLocalStrategy : (typeof collection.auth == 'boolean' ? {} : collection.auth)?.disableLocalStrategy,
|
45
|
+
strategies: [
|
46
|
+
...(typeof collection.auth == 'boolean' ? {} : collection.auth)?.strategies ?? [],
|
47
|
+
zitadelStrategy({
|
48
|
+
authSlug,
|
49
|
+
associatedIdFieldName,
|
50
|
+
...authOptionsProps,
|
51
|
+
...enableAPI ? {
|
52
|
+
enableAPI: true,
|
53
|
+
apiClientId: apiClientId,
|
54
|
+
apiKeyId: apiClientId,
|
55
|
+
apiKey: apiKey
|
56
|
+
} : {
|
57
|
+
enableAPI: undefined
|
58
|
+
}
|
59
|
+
})
|
60
|
+
]
|
61
|
+
},
|
62
|
+
fields: [
|
63
|
+
...collection.fields,
|
64
|
+
{
|
65
|
+
name: associatedIdFieldName,
|
66
|
+
type: 'text',
|
67
|
+
unique: true,
|
68
|
+
required: true
|
69
|
+
}
|
70
|
+
],
|
71
|
+
hooks: {
|
72
|
+
afterLogout: [
|
73
|
+
()=>signOut()
|
74
|
+
]
|
75
|
+
}
|
76
|
+
} : {}
|
77
|
+
})),
|
78
|
+
//would be a more developer-friendly alternative
|
79
|
+
//currently not working, maybe in future update
|
80
|
+
/*endpoints: [
|
81
|
+
...incomingConfig.endpoints || [],
|
82
|
+
...['get', 'post'].map(method => ({
|
83
|
+
handler: NextAuth.default(authOptions(authOptionsProps)),
|
84
|
+
method: method as 'get' | 'post',
|
85
|
+
path: 'api/auth/*'
|
86
|
+
}))
|
87
|
+
],*/ //current work around on creating a non-functional first user
|
88
|
+
async onInit (payload) {
|
89
|
+
if (incomingConfig.onInit) await incomingConfig.onInit(payload);
|
90
|
+
const existingUsers = await payload.find({
|
91
|
+
collection: authSlug,
|
92
|
+
limit: 1
|
93
|
+
});
|
94
|
+
if (existingUsers.docs.length === 0) {
|
95
|
+
await payload.create({
|
96
|
+
collection: authSlug,
|
97
|
+
data: {
|
98
|
+
email: 'delete.me@now.com',
|
99
|
+
password: 'password',
|
100
|
+
[associatedIdFieldName]: 'DELETE_ME'
|
101
|
+
}
|
102
|
+
});
|
103
|
+
}
|
104
|
+
},
|
105
|
+
i18n: {
|
106
|
+
...incomingConfig.i18n,
|
107
|
+
translations: {
|
108
|
+
de: {
|
109
|
+
...incomingConfig.i18n?.translations?.de ?? {},
|
110
|
+
...translations.de
|
111
|
+
},
|
112
|
+
en: {
|
113
|
+
...incomingConfig.i18n?.translations?.en ?? {},
|
114
|
+
...translations.en
|
115
|
+
}
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}),
|
119
|
+
nextauthHandler: NextAuth.default(authOptions(authOptionsProps))
|
120
|
+
};
|
121
|
+
};
|
122
|
+
|
123
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import NextAuth from 'next-auth'\nimport {signOut} from 'next-auth/react'\nimport {LoginButton} from './LoginButton/index.js'\nimport {authOptions} from './options.js'\nimport {zitadelStrategy} from './strategy.js'\nimport {ZitadelAuthOptionsProps, ZitadelPluginProviderType} from './types.js'\nimport {translations} from './translations.js'\n\n\nexport {LoginButton}\n\nexport const ZitadelPluginProvider: ZitadelPluginProviderType = ({\n authSlug = 'users',\n associatedIdFieldName = 'idp_id',\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 components: {\n ...incomingConfig.admin?.components,\n afterLogin: [\n ...incomingConfig.admin?.components?.afterLogin || [],\n ...(disableDefaultLoginButton ? [] : [LoginButton({\n internalProviderName,\n externalProviderName\n })])\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 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 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","signOut","LoginButton","authOptions","zitadelStrategy","translations","ZitadelPluginProvider","authSlug","associatedIdFieldName","disableLocalStrategy","disableDefaultLoginButton","internalProviderName","externalProviderName","issuerUrl","clientId","enableAPI","apiClientId","apiKeyId","apiKey","length","Error","authOptionsProps","zitadelPlugin","incomingConfig","admin","components","afterLogin","collections","map","collection","slug","auth","strategies","undefined","fields","name","type","unique","required","hooks","afterLogout","onInit","payload","existingUsers","find","limit","docs","create","data","email","password","i18n","de","en","nextauthHandler","default"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,sBAAsB,EAAC,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,WAAW,EAAE,sBAuCxB,CAAA"}
|
package/dist/options.js
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
export const authOptions = ({ internalProviderName, issuerUrl, clientId })=>({
|
2
|
+
providers: [
|
3
|
+
{
|
4
|
+
id: internalProviderName,
|
5
|
+
name: internalProviderName,
|
6
|
+
type: 'oauth',
|
7
|
+
version: '2',
|
8
|
+
wellKnown: issuerUrl,
|
9
|
+
authorization: {
|
10
|
+
params: {
|
11
|
+
scope: 'openid email profile'
|
12
|
+
}
|
13
|
+
},
|
14
|
+
idToken: true,
|
15
|
+
checks: [
|
16
|
+
'pkce',
|
17
|
+
'state'
|
18
|
+
],
|
19
|
+
client: {
|
20
|
+
token_endpoint_auth_method: 'none'
|
21
|
+
},
|
22
|
+
profile: async (profile)=>({
|
23
|
+
id: profile.sub,
|
24
|
+
name: profile.name,
|
25
|
+
firstName: profile.given_name,
|
26
|
+
lastName: profile.family_name,
|
27
|
+
email: profile.email,
|
28
|
+
loginName: profile.preferred_username,
|
29
|
+
image: profile.picture
|
30
|
+
}),
|
31
|
+
clientId
|
32
|
+
}
|
33
|
+
],
|
34
|
+
callbacks: {
|
35
|
+
session: async ({ session, token })=>({
|
36
|
+
...session,
|
37
|
+
user: {
|
38
|
+
...session.user,
|
39
|
+
id: token.sub
|
40
|
+
}
|
41
|
+
})
|
42
|
+
}
|
43
|
+
});
|
44
|
+
|
45
|
+
//# sourceMappingURL=options.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/options.ts"],"sourcesContent":["import {ZitadelAuthOptionsType} from './types.js'\n\nexport const authOptions: ZitadelAuthOptionsType = ({internalProviderName, issuerUrl, clientId}) => ({\n providers: [\n {\n id: internalProviderName,\n name: internalProviderName,\n type: 'oauth',\n version: '2',\n wellKnown: issuerUrl,\n authorization: {\n params: {\n scope: 'openid email profile'\n }\n },\n idToken: true,\n checks: ['pkce', 'state'],\n client: {\n token_endpoint_auth_method: 'none'\n },\n profile: async (profile) => ({\n id: profile.sub,\n name: profile.name,\n firstName: profile.given_name,\n lastName: profile.family_name,\n email: profile.email,\n loginName: profile.preferred_username,\n image: profile.picture\n }),\n clientId\n }\n ],\n callbacks: {\n session: async ({session, token}) => ({\n ...session,\n user: {\n ...session.user,\n id: token.sub\n }\n })\n }\n})"],"names":["authOptions","internalProviderName","issuerUrl","clientId","providers","id","name","type","version","wellKnown","authorization","params","scope","idToken","checks","client","token_endpoint_auth_method","profile","sub","firstName","given_name","lastName","family_name","email","loginName","preferred_username","image","picture","callbacks","session","token","user"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAEA,OAAO,MAAMA,cAAsC,CAAC,EAACC,oBAAoB,EAAEC,SAAS,EAAEC,QAAQ,EAAC,GAAM,CAAA;QACjGC,WAAW;YACP;gBACIC,IAAIJ;gBACJK,MAAML;gBACNM,MAAM;gBACNC,SAAS;gBACTC,WAAWP;gBACXQ,eAAe;oBACXC,QAAQ;wBACJC,OAAO;oBACX;gBACJ;gBACAC,SAAS;gBACTC,QAAQ;oBAAC;oBAAQ;iBAAQ;gBACzBC,QAAQ;oBACJC,4BAA4B;gBAChC;gBACAC,SAAS,OAAOA,UAAa,CAAA;wBACzBZ,IAAIY,QAAQC,GAAG;wBACfZ,MAAMW,QAAQX,IAAI;wBAClBa,WAAWF,QAAQG,UAAU;wBAC7BC,UAAUJ,QAAQK,WAAW;wBAC7BC,OAAON,QAAQM,KAAK;wBACpBC,WAAWP,QAAQQ,kBAAkB;wBACrCC,OAAOT,QAAQU,OAAO;oBAC1B,CAAA;gBACAxB;YACJ;SACH;QACDyB,WAAW;YACPC,SAAS,OAAO,EAACA,OAAO,EAAEC,KAAK,EAAC,GAAM,CAAA;oBAClC,GAAGD,OAAO;oBACVE,MAAM;wBACF,GAAGF,QAAQE,IAAI;wBACf1B,IAAIyB,MAAMZ,GAAG;oBACjB;gBACJ,CAAA;QACJ;IACJ,CAAA,EAAE"}
|
@@ -0,0 +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"}
|
package/dist/strategy.js
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
import { getServerSession } from 'next-auth';
|
2
|
+
import { authOptions } from './options.js';
|
3
|
+
import jwt from 'jsonwebtoken';
|
4
|
+
export const zitadelStrategy = ({ authSlug, associatedIdFieldName, internalProviderName, issuerUrl, clientId, enableAPI, apiClientId, apiKeyId, apiKey })=>({
|
5
|
+
name: internalProviderName,
|
6
|
+
authenticate: async ({ headers, payload })=>{
|
7
|
+
let idp_id;
|
8
|
+
if (enableAPI) {
|
9
|
+
// in case of incoming API call from the app
|
10
|
+
const authHeader = headers.get('Authorization');
|
11
|
+
if (authHeader?.includes('Bearer')) {
|
12
|
+
const introspect = await fetch(`${process.env.ZITADEL_URL}/oauth/v2/introspect`, {
|
13
|
+
method: 'post',
|
14
|
+
headers: {
|
15
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
16
|
+
},
|
17
|
+
body: new URLSearchParams({
|
18
|
+
'client_assertion_type': 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
|
19
|
+
'client_assertion': jwt.sign({}, apiKey, {
|
20
|
+
algorithm: 'RS256',
|
21
|
+
audience: issuerUrl,
|
22
|
+
expiresIn: '1h',
|
23
|
+
issuer: apiClientId,
|
24
|
+
keyid: apiKeyId,
|
25
|
+
subject: apiClientId
|
26
|
+
}),
|
27
|
+
'token': authHeader.split(' ')[1]
|
28
|
+
})
|
29
|
+
});
|
30
|
+
if (introspect.ok) {
|
31
|
+
const data = await introspect.json();
|
32
|
+
if (data?.active) {
|
33
|
+
idp_id = data.sub;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
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;
|
46
|
+
}
|
47
|
+
// search for associated user; if not found, create one
|
48
|
+
if (idp_id) {
|
49
|
+
const { docs } = await payload.find({
|
50
|
+
collection: authSlug,
|
51
|
+
where: {
|
52
|
+
[associatedIdFieldName]: {
|
53
|
+
equals: idp_id
|
54
|
+
}
|
55
|
+
}
|
56
|
+
});
|
57
|
+
const id = docs.length ? docs[0].id : (await payload.create({
|
58
|
+
collection: authSlug,
|
59
|
+
data: {
|
60
|
+
[associatedIdFieldName]: idp_id
|
61
|
+
}
|
62
|
+
})).id;
|
63
|
+
return {
|
64
|
+
collection: authSlug,
|
65
|
+
id,
|
66
|
+
email: ''
|
67
|
+
};
|
68
|
+
}
|
69
|
+
// Authentication failed
|
70
|
+
return null;
|
71
|
+
}
|
72
|
+
});
|
73
|
+
|
74
|
+
//# sourceMappingURL=strategy.js.map
|
@@ -0,0 +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"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"translations.d.ts","sourceRoot":"","sources":["../src/translations.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;;;;;;;;;;CAWxB,CAAA"}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
export const translations = {
|
2
|
+
de: {
|
3
|
+
zitadelPlugin: {
|
4
|
+
signIn: 'Mit {{externalProviderName}} anmelden'
|
5
|
+
}
|
6
|
+
},
|
7
|
+
en: {
|
8
|
+
zitadelPlugin: {
|
9
|
+
signIn: 'sign-in with {{externalProviderName}}'
|
10
|
+
}
|
11
|
+
}
|
12
|
+
};
|
13
|
+
|
14
|
+
//# sourceMappingURL=translations.js.map
|
@@ -0,0 +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"}
|
package/dist/types.d.ts
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
import { NextAuthOptions } from 'next-auth';
|
2
|
+
import { AuthStrategy } from 'payload/auth';
|
3
|
+
import { Config } from 'payload/config';
|
4
|
+
export type ZitadelPluginProps = {
|
5
|
+
disableLocalStrategy?: true | undefined;
|
6
|
+
disableDefaultLoginButton?: true | undefined;
|
7
|
+
defaultLoginButtonTitle?: string;
|
8
|
+
externalProviderName?: string;
|
9
|
+
} & Partial<ZitadelStrategyProps>;
|
10
|
+
export type ZitadelPluginProviderType = (props: ZitadelPluginProps) => {
|
11
|
+
zitadelPlugin: (incomingConfig: Config) => Config;
|
12
|
+
nextauthHandler: any;
|
13
|
+
};
|
14
|
+
export type ZitadelAuthOptionsProps = {
|
15
|
+
internalProviderName: string;
|
16
|
+
issuerUrl: string;
|
17
|
+
clientId: string;
|
18
|
+
};
|
19
|
+
export type ZitadelAuthOptionsType = (props: ZitadelAuthOptionsProps) => NextAuthOptions;
|
20
|
+
export type ZitadelAPIProps = {
|
21
|
+
enableAPI: true;
|
22
|
+
apiClientId: string;
|
23
|
+
apiKeyId: string;
|
24
|
+
apiKey: string;
|
25
|
+
};
|
26
|
+
export type ZitadelStrategyProps = ZitadelAuthOptionsProps & {
|
27
|
+
authSlug: string;
|
28
|
+
associatedIdFieldName: string;
|
29
|
+
} & (ZitadelAPIProps | {
|
30
|
+
enableAPI?: undefined;
|
31
|
+
} & Partial<ZitadelAPIProps>);
|
32
|
+
export type ZitadelStrategyType = (props: ZitadelStrategyProps) => AuthStrategy;
|
33
|
+
//# sourceMappingURL=types.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,WAAW,CAAA;AACzC,OAAO,EAAC,YAAY,EAAC,MAAM,cAAc,CAAA;AACzC,OAAO,EAAC,MAAM,EAAC,MAAM,gBAAgB,CAAA;AAErC,MAAM,MAAM,kBAAkB,GAAG;IAC7B,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,CAAA;AAExF,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"}
|
package/dist/types.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import {NextAuthOptions} from 'next-auth'\nimport {AuthStrategy} from 'payload/auth'\nimport {Config} from 'payload/config'\n\nexport type ZitadelPluginProps = {\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\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":"AAsCA,WAA+E"}
|
package/package.json
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
{
|
2
|
+
"name": "payload-zitadel-plugin",
|
3
|
+
"version": "0.1.0",
|
4
|
+
"description": "plugin for Payload CMS, which enables authentication via Zitadel IdP",
|
5
|
+
"type": "module",
|
6
|
+
"license": "MIT",
|
7
|
+
"author": {
|
8
|
+
"name": "WALX Tech e.K.",
|
9
|
+
"email": "x@walx.tech",
|
10
|
+
"url": "https://walx.tech"
|
11
|
+
},
|
12
|
+
"contributors": [
|
13
|
+
{
|
14
|
+
"name": "Ш41%",
|
15
|
+
"email": "_@w41x.io",
|
16
|
+
"url": "https://w41x.io"
|
17
|
+
}
|
18
|
+
],
|
19
|
+
"homepage": "https://github.com/w41x/payload-zitadel-plugin#readme",
|
20
|
+
"repository": {
|
21
|
+
"type": "git",
|
22
|
+
"url": "git+https://github.com/w41x/payload-zitadel-plugin.git"
|
23
|
+
},
|
24
|
+
"keywords": [
|
25
|
+
"payload",
|
26
|
+
"cms",
|
27
|
+
"plugin",
|
28
|
+
"zitadel"
|
29
|
+
],
|
30
|
+
"bugs": {
|
31
|
+
"url": "https://github.com/w41x/payload-zitadel-plugin/issues"
|
32
|
+
},
|
33
|
+
"main": "./dist/index.js",
|
34
|
+
"types": "./dist/index.d.ts",
|
35
|
+
"files": [
|
36
|
+
"dist"
|
37
|
+
],
|
38
|
+
"dependencies": {
|
39
|
+
"@payloadcms/translations": "3.0.0-beta.47",
|
40
|
+
"@payloadcms/ui": "3.0.0-beta.47",
|
41
|
+
"jsonwebtoken": "^9.0.2",
|
42
|
+
"next": "^15.0.0-rc.0",
|
43
|
+
"next-auth": "^4.24.7",
|
44
|
+
"payload": "3.0.0-beta.47",
|
45
|
+
"react": "^19.0.0-rc-dfd30974ab-20240613",
|
46
|
+
"react-dom": "^19.0.0-rc-dfd30974ab-20240613"
|
47
|
+
},
|
48
|
+
"devDependencies": {
|
49
|
+
"@swc/cli": "^0.3.12",
|
50
|
+
"@swc/core": "^1.5.29",
|
51
|
+
"@types/jsonwebtoken": "^9.0.6",
|
52
|
+
"@types/node": "^20.14.2",
|
53
|
+
"@types/react": "^18.3.3",
|
54
|
+
"@types/react-dom": "^18.3.0",
|
55
|
+
"rimraf": "^5.0.7",
|
56
|
+
"typescript": "^5.6.0-dev.20240614"
|
57
|
+
},
|
58
|
+
"engines": {
|
59
|
+
"node": "^22.3.0"
|
60
|
+
},
|
61
|
+
"exports": {
|
62
|
+
".": {
|
63
|
+
"import": "./dist/index.js",
|
64
|
+
"require": "./dist/index.js",
|
65
|
+
"types": "./dist/index.d.ts"
|
66
|
+
},
|
67
|
+
"./types": {
|
68
|
+
"import": "./dist/types.js",
|
69
|
+
"require": "./dist/types.js",
|
70
|
+
"types": "./dist/types.d.ts"
|
71
|
+
}
|
72
|
+
},
|
73
|
+
"publishConfig": {
|
74
|
+
"access": "public",
|
75
|
+
"registry": "https://registry.npmjs.org"
|
76
|
+
},
|
77
|
+
"scripts": {
|
78
|
+
"build": "pnpm build:swc && pnpm build:types",
|
79
|
+
"build:swc": "swc src -d dist --config-file .swcrc --strip-leading-paths",
|
80
|
+
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
81
|
+
"clean": "rimraf {dist, tsconfig.tsbuildinfo}"
|
82
|
+
}
|
83
|
+
}
|