Skip to content

Commit d13997e

Browse files
peintnermaxbalazsorban44
andauthoredOct 6, 2022
feat(providers): ZITADEL provider (#5479)
* feat: zitadel provider * Update packages/next-auth/src/providers/zitadel.ts Co-authored-by: Balázs Orbán <info@balazsorban.com> * Update packages/next-auth/src/providers/zitadel.ts Co-authored-by: Balázs Orbán <info@balazsorban.com> Co-authored-by: Balázs Orbán <info@balazsorban.com>
1 parent d6efda0 commit d13997e

File tree

3 files changed

+140
-0
lines changed

3 files changed

+140
-0
lines changed
 

‎apps/dev/pages/api/auth/[...nextauth].ts

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import Twitter, { TwitterLegacy } from "next-auth/providers/twitter"
3535
import Vk from "next-auth/providers/vk"
3636
import Wikimedia from "next-auth/providers/wikimedia"
3737
import WorkOS from "next-auth/providers/workos"
38+
import Zitadel from "next-auth/providers/zitadel"
3839

3940
// Adapters
4041
import { PrismaClient } from "@prisma/client"
@@ -120,6 +121,7 @@ export const authOptions: NextAuthOptions = {
120121
Vk({ clientId: process.env.VK_ID, clientSecret: process.env.VK_SECRET }),
121122
Wikimedia({ clientId: process.env.WIKIMEDIA_ID, clientSecret: process.env.WIKIMEDIA_SECRET }),
122123
WorkOS({ clientId: process.env.WORKOS_ID, clientSecret: process.env.WORKOS_SECRET }),
124+
Zitadel({ issuer: process.env.ZITADEL_ISSUER, clientId: process.env.ZITADEL_CLIENT_ID, clientSecret: process.env.ZITADEL_CLIENT_SECRET }),
123125
],
124126
}
125127

‎docs/docs/providers/zitadel.md

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
id: zitadel
3+
title: Zitadel
4+
---
5+
6+
## Documentation
7+
8+
https://docs.zitadel.com/docs/apis/openidoauth/endpoints
9+
10+
## Configuration
11+
12+
https://docs.zitadel.com/docs/guides/integrate/oauth-recommended-flows
13+
14+
The Redirect URIs used when creating the credentials must include your full domain and end in the callback path. For example:
15+
16+
- For production: `https://{YOUR_DOMAIN}/api/auth/callback/zitadel`
17+
- For development: `http://localhost:3000/api/auth/callback/zitadel`
18+
19+
Make sure to enable **dev mode** in ZITADEL console to allow redirects for local development.
20+
21+
## Options
22+
23+
The **ZITADEL Provider** comes with a set of default options:
24+
25+
- [ZITADEL Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/zitadel.ts)
26+
27+
You can override any of the options to suit your own use case.
28+
29+
## Example
30+
31+
```js
32+
import ZitadelProvider from "next-auth/providers/zitadel";
33+
...
34+
providers: [
35+
ZitadelProvider({
36+
issuer: process.env.ZITADEL_ISSUER,
37+
clientId: process.env.ZITADEL_CLIENT_ID,
38+
clientSecret: process.env.ZITADEL_CLIENT_SECRET,
39+
})
40+
]
41+
...
42+
```
43+
44+
If you need access to ZITADEL APIs or need additional information, make sure to add the corresponding scopes.
45+
46+
To get the full list of supported claims take a look [here](https://docs.zitadel.com/docs/apis/openidoauth/endpoints).
47+
48+
```js
49+
const options = {
50+
...
51+
providers: [
52+
ZitadelProvider({
53+
clientId: process.env.ZITADEL_CLIENT_ID,
54+
authorization: {
55+
params: {
56+
scope: `openid email profile urn:zitadel:iam:org:project:id:${process.env.ZITADEL_PROJECT_ID}:aud`
57+
}
58+
}
59+
})
60+
],
61+
...
62+
}
63+
```
64+
65+
:::
66+
67+
:::tip
68+
ZITADEL also returns a `email_verified` boolean property in the profile.
69+
70+
You can use this property to restrict access to people with verified accounts.
71+
72+
```js
73+
const options = {
74+
...
75+
callbacks: {
76+
async signIn({ account, profile }) {
77+
if (account.provider === "zitadel") {
78+
return profile.email_verified;
79+
}
80+
return true; // Do different verification for other providers that don't have `email_verified`
81+
},
82+
}
83+
...
84+
}
85+
```
86+
87+
:::
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import type { OAuthConfig, OAuthUserConfig } from "."
2+
3+
export interface ZitadelProfile extends Record<string, any> {
4+
amr: string // Authentication Method References as defined in RFC8176
5+
aud: string // The audience of the token, by default all client id's and the project id are included
6+
auth_time: number // Unix time of the authentication
7+
azp: string // Client id of the client who requested the token
8+
email: string // Email Address of the subject
9+
email_verified: boolean // if the email was verified by ZITADEL
10+
exp: number // Time the token expires (as unix time)
11+
family_name: string // The subjects family name
12+
given_name: string // Given name of the subject
13+
gender: string // Gender of the subject
14+
iat: number // Time of the token was issued at (as unix time)
15+
iss: string // Issuing domain of a token
16+
jti: string // Unique id of the token
17+
locale: string // Language from the subject
18+
name: string // The subjects full name
19+
nbf: number // Time the token must not be used before (as unix time)
20+
picture: string // The subjects profile picture
21+
phone: string // Phone number provided by the user
22+
phone_verified: boolean // if the phonenumber was verified by ZITADEL
23+
preferred_username: string // ZITADEL's login name of the user. Consist of username@primarydomain
24+
sub: string // Subject ID of the user
25+
}
26+
27+
export default function Zitadel<P extends ZitadelProfile>(
28+
options: OAuthUserConfig<P>
29+
): OAuthConfig<P> {
30+
const { issuer } = options
31+
32+
return {
33+
id: "zitadel",
34+
name: "ZITADEL",
35+
type: "oauth",
36+
version: "2",
37+
wellKnown: `${issuer}/.well-known/openid-configuration`,
38+
authorization: { params: { scope: "openid email profile" } },
39+
idToken: true,
40+
checks: ["pkce", "state"],
41+
async profile(profile) {
42+
return {
43+
id: profile.sub,
44+
name: profile.name,
45+
email: profile.email,
46+
image: profile.picture,
47+
}
48+
},
49+
options,
50+
}
51+
}

1 commit comments

Comments
 (1)
Please sign in to comment.