@draftlab/auth 0.4.1 → 0.6.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/adapters/{node.js → node.mjs} +2 -4
- package/dist/{allow.js → allow.mjs} +1 -1
- package/dist/{client.d.ts → client.d.mts} +47 -4
- package/dist/{client.js → client.mjs} +81 -10
- package/dist/{core.d.ts → core.d.mts} +10 -10
- package/dist/{core.js → core.mjs} +104 -56
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +3 -0
- package/dist/{keys.d.ts → keys.d.mts} +1 -1
- package/dist/{keys.js → keys.mjs} +6 -8
- package/dist/{pkce.js → pkce.mjs} +5 -10
- package/dist/plugin/{builder.d.ts → builder.d.mts} +1 -1
- package/dist/plugin/{manager.d.ts → manager.d.mts} +2 -2
- package/dist/plugin/{manager.js → manager.mjs} +1 -1
- package/dist/plugin/{plugin.d.ts → plugin.d.mts} +1 -1
- package/dist/plugin/{types.d.ts → types.d.mts} +1 -1
- package/dist/provider/apple.d.mts +105 -0
- package/dist/provider/apple.mjs +151 -0
- package/dist/provider/{code.d.ts → code.d.mts} +1 -1
- package/dist/provider/{code.js → code.mjs} +2 -3
- package/dist/provider/{discord.d.ts → discord.d.mts} +2 -2
- package/dist/provider/{discord.js → discord.mjs} +59 -1
- package/dist/provider/{facebook.d.ts → facebook.d.mts} +2 -2
- package/dist/provider/{facebook.js → facebook.mjs} +57 -1
- package/dist/provider/{github.d.ts → github.d.mts} +2 -2
- package/dist/provider/{github.js → github.mjs} +79 -1
- package/dist/provider/gitlab.d.mts +100 -0
- package/dist/provider/gitlab.mjs +128 -0
- package/dist/provider/{google.d.ts → google.d.mts} +2 -2
- package/dist/provider/{google.js → google.mjs} +45 -1
- package/dist/provider/{linkedin.d.ts → linkedin.d.mts} +2 -2
- package/dist/provider/{linkedin.js → linkedin.mjs} +57 -1
- package/dist/provider/{magiclink.d.ts → magiclink.d.mts} +1 -1
- package/dist/provider/{magiclink.js → magiclink.mjs} +4 -6
- package/dist/provider/{microsoft.d.ts → microsoft.d.mts} +2 -2
- package/dist/provider/{microsoft.js → microsoft.mjs} +68 -1
- package/dist/provider/{oauth2.d.ts → oauth2.d.mts} +1 -1
- package/dist/provider/{oauth2.js → oauth2.mjs} +4 -4
- package/dist/provider/{passkey.d.ts → passkey.d.mts} +1 -1
- package/dist/provider/{passkey.js → passkey.mjs} +8 -13
- package/dist/provider/{password.d.ts → password.d.mts} +1 -1
- package/dist/provider/{password.js → password.mjs} +31 -44
- package/dist/provider/{provider.d.ts → provider.d.mts} +1 -1
- package/dist/provider/reddit.d.mts +101 -0
- package/dist/provider/reddit.mjs +114 -0
- package/dist/provider/slack.d.mts +108 -0
- package/dist/provider/slack.mjs +125 -0
- package/dist/provider/spotify.d.mts +107 -0
- package/dist/provider/spotify.mjs +122 -0
- package/dist/provider/{totp.d.ts → totp.d.mts} +1 -1
- package/dist/provider/{totp.js → totp.mjs} +51 -14
- package/dist/provider/twitch.d.mts +102 -0
- package/dist/provider/twitch.mjs +118 -0
- package/dist/{random.js → random.mjs} +1 -2
- package/dist/revocation.d.mts +55 -0
- package/dist/revocation.mjs +63 -0
- package/dist/storage/{memory.d.ts → memory.d.mts} +1 -1
- package/dist/storage/{memory.js → memory.mjs} +3 -5
- package/dist/storage/{storage.d.ts → storage.d.mts} +27 -10
- package/dist/storage/storage.mjs +104 -0
- package/dist/storage/{turso.d.ts → turso.d.mts} +1 -1
- package/dist/storage/{turso.js → turso.mjs} +1 -1
- package/dist/storage/{unstorage.d.ts → unstorage.d.mts} +1 -1
- package/dist/storage/{unstorage.js → unstorage.mjs} +11 -4
- package/dist/{subject.d.ts → subject.d.mts} +1 -1
- package/dist/ui/{base.d.ts → base.d.mts} +1 -1
- package/dist/ui/{base.js → base.mjs} +1 -1
- package/dist/ui/{code.d.ts → code.d.mts} +1 -1
- package/dist/ui/{code.js → code.mjs} +3 -4
- package/dist/ui/{magiclink.d.ts → magiclink.d.mts} +1 -1
- package/dist/ui/{magiclink.js → magiclink.mjs} +3 -4
- package/dist/ui/{passkey.d.ts → passkey.d.mts} +1 -1
- package/dist/ui/{passkey.js → passkey.mjs} +2 -2
- package/dist/ui/{password.d.ts → password.d.mts} +1 -1
- package/dist/ui/{password.js → password.mjs} +3 -4
- package/dist/ui/{select.d.ts → select.d.mts} +1 -1
- package/dist/ui/{select.js → select.mjs} +2 -2
- package/dist/ui/{totp.d.ts → totp.d.mts} +1 -1
- package/dist/ui/{totp.js → totp.mjs} +2 -2
- package/dist/{util.js → util.mjs} +2 -5
- package/package.json +17 -16
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -3
- package/dist/storage/storage.js +0 -62
- /package/dist/adapters/{node.d.ts → node.d.mts} +0 -0
- /package/dist/{allow.d.ts → allow.d.mts} +0 -0
- /package/dist/{error.d.ts → error.d.mts} +0 -0
- /package/dist/{error.js → error.mjs} +0 -0
- /package/dist/{pkce.d.ts → pkce.d.mts} +0 -0
- /package/dist/plugin/{builder.js → builder.mjs} +0 -0
- /package/dist/plugin/{plugin.js → plugin.mjs} +0 -0
- /package/dist/plugin/{types.js → types.mjs} +0 -0
- /package/dist/provider/{provider.js → provider.mjs} +0 -0
- /package/dist/{random.d.ts → random.d.mts} +0 -0
- /package/dist/{subject.js → subject.mjs} +0 -0
- /package/dist/themes/{theme.d.ts → theme.d.mts} +0 -0
- /package/dist/themes/{theme.js → theme.mjs} +0 -0
- /package/dist/{types.d.ts → types.d.mts} +0 -0
- /package/dist/{types.js → types.mjs} +0 -0
- /package/dist/ui/{form.d.ts → form.d.mts} +0 -0
- /package/dist/ui/{form.js → form.mjs} +0 -0
- /package/dist/ui/{icon.d.ts → icon.d.mts} +0 -0
- /package/dist/ui/{icon.js → icon.mjs} +0 -0
- /package/dist/{util.d.ts → util.d.mts} +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
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
|
+
declare const AppleProvider: (config: AppleConfig) => Provider<Oauth2UserData>;
|
|
104
|
+
//#endregion
|
|
105
|
+
export { AppleConfig, AppleProvider };
|
|
@@ -0,0 +1,151 @@
|
|
|
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
|
+
* providers: {
|
|
15
|
+
* apple: AppleProvider({
|
|
16
|
+
* clientID: process.env.APPLE_CLIENT_ID,
|
|
17
|
+
* clientSecret: process.env.APPLE_CLIENT_SECRET,
|
|
18
|
+
* scopes: ["name", "email"]
|
|
19
|
+
* })
|
|
20
|
+
* }
|
|
21
|
+
* })
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* ## Setup Instructions
|
|
25
|
+
*
|
|
26
|
+
* ### 1. Create App ID
|
|
27
|
+
* - Go to [Apple Developer](https://developer.apple.com)
|
|
28
|
+
* - Create a new App ID with "Sign in with Apple" capability
|
|
29
|
+
*
|
|
30
|
+
* ### 2. Create Service ID
|
|
31
|
+
* - Create a new Service ID (this is your clientID)
|
|
32
|
+
* - Configure "Sign in with Apple"
|
|
33
|
+
* - Add your redirect URI
|
|
34
|
+
*
|
|
35
|
+
* ### 3. Create Private Key
|
|
36
|
+
* - Create a private key for "Sign in with Apple"
|
|
37
|
+
* - Download the .p8 file (this is used to create your clientSecret)
|
|
38
|
+
*
|
|
39
|
+
* ## Client Secret Generation
|
|
40
|
+
*
|
|
41
|
+
* Apple requires a JWT token as the client secret. You'll need:
|
|
42
|
+
* - Key ID from the private key
|
|
43
|
+
* - Team ID from your Apple Developer account
|
|
44
|
+
* - Private key (.p8 file)
|
|
45
|
+
*
|
|
46
|
+
* Use a library to generate the JWT (valid for ~15 minutes):
|
|
47
|
+
*
|
|
48
|
+
* ```ts
|
|
49
|
+
* import { SignJWT } from "jose"
|
|
50
|
+
*
|
|
51
|
+
* const secret = await new SignJWT({
|
|
52
|
+
* iss: "YOUR_TEAM_ID",
|
|
53
|
+
* aud: "https://appleid.apple.com",
|
|
54
|
+
* sub: process.env.APPLE_CLIENT_ID,
|
|
55
|
+
* iat: Math.floor(Date.now() / 1000),
|
|
56
|
+
* exp: Math.floor(Date.now() / 1000) + 15 * 60
|
|
57
|
+
* })
|
|
58
|
+
* .setProtectedHeader({ alg: "ES256", kid: "YOUR_KEY_ID" })
|
|
59
|
+
* .sign(privateKey)
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* ## Common Scopes
|
|
63
|
+
*
|
|
64
|
+
* - `name` - Access user's name (first and last name)
|
|
65
|
+
* - `email` - Access user's email address
|
|
66
|
+
*
|
|
67
|
+
* Note: Apple only returns user data on the first authorization. Subsequent authorizations won't include name/email.
|
|
68
|
+
*
|
|
69
|
+
* ## User Data Access
|
|
70
|
+
*
|
|
71
|
+
* ```ts
|
|
72
|
+
* success: async (ctx, value) => {
|
|
73
|
+
* if (value.provider === "apple") {
|
|
74
|
+
* const accessToken = value.tokenset.access
|
|
75
|
+
*
|
|
76
|
+
* // Apple doesn't provide a userinfo endpoint
|
|
77
|
+
* // User data is returned in the authorization response
|
|
78
|
+
* // You need to parse the id_token JWT to get user info
|
|
79
|
+
*
|
|
80
|
+
* // For subsequent logins without name/email, use the subject (user_id)
|
|
81
|
+
* // from the ID token to identify the user
|
|
82
|
+
* }
|
|
83
|
+
* }
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* @packageDocumentation
|
|
87
|
+
*/
|
|
88
|
+
/**
|
|
89
|
+
* Creates an Apple OAuth 2.0 authentication provider.
|
|
90
|
+
* Allows users to authenticate using their Apple accounts.
|
|
91
|
+
*
|
|
92
|
+
* @param config - Apple OAuth 2.0 configuration
|
|
93
|
+
* @returns OAuth 2.0 provider configured for Apple
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* // Basic Apple authentication
|
|
98
|
+
* const basicApple = AppleProvider({
|
|
99
|
+
* clientID: process.env.APPLE_CLIENT_ID,
|
|
100
|
+
* clientSecret: process.env.APPLE_CLIENT_SECRET
|
|
101
|
+
* })
|
|
102
|
+
*
|
|
103
|
+
* // Apple with name and email scopes
|
|
104
|
+
* const appleWithScopes = AppleProvider({
|
|
105
|
+
* clientID: process.env.APPLE_CLIENT_ID,
|
|
106
|
+
* clientSecret: process.env.APPLE_CLIENT_SECRET,
|
|
107
|
+
* scopes: ["name", "email"]
|
|
108
|
+
* })
|
|
109
|
+
*
|
|
110
|
+
* // Using the tokens and id_token
|
|
111
|
+
* export default issuer({
|
|
112
|
+
* providers: { apple: appleWithScopes },
|
|
113
|
+
* success: async (ctx, value) => {
|
|
114
|
+
* if (value.provider === "apple") {
|
|
115
|
+
* // Apple returns user data in the initial authorization response
|
|
116
|
+
* // You need to decode the id_token to extract user information
|
|
117
|
+
*
|
|
118
|
+
* // The id_token contains:
|
|
119
|
+
* // - sub: unique Apple user identifier
|
|
120
|
+
* // - email: user email (only on first authorization)
|
|
121
|
+
* // - email_verified: whether email is verified
|
|
122
|
+
* // - is_private_email: whether user used private relay
|
|
123
|
+
*
|
|
124
|
+
* // Decode and verify the id_token using jose:
|
|
125
|
+
* // const verified = await jwtVerify(value.tokenset.id, jwks)
|
|
126
|
+
* // const user = verified.payload
|
|
127
|
+
*
|
|
128
|
+
* return ctx.subject("user", {
|
|
129
|
+
* appleId: user.sub,
|
|
130
|
+
* email: user.email,
|
|
131
|
+
* emailVerified: user.email_verified,
|
|
132
|
+
* isPrivateEmail: user.is_private_email
|
|
133
|
+
* })
|
|
134
|
+
* }
|
|
135
|
+
* }
|
|
136
|
+
* })
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
const AppleProvider = (config) => {
|
|
140
|
+
return Oauth2Provider({
|
|
141
|
+
...config,
|
|
142
|
+
type: "apple",
|
|
143
|
+
endpoint: {
|
|
144
|
+
authorization: "https://appleid.apple.com/auth/authorize",
|
|
145
|
+
token: "https://appleid.apple.com/auth/token"
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
//#endregion
|
|
151
|
+
export { AppleProvider };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { generateUnbiasedDigits, timingSafeCompare } from "../random.
|
|
1
|
+
import { generateUnbiasedDigits, timingSafeCompare } from "../random.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/provider/code.ts
|
|
4
4
|
/**
|
|
@@ -130,8 +130,7 @@ const CodeProvider = (config) => {
|
|
|
130
130
|
const action = formData.get("action")?.toString();
|
|
131
131
|
if (action === "request" || action === "resend") {
|
|
132
132
|
const code = generateCode();
|
|
133
|
-
const
|
|
134
|
-
const { action: _,...claims } = formEntries;
|
|
133
|
+
const { action: _, ...claims } = Object.fromEntries(formData);
|
|
135
134
|
const sendError = await config.sendCode(claims, code);
|
|
136
135
|
if (sendError) return transition(c, { type: "start" }, formData, sendError);
|
|
137
136
|
return transition(c, {
|
|
@@ -1,7 +1,65 @@
|
|
|
1
|
-
import { Oauth2Provider } from "./oauth2.
|
|
1
|
+
import { Oauth2Provider } from "./oauth2.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/provider/discord.ts
|
|
4
4
|
/**
|
|
5
|
+
* Discord OAuth 2.0 authentication provider for Draft Auth.
|
|
6
|
+
* Provides access tokens for calling Discord APIs on behalf of users.
|
|
7
|
+
*
|
|
8
|
+
* ## Quick Setup
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { DiscordProvider } from "@draftlab/auth/provider/discord"
|
|
12
|
+
*
|
|
13
|
+
* export default issuer({
|
|
14
|
+
* providers: {
|
|
15
|
+
* discord: DiscordProvider({
|
|
16
|
+
* clientID: process.env.DISCORD_CLIENT_ID,
|
|
17
|
+
* clientSecret: process.env.DISCORD_CLIENT_SECRET,
|
|
18
|
+
* scopes: ["identify", "email", "guilds"]
|
|
19
|
+
* })
|
|
20
|
+
* }
|
|
21
|
+
* })
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* ## Common Scopes
|
|
25
|
+
*
|
|
26
|
+
* - `identify` - Access to user's basic account information
|
|
27
|
+
* - `email` - Access to user's email address
|
|
28
|
+
* - `guilds` - Access to user's guilds (servers)
|
|
29
|
+
* - `guilds.join` - Ability to join user to guilds
|
|
30
|
+
* - `gdm.join` - Ability to join user to group DMs
|
|
31
|
+
* - `connections` - Access to user's connections (Steam, YouTube, etc.)
|
|
32
|
+
* - `guilds.members.read` - Read guild member information
|
|
33
|
+
* - `bot` - For bot applications (requires additional setup)
|
|
34
|
+
*
|
|
35
|
+
* ## User Data Access
|
|
36
|
+
*
|
|
37
|
+
* ```ts
|
|
38
|
+
* success: async (ctx, value) => {
|
|
39
|
+
* if (value.provider === "discord") {
|
|
40
|
+
* const accessToken = value.tokenset.access
|
|
41
|
+
*
|
|
42
|
+
* // Fetch user information
|
|
43
|
+
* const userResponse = await fetch('https://discord.com/api/users/@me', {
|
|
44
|
+
* headers: { Authorization: `Bearer ${accessToken}` }
|
|
45
|
+
* })
|
|
46
|
+
* const user = await userResponse.json()
|
|
47
|
+
*
|
|
48
|
+
* // Fetch user guilds (requires guilds scope)
|
|
49
|
+
* const guildsResponse = await fetch('https://discord.com/api/users/@me/guilds', {
|
|
50
|
+
* headers: { Authorization: `Bearer ${accessToken}` }
|
|
51
|
+
* })
|
|
52
|
+
* const guilds = await guildsResponse.json()
|
|
53
|
+
*
|
|
54
|
+
* // User info: user.username + user.discriminator
|
|
55
|
+
* // Avatar: `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png`
|
|
56
|
+
* }
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @packageDocumentation
|
|
61
|
+
*/
|
|
62
|
+
/**
|
|
5
63
|
* Creates a Discord OAuth 2.0 authentication provider.
|
|
6
64
|
* Use this when you need access tokens to call Discord APIs on behalf of the user.
|
|
7
65
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Provider } from "./provider.
|
|
2
|
-
import { Oauth2UserData, Oauth2WrappedConfig } from "./oauth2.
|
|
1
|
+
import { Provider } from "./provider.mjs";
|
|
2
|
+
import { Oauth2UserData, Oauth2WrappedConfig } from "./oauth2.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/provider/facebook.d.ts
|
|
5
5
|
|
|
@@ -1,7 +1,63 @@
|
|
|
1
|
-
import { Oauth2Provider } from "./oauth2.
|
|
1
|
+
import { Oauth2Provider } from "./oauth2.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/provider/facebook.ts
|
|
4
4
|
/**
|
|
5
|
+
* Facebook OAuth 2.0 authentication provider for Draft Auth.
|
|
6
|
+
* Provides access tokens for calling Facebook Graph API on behalf of users.
|
|
7
|
+
*
|
|
8
|
+
* ## Quick Setup
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { FacebookProvider } from "@draftlab/auth/provider/facebook"
|
|
12
|
+
*
|
|
13
|
+
* export default issuer({
|
|
14
|
+
* providers: {
|
|
15
|
+
* facebook: FacebookProvider({
|
|
16
|
+
* clientID: process.env.FACEBOOK_APP_ID,
|
|
17
|
+
* clientSecret: process.env.FACEBOOK_APP_SECRET,
|
|
18
|
+
* scopes: ["email", "public_profile", "user_friends"]
|
|
19
|
+
* })
|
|
20
|
+
* }
|
|
21
|
+
* })
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* ## Configuration Options
|
|
25
|
+
*
|
|
26
|
+
* - Access tokens for Facebook Graph API calls
|
|
27
|
+
* - Support for various Facebook permissions
|
|
28
|
+
* - Access to user data, posts, friends, etc.
|
|
29
|
+
*
|
|
30
|
+
* ## Common Facebook Permissions
|
|
31
|
+
*
|
|
32
|
+
* - `public_profile` - Basic profile information (name, picture, etc.)
|
|
33
|
+
* - `email` - User's email address
|
|
34
|
+
* - `user_friends` - List of user's friends who also use your app
|
|
35
|
+
* - `user_posts` - User's posts on their timeline
|
|
36
|
+
* - `user_photos` - User's photos and albums
|
|
37
|
+
* - `pages_read_engagement` - Read engagement data for Pages
|
|
38
|
+
*
|
|
39
|
+
* ## User Data Access
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* success: async (ctx, value) => {
|
|
43
|
+
* if (value.provider === "facebook") {
|
|
44
|
+
* const accessToken = value.tokenset.access
|
|
45
|
+
*
|
|
46
|
+
* // Fetch user profile from Graph API
|
|
47
|
+
* const profileResponse = await fetch(
|
|
48
|
+
* `https://graph.facebook.com/me?fields=id,name,email,picture&access_token=${accessToken}`
|
|
49
|
+
* )
|
|
50
|
+
* const profile = await profileResponse.json()
|
|
51
|
+
*
|
|
52
|
+
* // User info: `${profile.name} (${profile.email})`
|
|
53
|
+
* // Facebook ID: profile.id
|
|
54
|
+
* }
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @packageDocumentation
|
|
59
|
+
*/
|
|
60
|
+
/**
|
|
5
61
|
* Creates a Facebook OAuth 2.0 authentication provider.
|
|
6
62
|
* Use this when you need access tokens to call Facebook Graph API on behalf of the user.
|
|
7
63
|
*
|
|
@@ -1,7 +1,85 @@
|
|
|
1
|
-
import { Oauth2Provider } from "./oauth2.
|
|
1
|
+
import { Oauth2Provider } from "./oauth2.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/provider/github.ts
|
|
4
4
|
/**
|
|
5
|
+
* GitHub authentication provider for Draft Auth.
|
|
6
|
+
* Implements OAuth 2.0 flow for authenticating users with their GitHub accounts.
|
|
7
|
+
*
|
|
8
|
+
* ## Quick Setup
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { GithubProvider } from "@draftlab/auth/provider/github"
|
|
12
|
+
*
|
|
13
|
+
* export default issuer({
|
|
14
|
+
* providers: {
|
|
15
|
+
* github: GithubProvider({
|
|
16
|
+
* clientID: process.env.GITHUB_CLIENT_ID,
|
|
17
|
+
* clientSecret: process.env.GITHUB_CLIENT_SECRET,
|
|
18
|
+
* scopes: ["user:email", "read:user"]
|
|
19
|
+
* })
|
|
20
|
+
* }
|
|
21
|
+
* })
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* ## GitHub App vs OAuth App
|
|
25
|
+
*
|
|
26
|
+
* This provider works with both GitHub OAuth Apps and GitHub Apps:
|
|
27
|
+
*
|
|
28
|
+
* ### OAuth App (Recommended for user authentication)
|
|
29
|
+
* ```ts
|
|
30
|
+
* GithubProvider({
|
|
31
|
+
* clientID: "your-oauth-app-client-id",
|
|
32
|
+
* clientSecret: "your-oauth-app-client-secret",
|
|
33
|
+
* scopes: ["user:email", "read:user"]
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* ### GitHub App (For organization-level integrations)
|
|
38
|
+
* ```ts
|
|
39
|
+
* GithubProvider({
|
|
40
|
+
* clientID: "your-github-app-client-id",
|
|
41
|
+
* clientSecret: "your-github-app-client-secret",
|
|
42
|
+
* scopes: ["user:email", "read:user", "repo"]
|
|
43
|
+
* })
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* ## Common Scopes
|
|
47
|
+
*
|
|
48
|
+
* - `user:email` - Access user's email addresses
|
|
49
|
+
* - `read:user` - Read user profile information
|
|
50
|
+
* - `repo` - Access public and private repositories
|
|
51
|
+
* - `public_repo` - Access public repositories only
|
|
52
|
+
* - `read:org` - Read organization membership
|
|
53
|
+
* - `gist` - Create and update gists
|
|
54
|
+
*
|
|
55
|
+
* ## User Data Access
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* success: async (ctx, value) => {
|
|
59
|
+
* if (value.provider === "github") {
|
|
60
|
+
* const accessToken = value.tokenset.access
|
|
61
|
+
*
|
|
62
|
+
* // Fetch user information
|
|
63
|
+
* const userResponse = await fetch('https://api.github.com/user', {
|
|
64
|
+
* headers: { Authorization: `Bearer ${accessToken}` }
|
|
65
|
+
* })
|
|
66
|
+
* const user = await userResponse.json()
|
|
67
|
+
*
|
|
68
|
+
* // Fetch user emails (requires user:email scope)
|
|
69
|
+
* const emailsResponse = await fetch('https://api.github.com/user/emails', {
|
|
70
|
+
* headers: { Authorization: `Bearer ${accessToken}` }
|
|
71
|
+
* })
|
|
72
|
+
* const emails = await emailsResponse.json()
|
|
73
|
+
*
|
|
74
|
+
* // User info: `${user.login} (${user.name})`
|
|
75
|
+
* // Primary email: emails.find(e => e.primary)?.email
|
|
76
|
+
* }
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @packageDocumentation
|
|
81
|
+
*/
|
|
82
|
+
/**
|
|
5
83
|
* Creates a GitHub OAuth 2.0 authentication provider.
|
|
6
84
|
* Supports both GitHub OAuth Apps and GitHub Apps for user authentication.
|
|
7
85
|
*
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Provider } from "./provider.mjs";
|
|
2
|
+
import { Oauth2UserData, Oauth2WrappedConfig } from "./oauth2.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/provider/gitlab.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Configuration options for GitLab OAuth 2.0 provider.
|
|
8
|
+
* Extends the base OAuth 2.0 configuration with GitLab-specific documentation.
|
|
9
|
+
*/
|
|
10
|
+
interface GitlabConfig extends Oauth2WrappedConfig {
|
|
11
|
+
/**
|
|
12
|
+
* GitLab application client ID.
|
|
13
|
+
* Get this from your GitLab application settings.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* {
|
|
18
|
+
* clientID: "abcdef123456"
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
readonly clientID: string;
|
|
23
|
+
/**
|
|
24
|
+
* GitLab application client secret.
|
|
25
|
+
* Keep this secure and never expose it to client-side code.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* {
|
|
30
|
+
* clientSecret: process.env.GITLAB_CLIENT_SECRET
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
readonly clientSecret: string;
|
|
35
|
+
/**
|
|
36
|
+
* GitLab OAuth scopes to request access for.
|
|
37
|
+
* Determines what data and actions your app can access.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* {
|
|
42
|
+
* scopes: [
|
|
43
|
+
* "read_user", // Access user profile
|
|
44
|
+
* "read_api", // Read-access to API
|
|
45
|
+
* "read_repository" // Access repositories
|
|
46
|
+
* ]
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
readonly scopes: string[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Creates a GitLab OAuth 2.0 authentication provider.
|
|
54
|
+
* Allows users to authenticate using their GitLab accounts (gitlab.com or self-hosted).
|
|
55
|
+
*
|
|
56
|
+
* @param config - GitLab OAuth 2.0 configuration
|
|
57
|
+
* @returns OAuth 2.0 provider configured for GitLab
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* // Basic GitLab.com authentication
|
|
62
|
+
* const basicGitlab = GitlabProvider({
|
|
63
|
+
* clientID: process.env.GITLAB_CLIENT_ID,
|
|
64
|
+
* clientSecret: process.env.GITLAB_CLIENT_SECRET
|
|
65
|
+
* })
|
|
66
|
+
*
|
|
67
|
+
* // GitLab with read access
|
|
68
|
+
* const gitlabWithRead = GitlabProvider({
|
|
69
|
+
* clientID: process.env.GITLAB_CLIENT_ID,
|
|
70
|
+
* clientSecret: process.env.GITLAB_CLIENT_SECRET,
|
|
71
|
+
* scopes: ["read_user", "read_api"]
|
|
72
|
+
* })
|
|
73
|
+
*
|
|
74
|
+
* // Using the access token to fetch user data
|
|
75
|
+
* export default issuer({
|
|
76
|
+
* providers: { gitlab: gitlabWithRead },
|
|
77
|
+
* success: async (ctx, value) => {
|
|
78
|
+
* if (value.provider === "gitlab") {
|
|
79
|
+
* const token = value.tokenset.access
|
|
80
|
+
*
|
|
81
|
+
* const userRes = await fetch('https://gitlab.com/api/v4/user', {
|
|
82
|
+
* headers: { Authorization: `Bearer ${token}` }
|
|
83
|
+
* })
|
|
84
|
+
* const user = await userRes.json()
|
|
85
|
+
*
|
|
86
|
+
* return ctx.subject("user", {
|
|
87
|
+
* gitlabId: user.id,
|
|
88
|
+
* username: user.username,
|
|
89
|
+
* email: user.email,
|
|
90
|
+
* name: user.name,
|
|
91
|
+
* avatar: user.avatar_url
|
|
92
|
+
* })
|
|
93
|
+
* }
|
|
94
|
+
* }
|
|
95
|
+
* })
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
declare const GitlabProvider: (config: GitlabConfig) => Provider<Oauth2UserData>;
|
|
99
|
+
//#endregion
|
|
100
|
+
export { GitlabConfig, GitlabProvider };
|