@rudderjs/socialite 0.0.7 → 1.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 +2 -2
- package/boost/guidelines.md +118 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -28,8 +28,8 @@ export default {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// bootstrap/providers.ts
|
|
31
|
-
import {
|
|
32
|
-
export default [
|
|
31
|
+
import { SocialiteProvider } from '@rudderjs/socialite'
|
|
32
|
+
export default [SocialiteProvider]
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
## Usage
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# @rudderjs/socialite
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
OAuth authentication for third-party sign-in — GitHub, Google, Facebook, Apple out of the box, plus a driver contract for custom providers. Laravel's Socialite for Node. Handles the redirect → callback → exchange → user-fetch flow; you wire the routes. Pairs with `@rudderjs/auth` — after exchange, you call `Auth.login(user)` with a local user you've linked to the social profile.
|
|
6
|
+
|
|
7
|
+
## Key Patterns
|
|
8
|
+
|
|
9
|
+
### Setup
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
// config/socialite.ts
|
|
13
|
+
export default {
|
|
14
|
+
github: {
|
|
15
|
+
clientId: process.env.GITHUB_CLIENT_ID!,
|
|
16
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
17
|
+
redirectUrl: 'http://localhost:3000/auth/github/callback',
|
|
18
|
+
},
|
|
19
|
+
google: { clientId: '...', clientSecret: '...', redirectUrl: '...' },
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// bootstrap/providers.ts
|
|
23
|
+
import { SocialiteProvider } from '@rudderjs/socialite'
|
|
24
|
+
export default [SocialiteProvider]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### OAuth flow
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { Socialite } from '@rudderjs/socialite'
|
|
31
|
+
import { Auth } from '@rudderjs/auth'
|
|
32
|
+
|
|
33
|
+
// 1. Redirect to provider
|
|
34
|
+
Route.get('/auth/github', () => {
|
|
35
|
+
return Socialite.driver('github').redirect()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
// 2. Handle callback → exchange code → fetch profile → log in
|
|
39
|
+
Route.get('/auth/github/callback', async (req) => {
|
|
40
|
+
const socialUser = await Socialite.driver('github').user(req)
|
|
41
|
+
|
|
42
|
+
// socialUser exposes: getId(), getName(), getEmail(), getAvatar(), getToken()
|
|
43
|
+
const id = socialUser.getId()
|
|
44
|
+
const email = socialUser.getEmail()
|
|
45
|
+
|
|
46
|
+
// Find or create a local user
|
|
47
|
+
let user = await User.where('email', email).first()
|
|
48
|
+
if (!user) {
|
|
49
|
+
user = await User.create({ email, name: socialUser.getName() })
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Log in via @rudderjs/auth
|
|
53
|
+
await Auth.login(user)
|
|
54
|
+
return redirect('/dashboard')
|
|
55
|
+
})
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Scopes + state
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
Socialite.driver('github')
|
|
62
|
+
.scopes(['user:email', 'read:org'])
|
|
63
|
+
.with({ allow_signup: 'false' }) // extra query params
|
|
64
|
+
.redirect()
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
State (CSRF) is handled automatically — stored in the session and verified on callback.
|
|
68
|
+
|
|
69
|
+
### Custom providers
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { Socialite, SocialiteDriver } from '@rudderjs/socialite'
|
|
73
|
+
|
|
74
|
+
class DiscordDriver extends SocialiteDriver {
|
|
75
|
+
protected authUrl = 'https://discord.com/api/oauth2/authorize'
|
|
76
|
+
protected tokenUrl = 'https://discord.com/api/oauth2/token'
|
|
77
|
+
protected userUrl = 'https://discord.com/api/users/@me'
|
|
78
|
+
|
|
79
|
+
protected mapUser(raw: any) {
|
|
80
|
+
return {
|
|
81
|
+
id: raw.id,
|
|
82
|
+
name: raw.username,
|
|
83
|
+
email: raw.email,
|
|
84
|
+
avatar: `https://cdn.discordapp.com/avatars/${raw.id}/${raw.avatar}.png`,
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
Socialite.extend('discord', (cfg) => new DiscordDriver(cfg))
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### SocialUser interface
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
socialUser.getId() // provider's user id
|
|
96
|
+
socialUser.getName()
|
|
97
|
+
socialUser.getEmail()
|
|
98
|
+
socialUser.getAvatar()
|
|
99
|
+
socialUser.getToken() // access token
|
|
100
|
+
socialUser.getRaw() // full raw provider response
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Common Pitfalls
|
|
104
|
+
|
|
105
|
+
- **Missing `redirectUrl` registration with the provider.** Each provider requires the callback URL to be pre-registered in its developer console. Mismatched URLs (e.g. `http` vs `https`, trailing slash) cause silent redirect failures.
|
|
106
|
+
- **State mismatch on callback.** State is stored in the session — if the callback request doesn't carry the same session cookie (cross-domain, SameSite=strict, third-party cookie blocking), state validation fails. Make sure `SameSite=lax` (the default) for the auth callback routes.
|
|
107
|
+
- **Skipping `Auth.login()` after exchange.** `Socialite.user(req)` returns the social profile but does NOT log anyone in. You must find/create a local user and call `Auth.login(user)` yourself.
|
|
108
|
+
- **Handling "email not verified" or "email missing".** Some providers (GitHub with private email, Apple always) don't return email on first auth. Prompt the user for email after the social flow if the social email is empty.
|
|
109
|
+
- **Account linking.** If `user@example.com` signs up via email then later via Google, you need your own logic to link them. Socialite doesn't do this — find-by-email in the callback handler is the usual pattern.
|
|
110
|
+
- **Testing.** Use fixture responses + HTTP fake. Don't hit real OAuth endpoints in tests.
|
|
111
|
+
|
|
112
|
+
## Key Imports
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import { SocialiteProvider, Socialite, SocialiteDriver } from '@rudderjs/socialite'
|
|
116
|
+
|
|
117
|
+
import type { SocialiteConfig, SocialUser } from '@rudderjs/socialite'
|
|
118
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rudderjs/socialite",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"rudderjs": {
|
|
5
5
|
"provider": "SocialiteProvider",
|
|
6
6
|
"stage": "feature"
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
},
|
|
14
14
|
"type": "module",
|
|
15
15
|
"files": [
|
|
16
|
-
"dist"
|
|
16
|
+
"dist",
|
|
17
|
+
"boost"
|
|
17
18
|
],
|
|
18
19
|
"main": "./dist/index.js",
|
|
19
20
|
"types": "./dist/index.d.ts",
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
}
|
|
25
26
|
},
|
|
26
27
|
"dependencies": {
|
|
27
|
-
"@rudderjs/core": "
|
|
28
|
+
"@rudderjs/core": "^1.1.2"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"@types/node": "^20.0.0",
|