@rudderjs/socialite 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +107 -0
- package/dist/drivers/apple.d.ts +17 -0
- package/dist/drivers/apple.d.ts.map +1 -0
- package/dist/drivers/apple.js +86 -0
- package/dist/drivers/apple.js.map +1 -0
- package/dist/drivers/facebook.d.ts +10 -0
- package/dist/drivers/facebook.d.ts.map +1 -0
- package/dist/drivers/facebook.js +22 -0
- package/dist/drivers/facebook.js.map +1 -0
- package/dist/drivers/github.d.ts +15 -0
- package/dist/drivers/github.d.ts.map +1 -0
- package/dist/drivers/github.js +56 -0
- package/dist/drivers/github.js.map +1 -0
- package/dist/drivers/google.d.ts +10 -0
- package/dist/drivers/google.d.ts.map +1 -0
- package/dist/drivers/google.js +21 -0
- package/dist/drivers/google.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/provider.d.ts +43 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +89 -0
- package/dist/provider.js.map +1 -0
- package/dist/social-user.d.ts +26 -0
- package/dist/social-user.d.ts.map +1 -0
- package/dist/social-user.js +20 -0
- package/dist/social-user.js.map +1 -0
- package/package.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Suleiman Shahbari
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# @rudderjs/socialite
|
|
2
|
+
|
|
3
|
+
OAuth authentication for RudderJS. Built-in providers: GitHub, Google, Facebook, Apple. Extensible with custom providers.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @rudderjs/socialite
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
// config/socialite.ts
|
|
15
|
+
import { Env } from '@rudderjs/core'
|
|
16
|
+
|
|
17
|
+
export default {
|
|
18
|
+
github: {
|
|
19
|
+
clientId: Env.get('GITHUB_CLIENT_ID', ''),
|
|
20
|
+
clientSecret: Env.get('GITHUB_CLIENT_SECRET', ''),
|
|
21
|
+
redirectUrl: Env.get('GITHUB_REDIRECT_URL', 'http://localhost:3000/auth/github/callback'),
|
|
22
|
+
},
|
|
23
|
+
google: {
|
|
24
|
+
clientId: Env.get('GOOGLE_CLIENT_ID', ''),
|
|
25
|
+
clientSecret: Env.get('GOOGLE_CLIENT_SECRET', ''),
|
|
26
|
+
redirectUrl: Env.get('GOOGLE_REDIRECT_URL', 'http://localhost:3000/auth/google/callback'),
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// bootstrap/providers.ts
|
|
31
|
+
import { socialite } from '@rudderjs/socialite'
|
|
32
|
+
export default [..., socialite(configs.socialite)]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { Socialite } from '@rudderjs/socialite'
|
|
39
|
+
import { Auth } from '@rudderjs/auth'
|
|
40
|
+
|
|
41
|
+
// Redirect to provider
|
|
42
|
+
Route.get('/auth/github', () => {
|
|
43
|
+
return Socialite.driver('github').redirect()
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// Handle callback
|
|
47
|
+
Route.get('/auth/github/callback', async (req) => {
|
|
48
|
+
const socialUser = await Socialite.driver('github').user(req)
|
|
49
|
+
|
|
50
|
+
socialUser.getId() // "12345"
|
|
51
|
+
socialUser.getName() // "John Doe"
|
|
52
|
+
socialUser.getEmail() // "john@example.com"
|
|
53
|
+
socialUser.getAvatar() // "https://..."
|
|
54
|
+
socialUser.getNickname() // "johnd"
|
|
55
|
+
socialUser.token // "gho_abc123..."
|
|
56
|
+
|
|
57
|
+
// Find or create local user, then login
|
|
58
|
+
const user = await User.firstOrCreate(
|
|
59
|
+
{ githubId: socialUser.getId() },
|
|
60
|
+
{ name: socialUser.getName(), email: socialUser.getEmail() },
|
|
61
|
+
)
|
|
62
|
+
await Auth.login(user)
|
|
63
|
+
return Response.redirect('/')
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Providers
|
|
68
|
+
|
|
69
|
+
| Provider | Driver | Auth URL |
|
|
70
|
+
|----------|--------|----------|
|
|
71
|
+
| GitHub | `github` | `github.com/login/oauth/authorize` |
|
|
72
|
+
| Google | `google` | `accounts.google.com/o/oauth2/v2/auth` |
|
|
73
|
+
| Facebook | `facebook` | `facebook.com/v19.0/dialog/oauth` |
|
|
74
|
+
| Apple | `apple` | `appleid.apple.com/auth/authorize` |
|
|
75
|
+
|
|
76
|
+
## Custom Providers
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { SocialiteProvider, SocialUser, Socialite } from '@rudderjs/socialite'
|
|
80
|
+
|
|
81
|
+
class GitLabProvider extends SocialiteProvider {
|
|
82
|
+
protected defaultScopes() { return ['read_user'] }
|
|
83
|
+
protected authUrl() { return 'https://gitlab.com/oauth/authorize' }
|
|
84
|
+
protected tokenUrl() { return 'https://gitlab.com/oauth/token' }
|
|
85
|
+
protected userUrl() { return 'https://gitlab.com/api/v4/user' }
|
|
86
|
+
|
|
87
|
+
protected mapToUser(data: Record<string, unknown>, token: string, refreshToken: string | null) {
|
|
88
|
+
return new SocialUser({
|
|
89
|
+
id: String(data['id']), name: data['name'] as string,
|
|
90
|
+
email: data['email'] as string, avatar: data['avatar_url'] as string,
|
|
91
|
+
nickname: data['username'] as string, token, refreshToken, raw: data,
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
Socialite.extend('gitlab', (config) => new GitLabProvider(config))
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Scopes
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
// Add scopes
|
|
103
|
+
Socialite.driver('github').withScopes(['repo'])
|
|
104
|
+
|
|
105
|
+
// Replace scopes entirely
|
|
106
|
+
Socialite.driver('github').setScopes(['read:user'])
|
|
107
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SocialiteProvider } from '../provider.js';
|
|
2
|
+
import { SocialUser } from '../social-user.js';
|
|
3
|
+
export declare class AppleProvider extends SocialiteProvider {
|
|
4
|
+
protected defaultScopes(): string[];
|
|
5
|
+
protected authUrl(): string;
|
|
6
|
+
protected tokenUrl(): string;
|
|
7
|
+
protected userUrl(): string;
|
|
8
|
+
getRedirectUrl(state?: string): string;
|
|
9
|
+
protected mapToUser(data: Record<string, unknown>, token: string, refreshToken: string | null): SocialUser;
|
|
10
|
+
/** Apple sends user data as form POST on callback. Parse the id_token JWT for user info. */
|
|
11
|
+
user(codeOrRequest: string | {
|
|
12
|
+
query: Record<string, string>;
|
|
13
|
+
body?: unknown;
|
|
14
|
+
}): Promise<SocialUser>;
|
|
15
|
+
private getIdToken;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=apple.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apple.d.ts","sourceRoot":"","sources":["../../src/drivers/apple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,qBAAa,aAAc,SAAQ,iBAAiB;IAClD,SAAS,CAAC,aAAa,IAAI,MAAM,EAAE;IACnC,SAAS,CAAC,OAAO,IAAK,MAAM;IAC5B,SAAS,CAAC,QAAQ,IAAI,MAAM;IAC5B,SAAS,CAAC,OAAO,IAAK,MAAM;IAE5B,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;IAYtC,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU;IAkB1G,4FAA4F;IACtF,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;YA0B5F,UAAU;CAwBzB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { SocialiteProvider } from '../provider.js';
|
|
2
|
+
import { SocialUser } from '../social-user.js';
|
|
3
|
+
export class AppleProvider extends SocialiteProvider {
|
|
4
|
+
defaultScopes() { return ['name', 'email']; }
|
|
5
|
+
authUrl() { return 'https://appleid.apple.com/auth/authorize'; }
|
|
6
|
+
tokenUrl() { return 'https://appleid.apple.com/auth/token'; }
|
|
7
|
+
userUrl() { return ''; } // Apple sends user data in the callback, not a separate endpoint
|
|
8
|
+
getRedirectUrl(state) {
|
|
9
|
+
const params = new URLSearchParams({
|
|
10
|
+
client_id: this.config.clientId,
|
|
11
|
+
redirect_uri: this.config.redirectUrl,
|
|
12
|
+
response_type: 'code',
|
|
13
|
+
response_mode: 'form_post',
|
|
14
|
+
scope: this.scopes.join(' '),
|
|
15
|
+
...(state ? { state } : {}),
|
|
16
|
+
});
|
|
17
|
+
return `${this.authUrl()}?${params.toString()}`;
|
|
18
|
+
}
|
|
19
|
+
mapToUser(data, token, refreshToken) {
|
|
20
|
+
// Apple's id_token contains the user info as a JWT
|
|
21
|
+
const sub = data['sub'] ?? '';
|
|
22
|
+
const email = data['email'] ?? null;
|
|
23
|
+
const name = data['name'];
|
|
24
|
+
return new SocialUser({
|
|
25
|
+
id: sub,
|
|
26
|
+
name: name ? [name.firstName, name.lastName].filter(Boolean).join(' ') || null : null,
|
|
27
|
+
email,
|
|
28
|
+
avatar: null, // Apple doesn't provide avatars
|
|
29
|
+
nickname: null,
|
|
30
|
+
token,
|
|
31
|
+
refreshToken,
|
|
32
|
+
raw: data,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/** Apple sends user data as form POST on callback. Parse the id_token JWT for user info. */
|
|
36
|
+
async user(codeOrRequest) {
|
|
37
|
+
const code = typeof codeOrRequest === 'string'
|
|
38
|
+
? codeOrRequest
|
|
39
|
+
: (codeOrRequest.query['code'] ?? codeOrRequest.body?.['code']);
|
|
40
|
+
if (!code)
|
|
41
|
+
throw new Error('[RudderJS Socialite] Missing authorization code.');
|
|
42
|
+
const { accessToken, refreshToken } = await this.getAccessToken(code);
|
|
43
|
+
// Decode id_token (JWT) for user info — no verification needed here,
|
|
44
|
+
// Apple's token endpoint is trusted.
|
|
45
|
+
const idToken = (await this.getIdToken(code)) ?? {};
|
|
46
|
+
const userData = { ...idToken };
|
|
47
|
+
// Apple sends user name only on first authorization (as form POST body)
|
|
48
|
+
if (typeof codeOrRequest !== 'string' && codeOrRequest.body) {
|
|
49
|
+
const body = codeOrRequest.body;
|
|
50
|
+
if (body['user']) {
|
|
51
|
+
const user = typeof body['user'] === 'string' ? JSON.parse(body['user']) : body['user'];
|
|
52
|
+
userData['name'] = user;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return this.mapToUser(userData, accessToken, refreshToken);
|
|
56
|
+
}
|
|
57
|
+
async getIdToken(code) {
|
|
58
|
+
try {
|
|
59
|
+
const res = await fetch(this.tokenUrl(), {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
62
|
+
body: new URLSearchParams({
|
|
63
|
+
client_id: this.config.clientId,
|
|
64
|
+
client_secret: this.config.clientSecret,
|
|
65
|
+
code,
|
|
66
|
+
redirect_uri: this.config.redirectUrl,
|
|
67
|
+
grant_type: 'authorization_code',
|
|
68
|
+
}),
|
|
69
|
+
});
|
|
70
|
+
if (!res.ok)
|
|
71
|
+
return null;
|
|
72
|
+
const data = await res.json();
|
|
73
|
+
if (!data.id_token)
|
|
74
|
+
return null;
|
|
75
|
+
// Decode JWT payload (base64url)
|
|
76
|
+
const payload = data.id_token.split('.')[1];
|
|
77
|
+
if (!payload)
|
|
78
|
+
return null;
|
|
79
|
+
return JSON.parse(Buffer.from(payload, 'base64url').toString('utf8'));
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=apple.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apple.js","sourceRoot":"","sources":["../../src/drivers/apple.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SocialiteProvider } from '../provider.js';
|
|
2
|
+
import { SocialUser } from '../social-user.js';
|
|
3
|
+
export declare class FacebookProvider extends SocialiteProvider {
|
|
4
|
+
protected defaultScopes(): string[];
|
|
5
|
+
protected authUrl(): string;
|
|
6
|
+
protected tokenUrl(): string;
|
|
7
|
+
protected userUrl(): string;
|
|
8
|
+
protected mapToUser(data: Record<string, unknown>, token: string, refreshToken: string | null): SocialUser;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=facebook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facebook.d.ts","sourceRoot":"","sources":["../../src/drivers/facebook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,qBAAa,gBAAiB,SAAQ,iBAAiB;IACrD,SAAS,CAAC,aAAa,IAAI,MAAM,EAAE;IACnC,SAAS,CAAC,OAAO,IAAK,MAAM;IAC5B,SAAS,CAAC,QAAQ,IAAI,MAAM;IAC5B,SAAS,CAAC,OAAO,IAAK,MAAM;IAE5B,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU;CAa3G"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SocialiteProvider } from '../provider.js';
|
|
2
|
+
import { SocialUser } from '../social-user.js';
|
|
3
|
+
export class FacebookProvider extends SocialiteProvider {
|
|
4
|
+
defaultScopes() { return ['email', 'public_profile']; }
|
|
5
|
+
authUrl() { return 'https://www.facebook.com/v19.0/dialog/oauth'; }
|
|
6
|
+
tokenUrl() { return 'https://graph.facebook.com/v19.0/oauth/access_token'; }
|
|
7
|
+
userUrl() { return 'https://graph.facebook.com/v19.0/me?fields=id,name,email,picture.type(large)'; }
|
|
8
|
+
mapToUser(data, token, refreshToken) {
|
|
9
|
+
const picture = data['picture'];
|
|
10
|
+
return new SocialUser({
|
|
11
|
+
id: String(data['id'] ?? ''),
|
|
12
|
+
name: data['name'] ?? null,
|
|
13
|
+
email: data['email'] ?? null,
|
|
14
|
+
avatar: picture?.data?.url ?? null,
|
|
15
|
+
nickname: null,
|
|
16
|
+
token,
|
|
17
|
+
refreshToken,
|
|
18
|
+
raw: data,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=facebook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facebook.js","sourceRoot":"","sources":["../../src/drivers/facebook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,MAAM,OAAO,gBAAiB,SAAQ,iBAAiB;IAC3C,aAAa,KAAe,OAAO,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAA,CAAC,CAAC;IAChE,OAAO,KAAc,OAAO,6CAA6C,CAAA,CAAC,CAAC;IAC3E,QAAQ,KAAa,OAAO,qDAAqD,CAAA,CAAC,CAAC;IACnF,OAAO,KAAc,OAAO,8EAA8E,CAAA,CAAC,CAAC;IAE5G,SAAS,CAAC,IAA6B,EAAE,KAAa,EAAE,YAA2B;QAC3F,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAA4C,CAAA;QAC1E,OAAO,IAAI,UAAU,CAAC;YACpB,EAAE,EAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,EAAO,IAAI,CAAC,MAAM,CAAmB,IAAI,IAAI;YACjD,KAAK,EAAM,IAAI,CAAC,OAAO,CAAmB,IAAI,IAAI;YAClD,MAAM,EAAI,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI;YACpC,QAAQ,EAAE,IAAI;YACd,KAAK;YACL,YAAY;YACZ,GAAG,EAAE,IAAI;SACV,CAAC,CAAA;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SocialiteProvider } from '../provider.js';
|
|
2
|
+
import { SocialUser } from '../social-user.js';
|
|
3
|
+
export declare class GitHubProvider extends SocialiteProvider {
|
|
4
|
+
protected defaultScopes(): string[];
|
|
5
|
+
protected authUrl(): string;
|
|
6
|
+
protected tokenUrl(): string;
|
|
7
|
+
protected userUrl(): string;
|
|
8
|
+
protected mapToUser(data: Record<string, unknown>, token: string, refreshToken: string | null): SocialUser;
|
|
9
|
+
/** GitHub may not return email in the user endpoint if it's private. Fetch from /user/emails. */
|
|
10
|
+
user(codeOrRequest: string | {
|
|
11
|
+
query: Record<string, string>;
|
|
12
|
+
}): Promise<SocialUser>;
|
|
13
|
+
private fetchPrimaryEmail;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/drivers/github.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,qBAAa,cAAe,SAAQ,iBAAiB;IACnD,SAAS,CAAC,aAAa,IAAI,MAAM,EAAE;IACnC,SAAS,CAAC,OAAO,IAAK,MAAM;IAC5B,SAAS,CAAC,QAAQ,IAAI,MAAM;IAC5B,SAAS,CAAC,OAAO,IAAK,MAAM;IAE5B,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU;IAa1G,iGAAiG;IAC3F,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;YAoB5E,iBAAiB;CAahC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { SocialiteProvider } from '../provider.js';
|
|
2
|
+
import { SocialUser } from '../social-user.js';
|
|
3
|
+
export class GitHubProvider extends SocialiteProvider {
|
|
4
|
+
defaultScopes() { return ['read:user', 'user:email']; }
|
|
5
|
+
authUrl() { return 'https://github.com/login/oauth/authorize'; }
|
|
6
|
+
tokenUrl() { return 'https://github.com/login/oauth/access_token'; }
|
|
7
|
+
userUrl() { return 'https://api.github.com/user'; }
|
|
8
|
+
mapToUser(data, token, refreshToken) {
|
|
9
|
+
return new SocialUser({
|
|
10
|
+
id: String(data['id'] ?? ''),
|
|
11
|
+
name: data['name'] ?? null,
|
|
12
|
+
email: data['email'] ?? null,
|
|
13
|
+
avatar: data['avatar_url'] ?? null,
|
|
14
|
+
nickname: data['login'] ?? null,
|
|
15
|
+
token,
|
|
16
|
+
refreshToken,
|
|
17
|
+
raw: data,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/** GitHub may not return email in the user endpoint if it's private. Fetch from /user/emails. */
|
|
21
|
+
async user(codeOrRequest) {
|
|
22
|
+
const socialUser = await super.user(codeOrRequest);
|
|
23
|
+
if (!socialUser.getEmail()) {
|
|
24
|
+
const email = await this.fetchPrimaryEmail(socialUser.token);
|
|
25
|
+
if (email) {
|
|
26
|
+
return new SocialUser({
|
|
27
|
+
id: socialUser.getId(),
|
|
28
|
+
name: socialUser.getName(),
|
|
29
|
+
email,
|
|
30
|
+
avatar: socialUser.getAvatar(),
|
|
31
|
+
nickname: socialUser.getNickname(),
|
|
32
|
+
token: socialUser.token,
|
|
33
|
+
refreshToken: socialUser.refreshToken,
|
|
34
|
+
raw: { ...socialUser.getRaw(), email },
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return socialUser;
|
|
39
|
+
}
|
|
40
|
+
async fetchPrimaryEmail(token) {
|
|
41
|
+
try {
|
|
42
|
+
const res = await fetch('https://api.github.com/user/emails', {
|
|
43
|
+
headers: { 'Authorization': `Bearer ${token}`, 'Accept': 'application/json' },
|
|
44
|
+
});
|
|
45
|
+
if (!res.ok)
|
|
46
|
+
return null;
|
|
47
|
+
const emails = await res.json();
|
|
48
|
+
const primary = emails.find(e => e.primary && e.verified);
|
|
49
|
+
return primary?.email ?? emails[0]?.email ?? null;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/drivers/github.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,MAAM,OAAO,cAAe,SAAQ,iBAAiB;IACzC,aAAa,KAAe,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA,CAAC,CAAC;IAChE,OAAO,KAAc,OAAO,0CAA0C,CAAA,CAAC,CAAC;IACxE,QAAQ,KAAa,OAAO,6CAA6C,CAAA,CAAC,CAAC;IAC3E,OAAO,KAAc,OAAO,6BAA6B,CAAA,CAAC,CAAC;IAE3D,SAAS,CAAC,IAA6B,EAAE,KAAa,EAAE,YAA2B;QAC3F,OAAO,IAAI,UAAU,CAAC;YACpB,EAAE,EAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,EAAO,IAAI,CAAC,MAAM,CAAmB,IAAI,IAAI;YACjD,KAAK,EAAM,IAAI,CAAC,OAAO,CAAmB,IAAI,IAAI;YAClD,MAAM,EAAK,IAAI,CAAC,YAAY,CAAmB,IAAI,IAAI;YACvD,QAAQ,EAAG,IAAI,CAAC,OAAO,CAAmB,IAAI,IAAI;YAClD,KAAK;YACL,YAAY;YACZ,GAAG,EAAE,IAAI;SACV,CAAC,CAAA;IACJ,CAAC;IAED,iGAAiG;IACjG,KAAK,CAAC,IAAI,CAAC,aAAyD;QAClE,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;QAClD,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;YAC5D,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,IAAI,UAAU,CAAC;oBACpB,EAAE,EAAQ,UAAU,CAAC,KAAK,EAAE;oBAC5B,IAAI,EAAM,UAAU,CAAC,OAAO,EAAE;oBAC9B,KAAK;oBACL,MAAM,EAAI,UAAU,CAAC,SAAS,EAAE;oBAChC,QAAQ,EAAE,UAAU,CAAC,WAAW,EAAE;oBAClC,KAAK,EAAK,UAAU,CAAC,KAAK;oBAC1B,YAAY,EAAE,UAAU,CAAC,YAAY;oBACrC,GAAG,EAAE,EAAE,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE;iBACvC,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,KAAa;QAC3C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oCAAoC,EAAE;gBAC5D,OAAO,EAAE,EAAE,eAAe,EAAE,UAAU,KAAK,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE;aAC9E,CAAC,CAAA;YACF,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAA;YACxB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAA8D,CAAA;YAC3F,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAA;YACzD,OAAO,OAAO,EAAE,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI,CAAA;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SocialiteProvider } from '../provider.js';
|
|
2
|
+
import { SocialUser } from '../social-user.js';
|
|
3
|
+
export declare class GoogleProvider extends SocialiteProvider {
|
|
4
|
+
protected defaultScopes(): string[];
|
|
5
|
+
protected authUrl(): string;
|
|
6
|
+
protected tokenUrl(): string;
|
|
7
|
+
protected userUrl(): string;
|
|
8
|
+
protected mapToUser(data: Record<string, unknown>, token: string, refreshToken: string | null): SocialUser;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=google.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/drivers/google.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,qBAAa,cAAe,SAAQ,iBAAiB;IACnD,SAAS,CAAC,aAAa,IAAI,MAAM,EAAE;IACnC,SAAS,CAAC,OAAO,IAAK,MAAM;IAC5B,SAAS,CAAC,QAAQ,IAAI,MAAM;IAC5B,SAAS,CAAC,OAAO,IAAK,MAAM;IAE5B,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU;CAY3G"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SocialiteProvider } from '../provider.js';
|
|
2
|
+
import { SocialUser } from '../social-user.js';
|
|
3
|
+
export class GoogleProvider extends SocialiteProvider {
|
|
4
|
+
defaultScopes() { return ['openid', 'profile', 'email']; }
|
|
5
|
+
authUrl() { return 'https://accounts.google.com/o/oauth2/v2/auth'; }
|
|
6
|
+
tokenUrl() { return 'https://oauth2.googleapis.com/token'; }
|
|
7
|
+
userUrl() { return 'https://www.googleapis.com/oauth2/v3/userinfo'; }
|
|
8
|
+
mapToUser(data, token, refreshToken) {
|
|
9
|
+
return new SocialUser({
|
|
10
|
+
id: String(data['sub'] ?? ''),
|
|
11
|
+
name: data['name'] ?? null,
|
|
12
|
+
email: data['email'] ?? null,
|
|
13
|
+
avatar: data['picture'] ?? null,
|
|
14
|
+
nickname: null,
|
|
15
|
+
token,
|
|
16
|
+
refreshToken,
|
|
17
|
+
raw: data,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=google.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/drivers/google.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,MAAM,OAAO,cAAe,SAAQ,iBAAiB;IACzC,aAAa,KAAe,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA,CAAC,CAAC;IACnE,OAAO,KAAc,OAAO,8CAA8C,CAAA,CAAC,CAAC;IAC5E,QAAQ,KAAa,OAAO,qCAAqC,CAAA,CAAC,CAAC;IACnE,OAAO,KAAc,OAAO,+CAA+C,CAAA,CAAC,CAAC;IAE7E,SAAS,CAAC,IAA6B,EAAE,KAAa,EAAE,YAA2B;QAC3F,OAAO,IAAI,UAAU,CAAC;YACpB,EAAE,EAAQ,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,EAAO,IAAI,CAAC,MAAM,CAAmB,IAAI,IAAI;YACjD,KAAK,EAAM,IAAI,CAAC,OAAO,CAAmB,IAAI,IAAI;YAClD,MAAM,EAAK,IAAI,CAAC,SAAS,CAAmB,IAAI,IAAI;YACpD,QAAQ,EAAE,IAAI;YACd,KAAK;YACL,YAAY;YACZ,GAAG,EAAE,IAAI;SACV,CAAC,CAAA;IACJ,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ServiceProvider, type Application } from '@rudderjs/core';
|
|
2
|
+
import { SocialiteProvider, type SocialiteProviderConfig } from './provider.js';
|
|
3
|
+
export { SocialUser } from './social-user.js';
|
|
4
|
+
export { SocialiteProvider } from './provider.js';
|
|
5
|
+
export { GitHubProvider } from './drivers/github.js';
|
|
6
|
+
export { GoogleProvider } from './drivers/google.js';
|
|
7
|
+
export { FacebookProvider } from './drivers/facebook.js';
|
|
8
|
+
export { AppleProvider } from './drivers/apple.js';
|
|
9
|
+
export type { SocialiteProviderConfig } from './provider.js';
|
|
10
|
+
type ProviderFactory = (config: SocialiteProviderConfig) => SocialiteProvider;
|
|
11
|
+
export declare class Socialite {
|
|
12
|
+
private static _config;
|
|
13
|
+
private static _custom;
|
|
14
|
+
private static _instances;
|
|
15
|
+
/** Get or create a provider instance by name. */
|
|
16
|
+
static driver(name: string): SocialiteProvider;
|
|
17
|
+
/** Register a custom provider driver. */
|
|
18
|
+
static extend(name: string, factory: ProviderFactory): void;
|
|
19
|
+
/** @internal — set config from the service provider. */
|
|
20
|
+
static configure(config: SocialiteConfig): void;
|
|
21
|
+
/** @internal — reset for testing. */
|
|
22
|
+
static reset(): void;
|
|
23
|
+
}
|
|
24
|
+
export type SocialiteConfig = Record<string, SocialiteProviderConfig>;
|
|
25
|
+
/**
|
|
26
|
+
* Returns a SocialiteServiceProvider configured for OAuth.
|
|
27
|
+
*
|
|
28
|
+
* Built-in providers: github, google, facebook, apple
|
|
29
|
+
*
|
|
30
|
+
* Usage in bootstrap/providers.ts:
|
|
31
|
+
* import { socialite } from '@rudderjs/socialite'
|
|
32
|
+
* export default [..., socialite(configs.socialite), ...]
|
|
33
|
+
*/
|
|
34
|
+
export declare function socialite(config: SocialiteConfig): new (app: Application) => ServiceProvider;
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAE,iBAAiB,EAAE,KAAK,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAQ/E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,YAAY,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAI5D,KAAK,eAAe,GAAG,CAAC,MAAM,EAAE,uBAAuB,KAAK,iBAAiB,CAAA;AAW7E,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAsB;IAC5C,OAAO,CAAC,MAAM,CAAC,OAAO,CAAqC;IAC3D,OAAO,CAAC,MAAM,CAAC,UAAU,CAAuC;IAEhE,iDAAiD;IACjD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB;IAe9C,yCAAyC;IACzC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;IAI3D,wDAAwD;IACxD,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAK/C,qCAAqC;IACrC,MAAM,CAAC,KAAK,IAAI,IAAI;CAKrB;AAID,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAA;AAIrE;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,KAAK,GAAG,EAAE,WAAW,KAAK,eAAe,CAW5F"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ServiceProvider } from '@rudderjs/core';
|
|
2
|
+
import { GitHubProvider } from './drivers/github.js';
|
|
3
|
+
import { GoogleProvider } from './drivers/google.js';
|
|
4
|
+
import { FacebookProvider } from './drivers/facebook.js';
|
|
5
|
+
import { AppleProvider } from './drivers/apple.js';
|
|
6
|
+
// ─── Re-exports ───────────────────────────────────────────
|
|
7
|
+
export { SocialUser } from './social-user.js';
|
|
8
|
+
export { SocialiteProvider } from './provider.js';
|
|
9
|
+
export { GitHubProvider } from './drivers/github.js';
|
|
10
|
+
export { GoogleProvider } from './drivers/google.js';
|
|
11
|
+
export { FacebookProvider } from './drivers/facebook.js';
|
|
12
|
+
export { AppleProvider } from './drivers/apple.js';
|
|
13
|
+
const builtInDrivers = {
|
|
14
|
+
github: (c) => new GitHubProvider(c),
|
|
15
|
+
google: (c) => new GoogleProvider(c),
|
|
16
|
+
facebook: (c) => new FacebookProvider(c),
|
|
17
|
+
apple: (c) => new AppleProvider(c),
|
|
18
|
+
};
|
|
19
|
+
// ─── Socialite Facade ─────────────────────────────────────
|
|
20
|
+
export class Socialite {
|
|
21
|
+
static _config = {};
|
|
22
|
+
static _custom = new Map();
|
|
23
|
+
static _instances = new Map();
|
|
24
|
+
/** Get or create a provider instance by name. */
|
|
25
|
+
static driver(name) {
|
|
26
|
+
const existing = this._instances.get(name);
|
|
27
|
+
if (existing)
|
|
28
|
+
return existing;
|
|
29
|
+
const config = this._config[name];
|
|
30
|
+
if (!config)
|
|
31
|
+
throw new Error(`[RudderJS Socialite] Provider "${name}" is not configured.`);
|
|
32
|
+
const factory = this._custom.get(name) ?? builtInDrivers[name];
|
|
33
|
+
if (!factory)
|
|
34
|
+
throw new Error(`[RudderJS Socialite] Unknown provider "${name}". Use Socialite.extend() to register custom providers.`);
|
|
35
|
+
const instance = factory(config);
|
|
36
|
+
this._instances.set(name, instance);
|
|
37
|
+
return instance;
|
|
38
|
+
}
|
|
39
|
+
/** Register a custom provider driver. */
|
|
40
|
+
static extend(name, factory) {
|
|
41
|
+
this._custom.set(name, factory);
|
|
42
|
+
}
|
|
43
|
+
/** @internal — set config from the service provider. */
|
|
44
|
+
static configure(config) {
|
|
45
|
+
this._config = config;
|
|
46
|
+
this._instances.clear();
|
|
47
|
+
}
|
|
48
|
+
/** @internal — reset for testing. */
|
|
49
|
+
static reset() {
|
|
50
|
+
this._config = {};
|
|
51
|
+
this._custom.clear();
|
|
52
|
+
this._instances.clear();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// ─── Service Provider Factory ─────────────────────────────
|
|
56
|
+
/**
|
|
57
|
+
* Returns a SocialiteServiceProvider configured for OAuth.
|
|
58
|
+
*
|
|
59
|
+
* Built-in providers: github, google, facebook, apple
|
|
60
|
+
*
|
|
61
|
+
* Usage in bootstrap/providers.ts:
|
|
62
|
+
* import { socialite } from '@rudderjs/socialite'
|
|
63
|
+
* export default [..., socialite(configs.socialite), ...]
|
|
64
|
+
*/
|
|
65
|
+
export function socialite(config) {
|
|
66
|
+
class SocialiteServiceProvider extends ServiceProvider {
|
|
67
|
+
register() { }
|
|
68
|
+
async boot() {
|
|
69
|
+
Socialite.configure(config);
|
|
70
|
+
this.app.instance('socialite', Socialite);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return SocialiteServiceProvider;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { SocialUser } from './social-user.js';
|
|
2
|
+
export interface SocialiteProviderConfig {
|
|
3
|
+
clientId: string;
|
|
4
|
+
clientSecret: string;
|
|
5
|
+
redirectUrl: string;
|
|
6
|
+
scopes?: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare abstract class SocialiteProvider {
|
|
9
|
+
protected readonly config: SocialiteProviderConfig;
|
|
10
|
+
protected scopes: string[];
|
|
11
|
+
constructor(config: SocialiteProviderConfig);
|
|
12
|
+
/** Default scopes for this provider. */
|
|
13
|
+
protected abstract defaultScopes(): string[];
|
|
14
|
+
/** OAuth authorize URL (e.g. https://github.com/login/oauth/authorize). */
|
|
15
|
+
protected abstract authUrl(): string;
|
|
16
|
+
/** OAuth token URL (e.g. https://github.com/login/oauth/access_token). */
|
|
17
|
+
protected abstract tokenUrl(): string;
|
|
18
|
+
/** User info URL (e.g. https://api.github.com/user). */
|
|
19
|
+
protected abstract userUrl(): string;
|
|
20
|
+
/** Parse the provider's user API response into a SocialUser. */
|
|
21
|
+
protected abstract mapToUser(data: Record<string, unknown>, token: string, refreshToken: string | null): SocialUser;
|
|
22
|
+
/** Add extra scopes. */
|
|
23
|
+
withScopes(scopes: string[]): this;
|
|
24
|
+
/** Set scopes (replacing defaults). */
|
|
25
|
+
setScopes(scopes: string[]): this;
|
|
26
|
+
/** Get the redirect URL to the OAuth provider. */
|
|
27
|
+
getRedirectUrl(state?: string): string;
|
|
28
|
+
/** Redirect the response to the OAuth provider. */
|
|
29
|
+
redirect(state?: string): Response;
|
|
30
|
+
/** Exchange the authorization code for an access token. */
|
|
31
|
+
getAccessToken(code: string): Promise<{
|
|
32
|
+
accessToken: string;
|
|
33
|
+
refreshToken: string | null;
|
|
34
|
+
expiresIn: number | null;
|
|
35
|
+
}>;
|
|
36
|
+
/** Get the authenticated user from the OAuth callback. */
|
|
37
|
+
user(codeOrRequest: string | {
|
|
38
|
+
query: Record<string, string>;
|
|
39
|
+
}): Promise<SocialUser>;
|
|
40
|
+
/** Get the user directly from an access token (e.g. for mobile apps). */
|
|
41
|
+
getUserByToken(token: string, refreshToken?: string | null): Promise<SocialUser>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAI7C,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAM,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAG,MAAM,CAAA;IACpB,MAAM,CAAC,EAAO,MAAM,EAAE,CAAA;CACvB;AAED,8BAAsB,iBAAiB;IAGzB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,uBAAuB;IAF9D,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,CAAA;gBAEK,MAAM,EAAE,uBAAuB;IAI9D,wCAAwC;IACxC,SAAS,CAAC,QAAQ,CAAC,aAAa,IAAI,MAAM,EAAE;IAE5C,2EAA2E;IAC3E,SAAS,CAAC,QAAQ,CAAC,OAAO,IAAI,MAAM;IAEpC,0EAA0E;IAC1E,SAAS,CAAC,QAAQ,CAAC,QAAQ,IAAI,MAAM;IAErC,wDAAwD;IACxD,SAAS,CAAC,QAAQ,CAAC,OAAO,IAAI,MAAM;IAEpC,gEAAgE;IAChE,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU;IAEnH,wBAAwB;IACxB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAKlC,uCAAuC;IACvC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAKjC,kDAAkD;IAClD,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;IAWtC,mDAAmD;IACnD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ;IAIlC,2DAA2D;IACrD,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAmC3H,0DAA0D;IACpD,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAW1F,yEAAyE;IACnE,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC;CAgBvF"}
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export class SocialiteProvider {
|
|
2
|
+
config;
|
|
3
|
+
scopes;
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.config = config;
|
|
6
|
+
this.scopes = config.scopes ?? this.defaultScopes();
|
|
7
|
+
}
|
|
8
|
+
/** Add extra scopes. */
|
|
9
|
+
withScopes(scopes) {
|
|
10
|
+
this.scopes = [...new Set([...this.scopes, ...scopes])];
|
|
11
|
+
return this;
|
|
12
|
+
}
|
|
13
|
+
/** Set scopes (replacing defaults). */
|
|
14
|
+
setScopes(scopes) {
|
|
15
|
+
this.scopes = scopes;
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
/** Get the redirect URL to the OAuth provider. */
|
|
19
|
+
getRedirectUrl(state) {
|
|
20
|
+
const params = new URLSearchParams({
|
|
21
|
+
client_id: this.config.clientId,
|
|
22
|
+
redirect_uri: this.config.redirectUrl,
|
|
23
|
+
response_type: 'code',
|
|
24
|
+
scope: this.scopes.join(' '),
|
|
25
|
+
...(state ? { state } : {}),
|
|
26
|
+
});
|
|
27
|
+
return `${this.authUrl()}?${params.toString()}`;
|
|
28
|
+
}
|
|
29
|
+
/** Redirect the response to the OAuth provider. */
|
|
30
|
+
redirect(state) {
|
|
31
|
+
return Response.redirect(this.getRedirectUrl(state), 302);
|
|
32
|
+
}
|
|
33
|
+
/** Exchange the authorization code for an access token. */
|
|
34
|
+
async getAccessToken(code) {
|
|
35
|
+
const res = await fetch(this.tokenUrl(), {
|
|
36
|
+
method: 'POST',
|
|
37
|
+
headers: {
|
|
38
|
+
'Content-Type': 'application/json',
|
|
39
|
+
'Accept': 'application/json',
|
|
40
|
+
},
|
|
41
|
+
body: JSON.stringify({
|
|
42
|
+
client_id: this.config.clientId,
|
|
43
|
+
client_secret: this.config.clientSecret,
|
|
44
|
+
code,
|
|
45
|
+
redirect_uri: this.config.redirectUrl,
|
|
46
|
+
grant_type: 'authorization_code',
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
if (!res.ok) {
|
|
50
|
+
const text = await res.text();
|
|
51
|
+
throw new Error(`[RudderJS Socialite] Token exchange failed: ${res.status} ${text}`);
|
|
52
|
+
}
|
|
53
|
+
const data = await res.json();
|
|
54
|
+
// Some providers return access_token, others return it in different shapes
|
|
55
|
+
const accessToken = (data['access_token'] ?? data['accessToken']);
|
|
56
|
+
const refreshToken = (data['refresh_token'] ?? data['refreshToken']);
|
|
57
|
+
const expiresIn = (data['expires_in'] ?? data['expiresIn']);
|
|
58
|
+
if (!accessToken) {
|
|
59
|
+
throw new Error(`[RudderJS Socialite] No access_token in response: ${JSON.stringify(data)}`);
|
|
60
|
+
}
|
|
61
|
+
return { accessToken, refreshToken: refreshToken ?? null, expiresIn: expiresIn ?? null };
|
|
62
|
+
}
|
|
63
|
+
/** Get the authenticated user from the OAuth callback. */
|
|
64
|
+
async user(codeOrRequest) {
|
|
65
|
+
const code = typeof codeOrRequest === 'string'
|
|
66
|
+
? codeOrRequest
|
|
67
|
+
: codeOrRequest.query['code'];
|
|
68
|
+
if (!code)
|
|
69
|
+
throw new Error('[RudderJS Socialite] Missing authorization code.');
|
|
70
|
+
const { accessToken, refreshToken } = await this.getAccessToken(code);
|
|
71
|
+
return this.getUserByToken(accessToken, refreshToken);
|
|
72
|
+
}
|
|
73
|
+
/** Get the user directly from an access token (e.g. for mobile apps). */
|
|
74
|
+
async getUserByToken(token, refreshToken) {
|
|
75
|
+
const res = await fetch(this.userUrl(), {
|
|
76
|
+
headers: {
|
|
77
|
+
'Authorization': `Bearer ${token}`,
|
|
78
|
+
'Accept': 'application/json',
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
if (!res.ok) {
|
|
82
|
+
const text = await res.text();
|
|
83
|
+
throw new Error(`[RudderJS Socialite] User info request failed: ${res.status} ${text}`);
|
|
84
|
+
}
|
|
85
|
+
const data = await res.json();
|
|
86
|
+
return this.mapToUser(data, token, refreshToken ?? null);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare class SocialUser {
|
|
2
|
+
private readonly data;
|
|
3
|
+
constructor(data: {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string | null;
|
|
6
|
+
email: string | null;
|
|
7
|
+
avatar: string | null;
|
|
8
|
+
nickname: string | null;
|
|
9
|
+
token: string;
|
|
10
|
+
refreshToken?: string | null;
|
|
11
|
+
expiresIn?: number | null;
|
|
12
|
+
raw: Record<string, unknown>;
|
|
13
|
+
});
|
|
14
|
+
getId(): string;
|
|
15
|
+
getName(): string | null;
|
|
16
|
+
getEmail(): string | null;
|
|
17
|
+
getAvatar(): string | null;
|
|
18
|
+
getNickname(): string | null;
|
|
19
|
+
/** The access token from the OAuth provider. */
|
|
20
|
+
get token(): string;
|
|
21
|
+
get refreshToken(): string | null;
|
|
22
|
+
get expiresIn(): number | null;
|
|
23
|
+
/** Raw user data from the provider's API. */
|
|
24
|
+
getRaw(): Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=social-user.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"social-user.d.ts","sourceRoot":"","sources":["../src/social-user.ts"],"names":[],"mappings":"AAGA,qBAAa,UAAU;IAEnB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE;QACrB,EAAE,EAAQ,MAAM,CAAA;QAChB,IAAI,EAAM,MAAM,GAAG,IAAI,CAAA;QACvB,KAAK,EAAK,MAAM,GAAG,IAAI,CAAA;QACvB,MAAM,EAAI,MAAM,GAAG,IAAI,CAAA;QACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;QACvB,KAAK,EAAK,MAAM,CAAA;QAChB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,GAAG,EAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAClC;IAGH,KAAK,IAAU,MAAM;IACrB,OAAO,IAAQ,MAAM,GAAG,IAAI;IAC5B,QAAQ,IAAO,MAAM,GAAG,IAAI;IAC5B,SAAS,IAAM,MAAM,GAAG,IAAI;IAC5B,WAAW,IAAI,MAAM,GAAG,IAAI;IAE5B,gDAAgD;IAChD,IAAI,KAAK,IAAW,MAAM,CAAuC;IACjE,IAAI,YAAY,IAAI,MAAM,GAAG,IAAI,CAA+C;IAChF,IAAI,SAAS,IAAO,MAAM,GAAG,IAAI,CAA4C;IAE7E,6CAA6C;IAC7C,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAClC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// ─── Social User ──────────────────────────────────────────
|
|
2
|
+
// Normalized user returned by all OAuth providers.
|
|
3
|
+
export class SocialUser {
|
|
4
|
+
data;
|
|
5
|
+
constructor(data) {
|
|
6
|
+
this.data = data;
|
|
7
|
+
}
|
|
8
|
+
getId() { return this.data.id; }
|
|
9
|
+
getName() { return this.data.name; }
|
|
10
|
+
getEmail() { return this.data.email; }
|
|
11
|
+
getAvatar() { return this.data.avatar; }
|
|
12
|
+
getNickname() { return this.data.nickname; }
|
|
13
|
+
/** The access token from the OAuth provider. */
|
|
14
|
+
get token() { return this.data.token; }
|
|
15
|
+
get refreshToken() { return this.data.refreshToken ?? null; }
|
|
16
|
+
get expiresIn() { return this.data.expiresIn ?? null; }
|
|
17
|
+
/** Raw user data from the provider's API. */
|
|
18
|
+
getRaw() { return this.data.raw; }
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=social-user.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"social-user.js","sourceRoot":"","sources":["../src/social-user.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,mDAAmD;AAEnD,MAAM,OAAO,UAAU;IAEF;IADnB,YACmB,IAUhB;QAVgB,SAAI,GAAJ,IAAI,CAUpB;IACA,CAAC;IAEJ,KAAK,KAAyB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA,CAAC,CAAC;IACnD,OAAO,KAAwB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA,CAAC,CAAC;IACtD,QAAQ,KAAuB,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAA,CAAC,CAAC;IACvD,SAAS,KAAsB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAA,CAAC,CAAC;IACxD,WAAW,KAAoB,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAA,CAAC,CAAC;IAE1D,gDAAgD;IAChD,IAAI,KAAK,KAAgC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAA,CAAC,CAAC;IACjE,IAAI,YAAY,KAAyB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAA,CAAC,CAAC;IAChF,IAAI,SAAS,KAA4B,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAA,CAAC,CAAC;IAE7E,6CAA6C;IAC7C,MAAM,KAA8B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAA,CAAC,CAAC;CAC3D"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rudderjs/socialite",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/rudderjs/rudder",
|
|
8
|
+
"directory": "packages/socialite"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@rudderjs/core": "0.0.8"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^20.0.0",
|
|
27
|
+
"typescript": "^5.4.0"
|
|
28
|
+
},
|
|
29
|
+
"author": "Suleiman Shahbari",
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc -p tsconfig.build.json",
|
|
32
|
+
"dev": "tsc -p tsconfig.build.json --watch",
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"lint": "eslint src",
|
|
35
|
+
"clean": "rm -rf dist",
|
|
36
|
+
"test": "tsc -p tsconfig.test.json && node --test dist-test/index.test.js; EXIT=$?; rm -rf dist-test; exit $EXIT"
|
|
37
|
+
}
|
|
38
|
+
}
|