@rudderjs/socialite 1.1.0 → 2.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/README.md +4 -5
- package/boost/guidelines.md +45 -26
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -27,11 +27,10 @@ export default {
|
|
|
27
27
|
},
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
// bootstrap/providers.ts
|
|
31
|
-
import { SocialiteProvider } from '@rudderjs/socialite'
|
|
32
|
-
export default [SocialiteProvider]
|
|
33
30
|
```
|
|
34
31
|
|
|
32
|
+
`SocialiteProvider` is picked up by [auto-discovery](https://github.com/rudderjs/rudder/blob/main/docs/guide/service-providers.md#auto-discovery) — `pnpm rudder providers:discover` is all that's needed.
|
|
33
|
+
|
|
35
34
|
## Usage
|
|
36
35
|
|
|
37
36
|
```ts
|
|
@@ -154,9 +153,9 @@ request shape — `@rudderjs/server-hono` already does this.
|
|
|
154
153
|
## Custom Providers
|
|
155
154
|
|
|
156
155
|
```ts
|
|
157
|
-
import {
|
|
156
|
+
import { SocialiteDriver, SocialUser, Socialite } from '@rudderjs/socialite'
|
|
158
157
|
|
|
159
|
-
class GitLabProvider extends
|
|
158
|
+
class GitLabProvider extends SocialiteDriver {
|
|
160
159
|
protected defaultScopes() { return ['read_user'] }
|
|
161
160
|
protected authUrl() { return 'https://gitlab.com/oauth/authorize' }
|
|
162
161
|
protected tokenUrl() { return 'https://gitlab.com/oauth/token' }
|
package/boost/guidelines.md
CHANGED
|
@@ -39,9 +39,11 @@ Route.get('/auth/github', () => {
|
|
|
39
39
|
Route.get('/auth/github/callback', async (req) => {
|
|
40
40
|
const socialUser = await Socialite.driver('github').user(req)
|
|
41
41
|
|
|
42
|
-
// socialUser
|
|
43
|
-
|
|
44
|
-
const
|
|
42
|
+
// socialUser methods: getId(), getName(), getEmail(), getAvatar(), getNickname(), getRaw()
|
|
43
|
+
// socialUser getters: .token, .refreshToken, .expiresIn
|
|
44
|
+
const id = socialUser.getId()
|
|
45
|
+
const email = socialUser.getEmail()
|
|
46
|
+
const accessToken = socialUser.token
|
|
45
47
|
|
|
46
48
|
// Find or create a local user
|
|
47
49
|
let user = await User.where('email', email).first()
|
|
@@ -58,31 +60,42 @@ Route.get('/auth/github/callback', async (req) => {
|
|
|
58
60
|
### Scopes + state
|
|
59
61
|
|
|
60
62
|
```ts
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
// Replace defaults
|
|
64
|
+
Socialite.driver('github').setScopes(['user:email', 'read:org']).redirect()
|
|
65
|
+
|
|
66
|
+
// Or extend defaults — withScopes() merges, deduped
|
|
67
|
+
Socialite.driver('github').withScopes(['read:org']).redirect()
|
|
68
|
+
|
|
69
|
+
// Skip CSRF state (mobile / machine-to-machine flows that can't reach the session)
|
|
70
|
+
Socialite.driver('github').stateless().redirect()
|
|
65
71
|
```
|
|
66
72
|
|
|
67
|
-
State (CSRF) is handled automatically — stored in the session and verified on callback.
|
|
73
|
+
State (CSRF) is handled automatically — stored in the session and verified on callback. To inject extra provider-specific query parameters (`prompt=consent`, Apple's `response_mode=form_post`, etc.), override `extraAuthParams()` on a custom driver subclass — there is no fluent `.with({...})` method.
|
|
68
74
|
|
|
69
75
|
### Custom providers
|
|
70
76
|
|
|
77
|
+
`SocialiteDriver` declares `authUrl`, `tokenUrl`, `userUrl`, `defaultScopes`, and `mapToUser` as abstract **methods** (not properties). Override each:
|
|
78
|
+
|
|
71
79
|
```ts
|
|
72
|
-
import { Socialite, SocialiteDriver } from '@rudderjs/socialite'
|
|
80
|
+
import { Socialite, SocialiteDriver, SocialUser } from '@rudderjs/socialite'
|
|
73
81
|
|
|
74
82
|
class DiscordDriver extends SocialiteDriver {
|
|
75
|
-
protected
|
|
76
|
-
protected
|
|
77
|
-
protected
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
protected defaultScopes() { return ['identify', 'email'] }
|
|
84
|
+
protected authUrl() { return 'https://discord.com/api/oauth2/authorize' }
|
|
85
|
+
protected tokenUrl() { return 'https://discord.com/api/oauth2/token' }
|
|
86
|
+
protected userUrl() { return 'https://discord.com/api/users/@me' }
|
|
87
|
+
|
|
88
|
+
protected mapToUser(raw: Record<string, unknown>, token: string, refreshToken: string | null): SocialUser {
|
|
89
|
+
return new SocialUser({
|
|
90
|
+
id: String(raw['id']),
|
|
91
|
+
name: (raw['username'] as string) ?? null,
|
|
92
|
+
email: (raw['email'] as string) ?? null,
|
|
93
|
+
avatar: raw['avatar'] ? `https://cdn.discordapp.com/avatars/${raw['id']}/${raw['avatar']}.png` : null,
|
|
94
|
+
nickname: null,
|
|
95
|
+
token,
|
|
96
|
+
refreshToken,
|
|
97
|
+
raw,
|
|
98
|
+
})
|
|
86
99
|
}
|
|
87
100
|
}
|
|
88
101
|
|
|
@@ -92,12 +105,18 @@ Socialite.extend('discord', (cfg) => new DiscordDriver(cfg))
|
|
|
92
105
|
### SocialUser interface
|
|
93
106
|
|
|
94
107
|
```ts
|
|
95
|
-
|
|
96
|
-
socialUser.
|
|
97
|
-
socialUser.
|
|
98
|
-
socialUser.
|
|
99
|
-
socialUser.
|
|
100
|
-
socialUser.
|
|
108
|
+
// Methods
|
|
109
|
+
socialUser.getId() // provider's user id (always string)
|
|
110
|
+
socialUser.getName() // string | null
|
|
111
|
+
socialUser.getEmail() // string | null
|
|
112
|
+
socialUser.getAvatar() // string | null
|
|
113
|
+
socialUser.getNickname() // string | null
|
|
114
|
+
socialUser.getRaw() // Record<string, unknown> — full raw provider response
|
|
115
|
+
|
|
116
|
+
// Getters (not methods)
|
|
117
|
+
socialUser.token // access token
|
|
118
|
+
socialUser.refreshToken // string | null
|
|
119
|
+
socialUser.expiresIn // number | null
|
|
101
120
|
```
|
|
102
121
|
|
|
103
122
|
## Common Pitfalls
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rudderjs/socialite",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"rudderjs": {
|
|
5
5
|
"provider": "SocialiteProvider",
|
|
6
6
|
"stage": "feature"
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
"directory": "packages/socialite"
|
|
13
13
|
},
|
|
14
14
|
"type": "module",
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
17
|
+
},
|
|
15
18
|
"files": [
|
|
16
19
|
"dist",
|
|
17
20
|
"boost"
|
|
@@ -25,10 +28,10 @@
|
|
|
25
28
|
}
|
|
26
29
|
},
|
|
27
30
|
"dependencies": {
|
|
28
|
-
"@rudderjs/core": "^1.1.
|
|
31
|
+
"@rudderjs/core": "^1.1.5"
|
|
29
32
|
},
|
|
30
33
|
"peerDependencies": {
|
|
31
|
-
"@rudderjs/session": "^
|
|
34
|
+
"@rudderjs/session": "^2.0.1"
|
|
32
35
|
},
|
|
33
36
|
"peerDependenciesMeta": {
|
|
34
37
|
"@rudderjs/session": {
|
|
@@ -38,7 +41,7 @@
|
|
|
38
41
|
"devDependencies": {
|
|
39
42
|
"@types/node": "^20.0.0",
|
|
40
43
|
"typescript": "^5.4.0",
|
|
41
|
-
"@rudderjs/session": "^
|
|
44
|
+
"@rudderjs/session": "^2.0.1"
|
|
42
45
|
},
|
|
43
46
|
"author": "Suleiman Shahbari",
|
|
44
47
|
"scripts": {
|