@draftlab/auth 0.15.0 → 0.16.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/dist/esm/allow.js +26 -0
- package/dist/esm/client.js +254 -0
- package/dist/esm/core.js +597 -0
- package/dist/esm/css.d.js +0 -0
- package/dist/esm/error.js +88 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/keys.js +126 -0
- package/dist/esm/mutex.js +53 -0
- package/dist/esm/pkce.js +87 -0
- package/dist/esm/provider/apple.js +15 -0
- package/dist/esm/provider/code.js +62 -0
- package/dist/esm/provider/discord.js +15 -0
- package/dist/esm/provider/facebook.js +15 -0
- package/dist/esm/provider/github.js +15 -0
- package/dist/esm/provider/gitlab.js +15 -0
- package/dist/esm/provider/google.js +16 -0
- package/dist/esm/provider/linkedin.js +15 -0
- package/dist/esm/provider/magiclink.js +83 -0
- package/dist/esm/provider/microsoft.js +15 -0
- package/dist/esm/provider/oauth2.js +130 -0
- package/dist/esm/provider/password.js +331 -0
- package/dist/esm/provider/provider.js +18 -0
- package/dist/esm/provider/reddit.js +15 -0
- package/dist/esm/provider/slack.js +15 -0
- package/dist/esm/provider/spotify.js +15 -0
- package/dist/esm/provider/twitch.js +15 -0
- package/dist/esm/provider/vercel.js +17 -0
- package/dist/esm/random.js +40 -0
- package/dist/esm/revocation.js +27 -0
- package/dist/esm/storage/memory.js +110 -0
- package/dist/esm/storage/storage.js +56 -0
- package/dist/esm/storage/turso.js +93 -0
- package/dist/esm/storage/unstorage.js +78 -0
- package/dist/esm/subject.js +7 -0
- package/dist/esm/themes/theme.js +115 -0
- package/dist/esm/toolkit/client.js +119 -0
- package/dist/esm/toolkit/index.js +25 -0
- package/dist/esm/toolkit/providers/facebook.js +11 -0
- package/dist/esm/toolkit/providers/github.js +11 -0
- package/dist/esm/toolkit/providers/google.js +11 -0
- package/dist/esm/toolkit/providers/strategy.js +0 -0
- package/dist/esm/toolkit/storage.js +81 -0
- package/dist/esm/toolkit/utils.js +18 -0
- package/dist/esm/types.js +0 -0
- package/dist/esm/ui/base.js +478 -0
- package/dist/esm/ui/code.js +186 -0
- package/dist/esm/ui/form.js +46 -0
- package/dist/esm/ui/icon.js +242 -0
- package/dist/esm/ui/magiclink.js +158 -0
- package/dist/esm/ui/password.js +435 -0
- package/dist/esm/ui/select.js +102 -0
- package/dist/esm/util.js +59 -0
- package/dist/{allow.d.mts → types/allow.d.ts} +9 -11
- package/dist/types/allow.d.ts.map +1 -0
- package/dist/types/client.d.ts +462 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/core.d.ts +113 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/{error.d.mts → types/error.d.ts} +95 -97
- package/dist/types/error.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/{keys.d.mts → types/keys.d.ts} +20 -24
- package/dist/types/keys.d.ts.map +1 -0
- package/dist/types/mutex.d.ts +42 -0
- package/dist/types/mutex.d.ts.map +1 -0
- package/dist/{pkce.d.mts → types/pkce.d.ts} +10 -11
- package/dist/types/pkce.d.ts.map +1 -0
- package/dist/types/provider/apple.d.ts +197 -0
- package/dist/types/provider/apple.d.ts.map +1 -0
- package/dist/types/provider/code.d.ts +288 -0
- package/dist/types/provider/code.d.ts.map +1 -0
- package/dist/types/provider/discord.d.ts +206 -0
- package/dist/types/provider/discord.d.ts.map +1 -0
- package/dist/types/provider/facebook.d.ts +200 -0
- package/dist/types/provider/facebook.d.ts.map +1 -0
- package/dist/types/provider/github.d.ts +220 -0
- package/dist/types/provider/github.d.ts.map +1 -0
- package/dist/types/provider/gitlab.d.ts +180 -0
- package/dist/types/provider/gitlab.d.ts.map +1 -0
- package/dist/types/provider/google.d.ts +158 -0
- package/dist/types/provider/google.d.ts.map +1 -0
- package/dist/types/provider/linkedin.d.ts +190 -0
- package/dist/types/provider/linkedin.d.ts.map +1 -0
- package/dist/types/provider/magiclink.d.ts +141 -0
- package/dist/types/provider/magiclink.d.ts.map +1 -0
- package/dist/types/provider/microsoft.d.ts +247 -0
- package/dist/types/provider/microsoft.d.ts.map +1 -0
- package/dist/types/provider/oauth2.d.ts +229 -0
- package/dist/types/provider/oauth2.d.ts.map +1 -0
- package/dist/types/provider/password.d.ts +408 -0
- package/dist/types/provider/password.d.ts.map +1 -0
- package/dist/types/provider/provider.d.ts +226 -0
- package/dist/types/provider/provider.d.ts.map +1 -0
- package/dist/types/provider/reddit.d.ts +159 -0
- package/dist/types/provider/reddit.d.ts.map +1 -0
- package/dist/types/provider/slack.d.ts +171 -0
- package/dist/types/provider/slack.d.ts.map +1 -0
- package/dist/types/provider/spotify.d.ts +168 -0
- package/dist/types/provider/spotify.d.ts.map +1 -0
- package/dist/types/provider/twitch.d.ts +163 -0
- package/dist/types/provider/twitch.d.ts.map +1 -0
- package/dist/types/provider/vercel.d.ts +294 -0
- package/dist/types/provider/vercel.d.ts.map +1 -0
- package/dist/{random.d.mts → types/random.d.ts} +4 -6
- package/dist/types/random.d.ts.map +1 -0
- package/dist/types/revocation.d.ts +76 -0
- package/dist/types/revocation.d.ts.map +1 -0
- package/dist/{storage/memory.d.mts → types/storage/memory.d.ts} +17 -21
- package/dist/types/storage/memory.d.ts.map +1 -0
- package/dist/types/storage/storage.d.ts +177 -0
- package/dist/types/storage/storage.d.ts.map +1 -0
- package/dist/{storage/turso.d.mts → types/storage/turso.d.ts} +4 -8
- package/dist/types/storage/turso.d.ts.map +1 -0
- package/dist/{storage/unstorage.d.mts → types/storage/unstorage.d.ts} +12 -11
- package/dist/types/storage/unstorage.d.ts.map +1 -0
- package/dist/types/subject.d.ts +115 -0
- package/dist/types/subject.d.ts.map +1 -0
- package/dist/types/themes/theme.d.ts +207 -0
- package/dist/types/themes/theme.d.ts.map +1 -0
- package/dist/types/toolkit/client.d.ts +235 -0
- package/dist/types/toolkit/client.d.ts.map +1 -0
- package/dist/types/toolkit/index.d.ts +45 -0
- package/dist/types/toolkit/index.d.ts.map +1 -0
- package/dist/types/toolkit/providers/facebook.d.ts +8 -0
- package/dist/types/toolkit/providers/facebook.d.ts.map +1 -0
- package/dist/types/toolkit/providers/github.d.ts +8 -0
- package/dist/types/toolkit/providers/github.d.ts.map +1 -0
- package/dist/types/toolkit/providers/google.d.ts +8 -0
- package/dist/types/toolkit/providers/google.d.ts.map +1 -0
- package/dist/types/toolkit/providers/strategy.d.ts +38 -0
- package/dist/types/toolkit/providers/strategy.d.ts.map +1 -0
- package/dist/{toolkit/storage.d.mts → types/toolkit/storage.d.ts} +37 -39
- package/dist/types/toolkit/storage.d.ts.map +1 -0
- package/dist/{toolkit/utils.d.mts → types/toolkit/utils.d.ts} +2 -4
- package/dist/types/toolkit/utils.d.ts.map +1 -0
- package/dist/types/types.d.ts +92 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/ui/base.d.ts +18 -0
- package/dist/types/ui/base.d.ts.map +1 -0
- package/dist/types/ui/code.d.ts +43 -0
- package/dist/types/ui/code.d.ts.map +1 -0
- package/dist/types/ui/form.d.ts +24 -0
- package/dist/types/ui/form.d.ts.map +1 -0
- package/dist/types/ui/icon.d.ts +60 -0
- package/dist/types/ui/icon.d.ts.map +1 -0
- package/dist/types/ui/magiclink.d.ts +41 -0
- package/dist/types/ui/magiclink.d.ts.map +1 -0
- package/dist/types/ui/password.d.ts +43 -0
- package/dist/types/ui/password.d.ts.map +1 -0
- package/dist/types/ui/select.d.ts +33 -0
- package/dist/types/ui/select.d.ts.map +1 -0
- package/dist/{util.d.mts → types/util.d.ts} +11 -13
- package/dist/types/util.d.ts.map +1 -0
- package/package.json +10 -16
- package/dist/adapters/node.d.mts +0 -18
- package/dist/adapters/node.mjs +0 -69
- package/dist/allow.mjs +0 -63
- package/dist/client.d.mts +0 -456
- package/dist/client.mjs +0 -283
- package/dist/core.d.mts +0 -110
- package/dist/core.mjs +0 -595
- package/dist/error.mjs +0 -237
- package/dist/index.d.mts +0 -2
- package/dist/index.mjs +0 -3
- package/dist/keys.mjs +0 -146
- package/dist/mutex.d.mts +0 -44
- package/dist/mutex.mjs +0 -110
- package/dist/pkce.mjs +0 -157
- package/dist/provider/apple.d.mts +0 -111
- package/dist/provider/apple.mjs +0 -164
- package/dist/provider/code.d.mts +0 -228
- package/dist/provider/code.mjs +0 -246
- package/dist/provider/discord.d.mts +0 -146
- package/dist/provider/discord.mjs +0 -156
- package/dist/provider/facebook.d.mts +0 -142
- package/dist/provider/facebook.mjs +0 -150
- package/dist/provider/github.d.mts +0 -140
- package/dist/provider/github.mjs +0 -169
- package/dist/provider/gitlab.d.mts +0 -106
- package/dist/provider/gitlab.mjs +0 -147
- package/dist/provider/google.d.mts +0 -112
- package/dist/provider/google.mjs +0 -109
- package/dist/provider/linkedin.d.mts +0 -132
- package/dist/provider/linkedin.mjs +0 -142
- package/dist/provider/magiclink.d.mts +0 -89
- package/dist/provider/magiclink.mjs +0 -143
- package/dist/provider/microsoft.d.mts +0 -178
- package/dist/provider/microsoft.mjs +0 -177
- package/dist/provider/oauth2.d.mts +0 -176
- package/dist/provider/oauth2.mjs +0 -222
- package/dist/provider/passkey.d.mts +0 -104
- package/dist/provider/passkey.mjs +0 -320
- package/dist/provider/password.d.mts +0 -412
- package/dist/provider/password.mjs +0 -363
- package/dist/provider/provider.d.mts +0 -227
- package/dist/provider/provider.mjs +0 -44
- package/dist/provider/reddit.d.mts +0 -107
- package/dist/provider/reddit.mjs +0 -127
- package/dist/provider/slack.d.mts +0 -114
- package/dist/provider/slack.mjs +0 -138
- package/dist/provider/spotify.d.mts +0 -113
- package/dist/provider/spotify.mjs +0 -135
- package/dist/provider/totp.d.mts +0 -112
- package/dist/provider/totp.mjs +0 -191
- package/dist/provider/twitch.d.mts +0 -108
- package/dist/provider/twitch.mjs +0 -131
- package/dist/provider/vercel.d.mts +0 -177
- package/dist/provider/vercel.mjs +0 -230
- package/dist/random.mjs +0 -86
- package/dist/revocation.d.mts +0 -55
- package/dist/revocation.mjs +0 -63
- package/dist/router/context.d.mts +0 -21
- package/dist/router/context.mjs +0 -193
- package/dist/router/cookies.d.mts +0 -8
- package/dist/router/cookies.mjs +0 -13
- package/dist/router/index.d.mts +0 -21
- package/dist/router/index.mjs +0 -107
- package/dist/router/matcher.d.mts +0 -15
- package/dist/router/matcher.mjs +0 -76
- package/dist/router/middleware/cors.d.mts +0 -15
- package/dist/router/middleware/cors.mjs +0 -114
- package/dist/router/safe-request.d.mts +0 -52
- package/dist/router/safe-request.mjs +0 -160
- package/dist/router/types.d.mts +0 -67
- package/dist/router/types.mjs +0 -1
- package/dist/router/variables.d.mts +0 -12
- package/dist/router/variables.mjs +0 -20
- package/dist/storage/memory.mjs +0 -125
- package/dist/storage/storage.d.mts +0 -179
- package/dist/storage/storage.mjs +0 -104
- package/dist/storage/turso.mjs +0 -117
- package/dist/storage/unstorage.mjs +0 -103
- package/dist/subject.d.mts +0 -62
- package/dist/subject.mjs +0 -36
- package/dist/themes/theme.d.mts +0 -209
- package/dist/themes/theme.mjs +0 -120
- package/dist/toolkit/client.d.mts +0 -169
- package/dist/toolkit/client.mjs +0 -209
- package/dist/toolkit/index.d.mts +0 -9
- package/dist/toolkit/index.mjs +0 -9
- package/dist/toolkit/providers/facebook.d.mts +0 -12
- package/dist/toolkit/providers/facebook.mjs +0 -16
- package/dist/toolkit/providers/github.d.mts +0 -12
- package/dist/toolkit/providers/github.mjs +0 -16
- package/dist/toolkit/providers/google.d.mts +0 -12
- package/dist/toolkit/providers/google.mjs +0 -20
- package/dist/toolkit/providers/strategy.d.mts +0 -40
- package/dist/toolkit/providers/strategy.mjs +0 -1
- package/dist/toolkit/storage.mjs +0 -157
- package/dist/toolkit/utils.mjs +0 -30
- package/dist/types.d.mts +0 -94
- package/dist/types.mjs +0 -1
- package/dist/ui/base.d.mts +0 -30
- package/dist/ui/base.mjs +0 -407
- package/dist/ui/code.d.mts +0 -43
- package/dist/ui/code.mjs +0 -173
- package/dist/ui/form.d.mts +0 -32
- package/dist/ui/form.mjs +0 -49
- package/dist/ui/icon.d.mts +0 -58
- package/dist/ui/icon.mjs +0 -247
- package/dist/ui/magiclink.d.mts +0 -41
- package/dist/ui/magiclink.mjs +0 -152
- package/dist/ui/passkey.d.mts +0 -27
- package/dist/ui/passkey.mjs +0 -323
- package/dist/ui/password.d.mts +0 -42
- package/dist/ui/password.mjs +0 -402
- package/dist/ui/select.d.mts +0 -34
- package/dist/ui/select.mjs +0 -98
- package/dist/ui/totp.d.mts +0 -34
- package/dist/ui/totp.mjs +0 -270
- package/dist/util.mjs +0 -128
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { Provider } from "./provider.mjs";
|
|
2
|
-
import { Oauth2UserData, Oauth2WrappedConfig } from "./oauth2.mjs";
|
|
3
|
-
|
|
4
|
-
//#region src/provider/apple.d.ts
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Configuration options for Apple OAuth 2.0 provider.
|
|
8
|
-
* Extends the base OAuth 2.0 configuration with Apple-specific documentation.
|
|
9
|
-
*/
|
|
10
|
-
interface AppleConfig extends Oauth2WrappedConfig {
|
|
11
|
-
/**
|
|
12
|
-
* Apple Service ID (app identifier for your Sign in with Apple implementation).
|
|
13
|
-
* Get this from your Apple Developer account when creating a Service ID.
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```ts
|
|
17
|
-
* {
|
|
18
|
-
* clientID: "com.example.app.signin"
|
|
19
|
-
* }
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
readonly clientID: string;
|
|
23
|
-
/**
|
|
24
|
-
* Apple client secret (JWT token signed with your private key).
|
|
25
|
-
* This is different from other providers - Apple requires a JWT token
|
|
26
|
-
* generated from your private key.
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```ts
|
|
30
|
-
* {
|
|
31
|
-
* clientSecret: process.env.APPLE_CLIENT_SECRET
|
|
32
|
-
* }
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
readonly clientSecret: string;
|
|
36
|
-
/**
|
|
37
|
-
* Apple OAuth scopes to request access for.
|
|
38
|
-
* Apple only supports "name" and "email" scopes.
|
|
39
|
-
*
|
|
40
|
-
* Important: Apple only provides user data (name, email) on the FIRST authorization.
|
|
41
|
-
* Subsequent authorizations won't include this data.
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* ```ts
|
|
45
|
-
* {
|
|
46
|
-
* scopes: ["name", "email"]
|
|
47
|
-
* }
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
readonly scopes: string[];
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Creates an Apple OAuth 2.0 authentication provider.
|
|
54
|
-
* Allows users to authenticate using their Apple accounts.
|
|
55
|
-
*
|
|
56
|
-
* @param config - Apple OAuth 2.0 configuration
|
|
57
|
-
* @returns OAuth 2.0 provider configured for Apple
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* ```ts
|
|
61
|
-
* // Basic Apple authentication
|
|
62
|
-
* const basicApple = AppleProvider({
|
|
63
|
-
* clientID: process.env.APPLE_CLIENT_ID,
|
|
64
|
-
* clientSecret: process.env.APPLE_CLIENT_SECRET
|
|
65
|
-
* })
|
|
66
|
-
*
|
|
67
|
-
* // Apple with name and email scopes
|
|
68
|
-
* const appleWithScopes = AppleProvider({
|
|
69
|
-
* clientID: process.env.APPLE_CLIENT_ID,
|
|
70
|
-
* clientSecret: process.env.APPLE_CLIENT_SECRET,
|
|
71
|
-
* scopes: ["name", "email"]
|
|
72
|
-
* })
|
|
73
|
-
*
|
|
74
|
-
* // Using the tokens and id_token
|
|
75
|
-
* export default issuer({
|
|
76
|
-
* providers: { apple: appleWithScopes },
|
|
77
|
-
* success: async (ctx, value) => {
|
|
78
|
-
* if (value.provider === "apple") {
|
|
79
|
-
* // Apple returns user data in the initial authorization response
|
|
80
|
-
* // You need to decode the id_token to extract user information
|
|
81
|
-
*
|
|
82
|
-
* // The id_token contains:
|
|
83
|
-
* // - sub: unique Apple user identifier
|
|
84
|
-
* // - email: user email (only on first authorization)
|
|
85
|
-
* // - email_verified: whether email is verified
|
|
86
|
-
* // - is_private_email: whether user used private relay
|
|
87
|
-
*
|
|
88
|
-
* // Decode and verify the id_token using jose:
|
|
89
|
-
* // const verified = await jwtVerify(value.tokenset.id, jwks)
|
|
90
|
-
* // const user = verified.payload
|
|
91
|
-
*
|
|
92
|
-
* return ctx.subject("user", {
|
|
93
|
-
* appleId: user.sub,
|
|
94
|
-
* email: user.email,
|
|
95
|
-
* emailVerified: user.email_verified,
|
|
96
|
-
* isPrivateEmail: user.is_private_email
|
|
97
|
-
* })
|
|
98
|
-
* }
|
|
99
|
-
* }
|
|
100
|
-
* })
|
|
101
|
-
* ```
|
|
102
|
-
*
|
|
103
|
-
* **Callback URL Pattern**: `{baseURL}{basePath}/{provider}/callback`
|
|
104
|
-
* - Development: `http://localhost:3000/auth/apple/callback`
|
|
105
|
-
* - Production: `https://yourapp.com/auth/apple/callback`
|
|
106
|
-
*
|
|
107
|
-
* Register this URL in your Apple Developer Portal.
|
|
108
|
-
*/
|
|
109
|
-
declare const AppleProvider: (config: AppleConfig) => Provider<Oauth2UserData>;
|
|
110
|
-
//#endregion
|
|
111
|
-
export { AppleConfig, AppleProvider };
|
package/dist/provider/apple.mjs
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { Oauth2Provider } from "./oauth2.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/provider/apple.ts
|
|
4
|
-
/**
|
|
5
|
-
* Apple authentication provider for Draft Auth.
|
|
6
|
-
* Implements OAuth 2.0 flow for authenticating users with their Apple accounts.
|
|
7
|
-
*
|
|
8
|
-
* ## Quick Setup
|
|
9
|
-
*
|
|
10
|
-
* ```ts
|
|
11
|
-
* import { AppleProvider } from "@draftlab/auth/provider/apple"
|
|
12
|
-
*
|
|
13
|
-
* export default issuer({
|
|
14
|
-
* basePath: "/auth", // Important for callback URL
|
|
15
|
-
* providers: {
|
|
16
|
-
* apple: AppleProvider({
|
|
17
|
-
* clientID: process.env.APPLE_CLIENT_ID,
|
|
18
|
-
* clientSecret: process.env.APPLE_CLIENT_SECRET,
|
|
19
|
-
* scopes: ["name", "email"]
|
|
20
|
-
* })
|
|
21
|
-
* }
|
|
22
|
-
* })
|
|
23
|
-
* ```
|
|
24
|
-
*
|
|
25
|
-
* **Callback URL Pattern**: `{baseURL}{basePath}/{provider}/callback`
|
|
26
|
-
* - Development: `http://localhost:3000/auth/apple/callback`
|
|
27
|
-
* - Production: `https://yourapp.com/auth/apple/callback`
|
|
28
|
-
*
|
|
29
|
-
* Register this URL in your Apple Developer Portal.
|
|
30
|
-
*
|
|
31
|
-
* ## Setup Instructions
|
|
32
|
-
*
|
|
33
|
-
* ### 1. Create App ID
|
|
34
|
-
* - Go to [Apple Developer](https://developer.apple.com)
|
|
35
|
-
* - Create a new App ID with "Sign in with Apple" capability
|
|
36
|
-
*
|
|
37
|
-
* ### 2. Create Service ID
|
|
38
|
-
* - Create a new Service ID (this is your clientID)
|
|
39
|
-
* - Configure "Sign in with Apple"
|
|
40
|
-
* - Add your redirect URI
|
|
41
|
-
*
|
|
42
|
-
* ### 3. Create Private Key
|
|
43
|
-
* - Create a private key for "Sign in with Apple"
|
|
44
|
-
* - Download the .p8 file (this is used to create your clientSecret)
|
|
45
|
-
*
|
|
46
|
-
* ## Client Secret Generation
|
|
47
|
-
*
|
|
48
|
-
* Apple requires a JWT token as the client secret. You'll need:
|
|
49
|
-
* - Key ID from the private key
|
|
50
|
-
* - Team ID from your Apple Developer account
|
|
51
|
-
* - Private key (.p8 file)
|
|
52
|
-
*
|
|
53
|
-
* Use a library to generate the JWT (valid for ~15 minutes):
|
|
54
|
-
*
|
|
55
|
-
* ```ts
|
|
56
|
-
* import { SignJWT } from "jose"
|
|
57
|
-
*
|
|
58
|
-
* const secret = await new SignJWT({
|
|
59
|
-
* iss: "YOUR_TEAM_ID",
|
|
60
|
-
* aud: "https://appleid.apple.com",
|
|
61
|
-
* sub: process.env.APPLE_CLIENT_ID,
|
|
62
|
-
* iat: Math.floor(Date.now() / 1000),
|
|
63
|
-
* exp: Math.floor(Date.now() / 1000) + 15 * 60
|
|
64
|
-
* })
|
|
65
|
-
* .setProtectedHeader({ alg: "ES256", kid: "YOUR_KEY_ID" })
|
|
66
|
-
* .sign(privateKey)
|
|
67
|
-
* ```
|
|
68
|
-
*
|
|
69
|
-
* ## Common Scopes
|
|
70
|
-
*
|
|
71
|
-
* - `name` - Access user's name (first and last name)
|
|
72
|
-
* - `email` - Access user's email address
|
|
73
|
-
*
|
|
74
|
-
* Note: Apple only returns user data on the first authorization. Subsequent authorizations won't include name/email.
|
|
75
|
-
*
|
|
76
|
-
* ## User Data Access
|
|
77
|
-
*
|
|
78
|
-
* ```ts
|
|
79
|
-
* success: async (ctx, value) => {
|
|
80
|
-
* if (value.provider === "apple") {
|
|
81
|
-
* const accessToken = value.tokenset.access
|
|
82
|
-
*
|
|
83
|
-
* // Apple doesn't provide a userinfo endpoint
|
|
84
|
-
* // User data is returned in the authorization response
|
|
85
|
-
* // You need to parse the id_token JWT to get user info
|
|
86
|
-
*
|
|
87
|
-
* // For subsequent logins without name/email, use the subject (user_id)
|
|
88
|
-
* // from the ID token to identify the user
|
|
89
|
-
* }
|
|
90
|
-
* }
|
|
91
|
-
* ```
|
|
92
|
-
*
|
|
93
|
-
* @packageDocumentation
|
|
94
|
-
*/
|
|
95
|
-
/**
|
|
96
|
-
* Creates an Apple OAuth 2.0 authentication provider.
|
|
97
|
-
* Allows users to authenticate using their Apple accounts.
|
|
98
|
-
*
|
|
99
|
-
* @param config - Apple OAuth 2.0 configuration
|
|
100
|
-
* @returns OAuth 2.0 provider configured for Apple
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* ```ts
|
|
104
|
-
* // Basic Apple authentication
|
|
105
|
-
* const basicApple = AppleProvider({
|
|
106
|
-
* clientID: process.env.APPLE_CLIENT_ID,
|
|
107
|
-
* clientSecret: process.env.APPLE_CLIENT_SECRET
|
|
108
|
-
* })
|
|
109
|
-
*
|
|
110
|
-
* // Apple with name and email scopes
|
|
111
|
-
* const appleWithScopes = AppleProvider({
|
|
112
|
-
* clientID: process.env.APPLE_CLIENT_ID,
|
|
113
|
-
* clientSecret: process.env.APPLE_CLIENT_SECRET,
|
|
114
|
-
* scopes: ["name", "email"]
|
|
115
|
-
* })
|
|
116
|
-
*
|
|
117
|
-
* // Using the tokens and id_token
|
|
118
|
-
* export default issuer({
|
|
119
|
-
* providers: { apple: appleWithScopes },
|
|
120
|
-
* success: async (ctx, value) => {
|
|
121
|
-
* if (value.provider === "apple") {
|
|
122
|
-
* // Apple returns user data in the initial authorization response
|
|
123
|
-
* // You need to decode the id_token to extract user information
|
|
124
|
-
*
|
|
125
|
-
* // The id_token contains:
|
|
126
|
-
* // - sub: unique Apple user identifier
|
|
127
|
-
* // - email: user email (only on first authorization)
|
|
128
|
-
* // - email_verified: whether email is verified
|
|
129
|
-
* // - is_private_email: whether user used private relay
|
|
130
|
-
*
|
|
131
|
-
* // Decode and verify the id_token using jose:
|
|
132
|
-
* // const verified = await jwtVerify(value.tokenset.id, jwks)
|
|
133
|
-
* // const user = verified.payload
|
|
134
|
-
*
|
|
135
|
-
* return ctx.subject("user", {
|
|
136
|
-
* appleId: user.sub,
|
|
137
|
-
* email: user.email,
|
|
138
|
-
* emailVerified: user.email_verified,
|
|
139
|
-
* isPrivateEmail: user.is_private_email
|
|
140
|
-
* })
|
|
141
|
-
* }
|
|
142
|
-
* }
|
|
143
|
-
* })
|
|
144
|
-
* ```
|
|
145
|
-
*
|
|
146
|
-
* **Callback URL Pattern**: `{baseURL}{basePath}/{provider}/callback`
|
|
147
|
-
* - Development: `http://localhost:3000/auth/apple/callback`
|
|
148
|
-
* - Production: `https://yourapp.com/auth/apple/callback`
|
|
149
|
-
*
|
|
150
|
-
* Register this URL in your Apple Developer Portal.
|
|
151
|
-
*/
|
|
152
|
-
const AppleProvider = (config) => {
|
|
153
|
-
return Oauth2Provider({
|
|
154
|
-
...config,
|
|
155
|
-
type: "apple",
|
|
156
|
-
endpoint: {
|
|
157
|
-
authorization: "https://appleid.apple.com/auth/authorize",
|
|
158
|
-
token: "https://appleid.apple.com/auth/token"
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
//#endregion
|
|
164
|
-
export { AppleProvider };
|
package/dist/provider/code.d.mts
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import { Provider } from "./provider.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/provider/code.d.ts
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Configuration options for the PIN code authentication provider.
|
|
7
|
-
*
|
|
8
|
-
* @template Claims - Type of claims collected during authentication (email, phone, etc.)
|
|
9
|
-
*/
|
|
10
|
-
interface CodeProviderConfig<Claims extends Record<string, string> = Record<string, string>> {
|
|
11
|
-
/**
|
|
12
|
-
* The length of the generated PIN code.
|
|
13
|
-
* Common values are 4, 6, or 8 digits.
|
|
14
|
-
*
|
|
15
|
-
* @default 6
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* ```ts
|
|
19
|
-
* {
|
|
20
|
-
* length: 4 // 4-digit PIN for easier entry
|
|
21
|
-
* }
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
readonly length?: number;
|
|
25
|
-
/**
|
|
26
|
-
* Request handler for rendering the authentication UI.
|
|
27
|
-
* Handles both the initial claim collection and PIN code entry screens.
|
|
28
|
-
*
|
|
29
|
-
* @param req - The HTTP request object
|
|
30
|
-
* @param state - Current authentication state (start or code verification)
|
|
31
|
-
* @param form - Form data from POST requests (if any)
|
|
32
|
-
* @param error - Authentication error to display (if any)
|
|
33
|
-
* @returns Promise resolving to the authentication page response
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```ts
|
|
37
|
-
* request: async (req, state, form, error) => {
|
|
38
|
-
* if (state.type === 'start') {
|
|
39
|
-
* return new Response(renderClaimForm(form, error))
|
|
40
|
-
* } else {
|
|
41
|
-
* return new Response(renderCodeForm(state.claims.email, error))
|
|
42
|
-
* }
|
|
43
|
-
* }
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
request: (req: Request, state: CodeProviderState, form?: FormData, error?: CodeProviderError) => Promise<Response>;
|
|
47
|
-
/**
|
|
48
|
-
* Callback for sending PIN codes to users via their preferred method.
|
|
49
|
-
* Should handle delivery via email, SMS, or other communication channels.
|
|
50
|
-
*
|
|
51
|
-
* @param claims - User claims containing contact information
|
|
52
|
-
* @param code - The generated PIN code to send
|
|
53
|
-
* @returns Promise resolving to undefined on success, or error object on failure
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* ```ts
|
|
57
|
-
* sendCode: async (claims, code) => {
|
|
58
|
-
* try {
|
|
59
|
-
* if (claims.email) {
|
|
60
|
-
* await emailService.send({
|
|
61
|
-
* to: claims.email,
|
|
62
|
-
* subject: 'Your verification code',
|
|
63
|
-
* text: `Your PIN code is: ${code}`
|
|
64
|
-
* })
|
|
65
|
-
* } else if (claims.phone) {
|
|
66
|
-
* await smsService.send(claims.phone, `PIN: ${code}`)
|
|
67
|
-
* } else {
|
|
68
|
-
* return {
|
|
69
|
-
* type: "invalid_claim",
|
|
70
|
-
* key: "email",
|
|
71
|
-
* value: "Email or phone number is required"
|
|
72
|
-
* }
|
|
73
|
-
* }
|
|
74
|
-
* } catch (error) {
|
|
75
|
-
* return {
|
|
76
|
-
* type: "invalid_claim",
|
|
77
|
-
* key: "delivery",
|
|
78
|
-
* value: "Failed to send code"
|
|
79
|
-
* }
|
|
80
|
-
* }
|
|
81
|
-
* }
|
|
82
|
-
* ```
|
|
83
|
-
*/
|
|
84
|
-
sendCode: (claims: Claims, code: string) => Promise<CodeProviderError | undefined>;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Authentication flow states for the PIN code provider.
|
|
88
|
-
* The provider transitions between these states during authentication.
|
|
89
|
-
*/
|
|
90
|
-
type CodeProviderState = {
|
|
91
|
-
/** Initial state: user enters their claims (email, phone, etc.) */
|
|
92
|
-
readonly type: "start";
|
|
93
|
-
} | {
|
|
94
|
-
/** Code verification state: user enters the PIN code */
|
|
95
|
-
readonly type: "code";
|
|
96
|
-
/** Whether this is a code resend request */
|
|
97
|
-
readonly resend?: boolean;
|
|
98
|
-
/** The generated PIN code for verification */
|
|
99
|
-
readonly code: string;
|
|
100
|
-
/** User claims collected during the start phase */
|
|
101
|
-
readonly claims: Record<string, string>;
|
|
102
|
-
};
|
|
103
|
-
/**
|
|
104
|
-
* Possible errors during PIN code authentication.
|
|
105
|
-
*/
|
|
106
|
-
type CodeProviderError = {
|
|
107
|
-
/** The entered PIN code is incorrect */
|
|
108
|
-
readonly type: "invalid_code";
|
|
109
|
-
} | {
|
|
110
|
-
/** A user claim is invalid or missing */
|
|
111
|
-
readonly type: "invalid_claim";
|
|
112
|
-
/** The claim field that failed validation */
|
|
113
|
-
readonly key: string;
|
|
114
|
-
/** The invalid value or error description */
|
|
115
|
-
readonly value: string;
|
|
116
|
-
};
|
|
117
|
-
/**
|
|
118
|
-
* User data returned by successful PIN code authentication.
|
|
119
|
-
*
|
|
120
|
-
* @template Claims - Type of claims collected during authentication
|
|
121
|
-
*/
|
|
122
|
-
interface CodeUserData<Claims extends Record<string, string> = Record<string, string>> {
|
|
123
|
-
/** The verified claims collected during authentication */
|
|
124
|
-
readonly claims: Claims;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Creates a PIN code authentication provider.
|
|
128
|
-
* Implements a flexible claim-based authentication flow with PIN verification.
|
|
129
|
-
*
|
|
130
|
-
* @template Claims - Type of claims to collect (email, phone, username, etc.)
|
|
131
|
-
* @param config - PIN code provider configuration
|
|
132
|
-
* @returns Provider instance implementing PIN code authentication
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* ```ts
|
|
136
|
-
* // Email-based PIN authentication
|
|
137
|
-
* const emailCodeProvider = CodeProvider<{ email: string }>({
|
|
138
|
-
* length: 6,
|
|
139
|
-
* request: async (req, state, form, error) => {
|
|
140
|
-
* if (state.type === 'start') {
|
|
141
|
-
* return new Response(renderEmailForm(form?.get('email'), error))
|
|
142
|
-
* } else {
|
|
143
|
-
* return new Response(renderPinForm(state.claims.email, error, state.resend))
|
|
144
|
-
* }
|
|
145
|
-
* },
|
|
146
|
-
* sendCode: async (claims, code) => {
|
|
147
|
-
* if (!claims.email || !isValidEmail(claims.email)) {
|
|
148
|
-
* return {
|
|
149
|
-
* type: "invalid_claim",
|
|
150
|
-
* key: "email",
|
|
151
|
-
* value: "Invalid email address"
|
|
152
|
-
* }
|
|
153
|
-
* }
|
|
154
|
-
*
|
|
155
|
-
* try {
|
|
156
|
-
* await emailService.send(claims.email, `Your verification code: ${code}`)
|
|
157
|
-
* } catch {
|
|
158
|
-
* return {
|
|
159
|
-
* type: "invalid_claim",
|
|
160
|
-
* key: "delivery",
|
|
161
|
-
* value: "Failed to send code"
|
|
162
|
-
* }
|
|
163
|
-
* }
|
|
164
|
-
* }
|
|
165
|
-
* })
|
|
166
|
-
*
|
|
167
|
-
* // Multi-channel PIN authentication (email or phone)
|
|
168
|
-
* const flexibleCodeProvider = CodeProvider<{ email?: string; phone?: string }>({
|
|
169
|
-
* length: 4,
|
|
170
|
-
* request: async (req, state, form, error) => {
|
|
171
|
-
* if (state.type === 'start') {
|
|
172
|
-
* return new Response(renderContactForm(form, error))
|
|
173
|
-
* } else {
|
|
174
|
-
* const contact = state.claims.email || state.claims.phone
|
|
175
|
-
* return new Response(renderPinForm(contact, error))
|
|
176
|
-
* }
|
|
177
|
-
* },
|
|
178
|
-
* sendCode: async (claims, code) => {
|
|
179
|
-
* try {
|
|
180
|
-
* if (claims.email) {
|
|
181
|
-
* await emailService.send(claims.email, `PIN: ${code}`)
|
|
182
|
-
* } else if (claims.phone) {
|
|
183
|
-
* await smsService.send(claims.phone, `PIN: ${code}`)
|
|
184
|
-
* } else {
|
|
185
|
-
* return {
|
|
186
|
-
* type: "invalid_claim",
|
|
187
|
-
* key: "email",
|
|
188
|
-
* value: "Provide either email or phone number"
|
|
189
|
-
* }
|
|
190
|
-
* }
|
|
191
|
-
* } catch {
|
|
192
|
-
* return {
|
|
193
|
-
* type: "invalid_claim",
|
|
194
|
-
* key: "delivery",
|
|
195
|
-
* value: "Failed to send code"
|
|
196
|
-
* }
|
|
197
|
-
* }
|
|
198
|
-
* }
|
|
199
|
-
* })
|
|
200
|
-
*
|
|
201
|
-
* // Usage in issuer
|
|
202
|
-
* export default issuer({
|
|
203
|
-
* providers: {
|
|
204
|
-
* email: emailCodeProvider,
|
|
205
|
-
* flexible: flexibleCodeProvider
|
|
206
|
-
* },
|
|
207
|
-
* success: async (ctx, value) => {
|
|
208
|
-
* if (value.provider === "code") {
|
|
209
|
-
* const email = value.claims.email
|
|
210
|
-
* const phone = value.claims.phone
|
|
211
|
-
*
|
|
212
|
-
* // Look up or create user based on verified claims
|
|
213
|
-
* const userId = await findOrCreateUser({ email, phone })
|
|
214
|
-
*
|
|
215
|
-
* return ctx.subject("user", { userId, email, phone })
|
|
216
|
-
* }
|
|
217
|
-
* }
|
|
218
|
-
* })
|
|
219
|
-
* ```
|
|
220
|
-
*/
|
|
221
|
-
declare const CodeProvider: <Claims extends Record<string, string> = Record<string, string>>(config: CodeProviderConfig<Claims>) => Provider<CodeUserData<Claims>>;
|
|
222
|
-
/**
|
|
223
|
-
* Type helper for CodeProvider configuration options.
|
|
224
|
-
* @internal
|
|
225
|
-
*/
|
|
226
|
-
type CodeProviderOptions = Parameters<typeof CodeProvider>[0];
|
|
227
|
-
//#endregion
|
|
228
|
-
export { CodeProvider, CodeProviderConfig, CodeProviderError, CodeProviderOptions, CodeProviderState, CodeUserData };
|