chadstart 1.0.0 → 1.0.2
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/.devcontainer/devcontainer.json +34 -0
- package/.env.example +30 -1
- package/.github/workflows/db-integration.yml +139 -0
- package/.github/workflows/npm-chadstart.yml +12 -1
- package/.github/workflows/npm-sdk.yml +12 -1
- package/chadstart.example.yml +52 -0
- package/chadstart.schema.json +62 -0
- package/core/api-generator.js +36 -36
- package/core/auth.js +76 -65
- package/core/db.js +324 -149
- package/core/entity-engine.js +1 -0
- package/core/oauth.js +263 -0
- package/core/seeder.js +3 -3
- package/docs/auth.md +3 -0
- package/docs/config.md +8 -8
- package/docs/oauth.md +869 -0
- package/mkdocs.yml +1 -0
- package/package.json +5 -1
- package/server/express-server.js +20 -18
- package/test/access-policies.test.js +8 -8
- package/test/api-keys.test.js +28 -28
- package/test/auth.test.js +18 -18
- package/test/db.test.js +71 -71
- package/test/groups.test.js +5 -5
- package/test/integration/db-integration.test.js +368 -0
- package/test/middleware.test.js +1 -1
- package/test/oauth.test.js +259 -0
- package/test/sdk.test.js +19 -19
- package/test/seeder.test.js +26 -26
package/docs/oauth.md
ADDED
|
@@ -0,0 +1,869 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: oauth
|
|
3
|
+
title: OAuth / Social Login
|
|
4
|
+
description: Add "Login with Google", "Login with GitHub", and 200+ other OAuth providers to your ChadStart app in minutes.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# OAuth / Social Login
|
|
8
|
+
|
|
9
|
+
## Introduction
|
|
10
|
+
|
|
11
|
+
ChadStart supports **OAuth / Social Login** via the [grant](https://www.npmjs.com/package/grant) library, giving you access to **200+ OAuth providers** out of the box. Users can sign in with their existing accounts on platforms like Google, GitHub, Facebook, Discord, and many more — no custom OAuth flow code required.
|
|
12
|
+
|
|
13
|
+
When a user logs in via an OAuth provider, ChadStart will:
|
|
14
|
+
|
|
15
|
+
1. Redirect the user to the provider's authorization page.
|
|
16
|
+
2. Handle the callback and extract the user's profile.
|
|
17
|
+
3. Find an existing user by email or create a new one in your authenticable entity.
|
|
18
|
+
4. Return a **JWT token** (same format as email/password login).
|
|
19
|
+
|
|
20
|
+
!!! info
|
|
21
|
+
OAuth secrets (**client IDs** and **client secrets**) must always be stored in environment variables — never in your YAML config file.
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### 1. Register your app with the provider
|
|
26
|
+
|
|
27
|
+
Visit the provider's developer console and create an OAuth application. You will receive a **Client ID** (key) and **Client Secret**.
|
|
28
|
+
|
|
29
|
+
Set the **Redirect URI** (callback URL) to:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
https://your-domain.com/connect/<provider>/callback
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
For local development:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
http://localhost:3000/connect/<provider>/callback
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2. Set environment variables
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# .env
|
|
45
|
+
OAUTH_GOOGLE_KEY=your-google-client-id
|
|
46
|
+
OAUTH_GOOGLE_SECRET=your-google-client-secret
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The pattern is always `OAUTH_<PROVIDER>_KEY` and `OAUTH_<PROVIDER>_SECRET` where `<PROVIDER>` is the provider name in **UPPERCASE**.
|
|
50
|
+
|
|
51
|
+
### 3. Add OAuth config to your YAML
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
oauth:
|
|
55
|
+
entity: User # Which authenticable entity to use
|
|
56
|
+
successRedirect: /dashboard # Where to redirect after login
|
|
57
|
+
providers:
|
|
58
|
+
google:
|
|
59
|
+
scope:
|
|
60
|
+
- openid
|
|
61
|
+
- email
|
|
62
|
+
- profile
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 4. Add a login button
|
|
66
|
+
|
|
67
|
+
```html
|
|
68
|
+
<a href="/connect/google">Login with Google</a>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
That's it! ChadStart handles the entire OAuth dance automatically.
|
|
72
|
+
|
|
73
|
+
## Configuration Reference
|
|
74
|
+
|
|
75
|
+
The `oauth` section in your YAML config supports the following options:
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
oauth:
|
|
79
|
+
# Target authenticable entity for OAuth users.
|
|
80
|
+
# Default: first authenticable entity in your config.
|
|
81
|
+
entity: User
|
|
82
|
+
|
|
83
|
+
# Redirect URL after successful login (?token=JWT is appended).
|
|
84
|
+
# If omitted, returns JSON: { token, user }
|
|
85
|
+
successRedirect: /dashboard
|
|
86
|
+
|
|
87
|
+
# Redirect URL on error (?error=message is appended).
|
|
88
|
+
# If omitted, returns JSON: { error }
|
|
89
|
+
errorRedirect: /login?error=true
|
|
90
|
+
|
|
91
|
+
# Default settings for all providers
|
|
92
|
+
defaults:
|
|
93
|
+
transport: querystring
|
|
94
|
+
|
|
95
|
+
# Provider configurations
|
|
96
|
+
providers:
|
|
97
|
+
google:
|
|
98
|
+
scope:
|
|
99
|
+
- openid
|
|
100
|
+
- email
|
|
101
|
+
- profile
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Provider Options
|
|
105
|
+
|
|
106
|
+
Each provider entry supports these options:
|
|
107
|
+
|
|
108
|
+
| Option | Type | Description |
|
|
109
|
+
|--------|------|-------------|
|
|
110
|
+
| `scope` | `string` or `string[]` | OAuth scopes to request |
|
|
111
|
+
| `callback` | `string` | Custom callback URL (default: `/api/auth/oauth/callback`) |
|
|
112
|
+
| `custom_params` | `object` | Extra query parameters for the authorization URL |
|
|
113
|
+
| `subdomain` | `string` | Required by some providers (e.g., Shopify) |
|
|
114
|
+
| `nonce` | `boolean` | Enable nonce generation (some OIDC providers) |
|
|
115
|
+
| `pkce` | `boolean` | Enable PKCE for enhanced security |
|
|
116
|
+
| `response` | `string[]` | Data to include in callback (e.g., `['tokens', 'profile']`) |
|
|
117
|
+
|
|
118
|
+
### Environment Variables
|
|
119
|
+
|
|
120
|
+
| Variable | Description |
|
|
121
|
+
|----------|-------------|
|
|
122
|
+
| `OAUTH_<PROVIDER>_KEY` | Client/App ID for the provider |
|
|
123
|
+
| `OAUTH_<PROVIDER>_SECRET` | Client/App Secret for the provider |
|
|
124
|
+
| `BASE_URL` | Your application's public URL (used to build redirect URIs) |
|
|
125
|
+
|
|
126
|
+
## API Endpoints
|
|
127
|
+
|
|
128
|
+
Once OAuth is configured, the following endpoints are available:
|
|
129
|
+
|
|
130
|
+
| Method | Path | Description |
|
|
131
|
+
|--------|------|-------------|
|
|
132
|
+
| `GET` | `/connect/<provider>` | Initiates the OAuth flow (redirects to provider) |
|
|
133
|
+
| `GET` | `/api/auth/oauth/callback` | OAuth callback (handled automatically) |
|
|
134
|
+
| `GET` | `/api/auth/oauth/providers` | Lists configured provider names |
|
|
135
|
+
|
|
136
|
+
### Example: List providers
|
|
137
|
+
|
|
138
|
+
```http
|
|
139
|
+
GET /api/auth/oauth/providers
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"providers": ["google", "github", "discord"]
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Top 20 Provider Setup Guides
|
|
149
|
+
|
|
150
|
+
Below are setup guides for the 20 most popular OAuth providers. For each one, you need to:
|
|
151
|
+
|
|
152
|
+
1. Create an app on the provider's developer portal
|
|
153
|
+
2. Set the redirect URI to `https://your-domain.com/connect/<provider>/callback`
|
|
154
|
+
3. Add the client ID and secret to your `.env` file
|
|
155
|
+
4. Add the provider to your YAML config
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
### 1. Google
|
|
160
|
+
|
|
161
|
+
**Developer Console:** [console.cloud.google.com](https://console.cloud.google.com/apis/credentials)
|
|
162
|
+
|
|
163
|
+
1. Create a project → **APIs & Services** → **Credentials** → **Create OAuth Client ID**
|
|
164
|
+
2. Set application type to **Web application**
|
|
165
|
+
3. Add authorized redirect URI: `http://localhost:3000/connect/google/callback`
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
OAUTH_GOOGLE_KEY=your-client-id.apps.googleusercontent.com
|
|
169
|
+
OAUTH_GOOGLE_SECRET=your-client-secret
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```yaml
|
|
173
|
+
oauth:
|
|
174
|
+
providers:
|
|
175
|
+
google:
|
|
176
|
+
scope:
|
|
177
|
+
- openid
|
|
178
|
+
- email
|
|
179
|
+
- profile
|
|
180
|
+
custom_params:
|
|
181
|
+
access_type: offline # Get a refresh token
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
### 2. GitHub
|
|
187
|
+
|
|
188
|
+
**Developer Settings:** [github.com/settings/developers](https://github.com/settings/developers)
|
|
189
|
+
|
|
190
|
+
1. Go to **Settings** → **Developer Settings** → **OAuth Apps** → **New OAuth App**
|
|
191
|
+
2. Set the callback URL: `http://localhost:3000/connect/github/callback`
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
OAUTH_GITHUB_KEY=your-github-client-id
|
|
195
|
+
OAUTH_GITHUB_SECRET=your-github-client-secret
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
```yaml
|
|
199
|
+
oauth:
|
|
200
|
+
providers:
|
|
201
|
+
github:
|
|
202
|
+
scope:
|
|
203
|
+
- user:email
|
|
204
|
+
- read:user
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
### 3. Facebook
|
|
210
|
+
|
|
211
|
+
**Developer Portal:** [developers.facebook.com](https://developers.facebook.com/apps/)
|
|
212
|
+
|
|
213
|
+
1. Create a new app → **Facebook Login** → **Settings**
|
|
214
|
+
2. Add valid redirect URI: `http://localhost:3000/connect/facebook/callback`
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
OAUTH_FACEBOOK_KEY=your-facebook-app-id
|
|
218
|
+
OAUTH_FACEBOOK_SECRET=your-facebook-app-secret
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
```yaml
|
|
222
|
+
oauth:
|
|
223
|
+
providers:
|
|
224
|
+
facebook:
|
|
225
|
+
scope:
|
|
226
|
+
- email
|
|
227
|
+
- public_profile
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
### 4. Discord
|
|
233
|
+
|
|
234
|
+
**Developer Portal:** [discord.com/developers](https://discord.com/developers/applications)
|
|
235
|
+
|
|
236
|
+
1. Create a new application → **OAuth2** → **General**
|
|
237
|
+
2. Add redirect: `http://localhost:3000/connect/discord/callback`
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
OAUTH_DISCORD_KEY=your-discord-client-id
|
|
241
|
+
OAUTH_DISCORD_SECRET=your-discord-client-secret
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
```yaml
|
|
245
|
+
oauth:
|
|
246
|
+
providers:
|
|
247
|
+
discord:
|
|
248
|
+
scope:
|
|
249
|
+
- identify
|
|
250
|
+
- email
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
### 5. Apple
|
|
256
|
+
|
|
257
|
+
**Developer Portal:** [developer.apple.com](https://developer.apple.com/account/resources/identifiers/list/serviceId)
|
|
258
|
+
|
|
259
|
+
1. Register a **Services ID** and configure **Sign In with Apple**
|
|
260
|
+
2. Set the redirect URL: `https://your-domain.com/connect/apple/callback`
|
|
261
|
+
|
|
262
|
+
!!! warning
|
|
263
|
+
Apple requires HTTPS even for development.
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
OAUTH_APPLE_KEY=your-apple-services-id
|
|
267
|
+
OAUTH_APPLE_SECRET=your-apple-client-secret
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```yaml
|
|
271
|
+
oauth:
|
|
272
|
+
providers:
|
|
273
|
+
apple:
|
|
274
|
+
scope:
|
|
275
|
+
- name
|
|
276
|
+
- email
|
|
277
|
+
nonce: true
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
### 6. Microsoft
|
|
283
|
+
|
|
284
|
+
**Azure Portal:** [portal.azure.com](https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade)
|
|
285
|
+
|
|
286
|
+
1. Register a new application → **Authentication** → **Add a platform** → **Web**
|
|
287
|
+
2. Set redirect URI: `http://localhost:3000/connect/microsoft/callback`
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
OAUTH_MICROSOFT_KEY=your-application-client-id
|
|
291
|
+
OAUTH_MICROSOFT_SECRET=your-client-secret-value
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
```yaml
|
|
295
|
+
oauth:
|
|
296
|
+
providers:
|
|
297
|
+
microsoft:
|
|
298
|
+
scope:
|
|
299
|
+
- openid
|
|
300
|
+
- email
|
|
301
|
+
- profile
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
### 7. Twitter (X)
|
|
307
|
+
|
|
308
|
+
**Developer Portal:** [developer.twitter.com](https://developer.twitter.com/en/portal/projects-and-apps)
|
|
309
|
+
|
|
310
|
+
1. Create a project and app → **User authentication settings** → **Edit**
|
|
311
|
+
2. Set the callback URL: `http://localhost:3000/connect/twitter/callback`
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
OAUTH_TWITTER_KEY=your-twitter-api-key
|
|
315
|
+
OAUTH_TWITTER_SECRET=your-twitter-api-secret
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
```yaml
|
|
319
|
+
oauth:
|
|
320
|
+
providers:
|
|
321
|
+
twitter:
|
|
322
|
+
scope:
|
|
323
|
+
- users.read
|
|
324
|
+
- tweet.read
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
### 8. LinkedIn
|
|
330
|
+
|
|
331
|
+
**Developer Portal:** [linkedin.com/developers](https://www.linkedin.com/developers/apps)
|
|
332
|
+
|
|
333
|
+
1. Create an app → **Auth** → add redirect URL: `http://localhost:3000/connect/linkedin/callback`
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
OAUTH_LINKEDIN_KEY=your-linkedin-client-id
|
|
337
|
+
OAUTH_LINKEDIN_SECRET=your-linkedin-client-secret
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
```yaml
|
|
341
|
+
oauth:
|
|
342
|
+
providers:
|
|
343
|
+
linkedin:
|
|
344
|
+
scope:
|
|
345
|
+
- openid
|
|
346
|
+
- email
|
|
347
|
+
- profile
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
### 9. Spotify
|
|
353
|
+
|
|
354
|
+
**Developer Dashboard:** [developer.spotify.com/dashboard](https://developer.spotify.com/dashboard)
|
|
355
|
+
|
|
356
|
+
1. Create an app → **Edit Settings** → add redirect URI: `http://localhost:3000/connect/spotify/callback`
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
OAUTH_SPOTIFY_KEY=your-spotify-client-id
|
|
360
|
+
OAUTH_SPOTIFY_SECRET=your-spotify-client-secret
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
```yaml
|
|
364
|
+
oauth:
|
|
365
|
+
providers:
|
|
366
|
+
spotify:
|
|
367
|
+
scope:
|
|
368
|
+
- user-read-email
|
|
369
|
+
- user-read-private
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
### 10. Slack
|
|
375
|
+
|
|
376
|
+
**API Portal:** [api.slack.com/apps](https://api.slack.com/apps)
|
|
377
|
+
|
|
378
|
+
1. Create an app → **OAuth & Permissions** → add redirect URL: `http://localhost:3000/connect/slack/callback`
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
OAUTH_SLACK_KEY=your-slack-client-id
|
|
382
|
+
OAUTH_SLACK_SECRET=your-slack-client-secret
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
```yaml
|
|
386
|
+
oauth:
|
|
387
|
+
providers:
|
|
388
|
+
slack:
|
|
389
|
+
scope:
|
|
390
|
+
- openid
|
|
391
|
+
- email
|
|
392
|
+
- profile
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
### 11. GitLab
|
|
398
|
+
|
|
399
|
+
**Application Settings:** [gitlab.com/-/profile/applications](https://gitlab.com/-/profile/applications)
|
|
400
|
+
|
|
401
|
+
1. Create a new application with redirect URI: `http://localhost:3000/connect/gitlab/callback`
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
OAUTH_GITLAB_KEY=your-gitlab-application-id
|
|
405
|
+
OAUTH_GITLAB_SECRET=your-gitlab-secret
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
```yaml
|
|
409
|
+
oauth:
|
|
410
|
+
providers:
|
|
411
|
+
gitlab:
|
|
412
|
+
scope:
|
|
413
|
+
- read_user
|
|
414
|
+
- email
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
### 12. Bitbucket
|
|
420
|
+
|
|
421
|
+
**App Passwords:** [bitbucket.org/account/settings/app-passwords/](https://bitbucket.org/account/settings/)
|
|
422
|
+
|
|
423
|
+
1. Go to **Settings** → **OAuth consumers** → **Add consumer**
|
|
424
|
+
2. Set callback URL: `http://localhost:3000/connect/bitbucket/callback`
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
OAUTH_BITBUCKET_KEY=your-bitbucket-key
|
|
428
|
+
OAUTH_BITBUCKET_SECRET=your-bitbucket-secret
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
```yaml
|
|
432
|
+
oauth:
|
|
433
|
+
providers:
|
|
434
|
+
bitbucket:
|
|
435
|
+
scope:
|
|
436
|
+
- account
|
|
437
|
+
- email
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
### 13. Twitch
|
|
443
|
+
|
|
444
|
+
**Developer Console:** [dev.twitch.tv/console/apps](https://dev.twitch.tv/console/apps)
|
|
445
|
+
|
|
446
|
+
1. Register a new application with redirect URL: `http://localhost:3000/connect/twitch/callback`
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
OAUTH_TWITCH_KEY=your-twitch-client-id
|
|
450
|
+
OAUTH_TWITCH_SECRET=your-twitch-client-secret
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
```yaml
|
|
454
|
+
oauth:
|
|
455
|
+
providers:
|
|
456
|
+
twitch:
|
|
457
|
+
scope:
|
|
458
|
+
- user:read:email
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
### 14. Dropbox
|
|
464
|
+
|
|
465
|
+
**App Console:** [dropbox.com/developers/apps](https://www.dropbox.com/developers/apps)
|
|
466
|
+
|
|
467
|
+
1. Create app → **Settings** → add redirect URI: `http://localhost:3000/connect/dropbox/callback`
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
OAUTH_DROPBOX_KEY=your-dropbox-app-key
|
|
471
|
+
OAUTH_DROPBOX_SECRET=your-dropbox-app-secret
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
```yaml
|
|
475
|
+
oauth:
|
|
476
|
+
providers:
|
|
477
|
+
dropbox:
|
|
478
|
+
scope:
|
|
479
|
+
- account_info.read
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
### 15. Shopify
|
|
485
|
+
|
|
486
|
+
**Partners Dashboard:** [partners.shopify.com](https://partners.shopify.com/)
|
|
487
|
+
|
|
488
|
+
1. Create an app → **App setup** → add redirect URL: `http://localhost:3000/connect/shopify/callback`
|
|
489
|
+
|
|
490
|
+
```bash
|
|
491
|
+
OAUTH_SHOPIFY_KEY=your-shopify-api-key
|
|
492
|
+
OAUTH_SHOPIFY_SECRET=your-shopify-api-secret
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
```yaml
|
|
496
|
+
oauth:
|
|
497
|
+
providers:
|
|
498
|
+
shopify:
|
|
499
|
+
subdomain: your-store # Your Shopify store subdomain
|
|
500
|
+
scope:
|
|
501
|
+
- read_products
|
|
502
|
+
- read_customers
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
### 16. Notion
|
|
508
|
+
|
|
509
|
+
**Integrations:** [notion.so/my-integrations](https://www.notion.so/my-integrations)
|
|
510
|
+
|
|
511
|
+
1. Create a new integration → **OAuth** → set redirect URI: `http://localhost:3000/connect/notion/callback`
|
|
512
|
+
|
|
513
|
+
```bash
|
|
514
|
+
OAUTH_NOTION_KEY=your-notion-client-id
|
|
515
|
+
OAUTH_NOTION_SECRET=your-notion-client-secret
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
```yaml
|
|
519
|
+
oauth:
|
|
520
|
+
providers:
|
|
521
|
+
notion:
|
|
522
|
+
scope: []
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
### 17. Zoom
|
|
528
|
+
|
|
529
|
+
**Marketplace:** [marketplace.zoom.us](https://marketplace.zoom.us/develop/create)
|
|
530
|
+
|
|
531
|
+
1. Create an OAuth app → add redirect URL: `http://localhost:3000/connect/zoom/callback`
|
|
532
|
+
|
|
533
|
+
```bash
|
|
534
|
+
OAUTH_ZOOM_KEY=your-zoom-client-id
|
|
535
|
+
OAUTH_ZOOM_SECRET=your-zoom-client-secret
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
```yaml
|
|
539
|
+
oauth:
|
|
540
|
+
providers:
|
|
541
|
+
zoom:
|
|
542
|
+
scope:
|
|
543
|
+
- user:read
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
### 18. Stripe
|
|
549
|
+
|
|
550
|
+
**Dashboard:** [dashboard.stripe.com](https://dashboard.stripe.com/settings/connect)
|
|
551
|
+
|
|
552
|
+
1. Go to **Settings** → **Connect** → set redirect URI: `http://localhost:3000/connect/stripe/callback`
|
|
553
|
+
|
|
554
|
+
```bash
|
|
555
|
+
OAUTH_STRIPE_KEY=your-stripe-client-id
|
|
556
|
+
OAUTH_STRIPE_SECRET=your-stripe-api-secret-key
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
```yaml
|
|
560
|
+
oauth:
|
|
561
|
+
providers:
|
|
562
|
+
stripe:
|
|
563
|
+
scope:
|
|
564
|
+
- read_write
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
569
|
+
### 19. Reddit
|
|
570
|
+
|
|
571
|
+
**App Preferences:** [reddit.com/prefs/apps](https://www.reddit.com/prefs/apps)
|
|
572
|
+
|
|
573
|
+
1. Create a new app (select **web app**) → set redirect URI: `http://localhost:3000/connect/reddit/callback`
|
|
574
|
+
|
|
575
|
+
```bash
|
|
576
|
+
OAUTH_REDDIT_KEY=your-reddit-client-id
|
|
577
|
+
OAUTH_REDDIT_SECRET=your-reddit-client-secret
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
```yaml
|
|
581
|
+
oauth:
|
|
582
|
+
providers:
|
|
583
|
+
reddit:
|
|
584
|
+
scope:
|
|
585
|
+
- identity
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
---
|
|
589
|
+
|
|
590
|
+
### 20. Auth0
|
|
591
|
+
|
|
592
|
+
**Dashboard:** [manage.auth0.com](https://manage.auth0.com/)
|
|
593
|
+
|
|
594
|
+
1. Create a new application → **Settings** → set callback URL: `http://localhost:3000/connect/auth0/callback`
|
|
595
|
+
|
|
596
|
+
```bash
|
|
597
|
+
OAUTH_AUTH0_KEY=your-auth0-client-id
|
|
598
|
+
OAUTH_AUTH0_SECRET=your-auth0-client-secret
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
```yaml
|
|
602
|
+
oauth:
|
|
603
|
+
providers:
|
|
604
|
+
auth0:
|
|
605
|
+
subdomain: your-tenant # Your Auth0 tenant subdomain
|
|
606
|
+
scope:
|
|
607
|
+
- openid
|
|
608
|
+
- email
|
|
609
|
+
- profile
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
---
|
|
613
|
+
|
|
614
|
+
## All Supported Providers (200+)
|
|
615
|
+
|
|
616
|
+
ChadStart uses the [grant](https://www.npmjs.com/package/grant) library under the hood, which supports **200+ OAuth providers**. Any provider listed at [github.com/simov/grant](https://github.com/simov/grant) can be added to your YAML config by its name.
|
|
617
|
+
|
|
618
|
+
Below is a selection of additional providers you can configure. The setup pattern is the same for all:
|
|
619
|
+
|
|
620
|
+
1. Set `OAUTH_<PROVIDER>_KEY` and `OAUTH_<PROVIDER>_SECRET` in your `.env`
|
|
621
|
+
2. Add the provider to your YAML config under `oauth.providers`
|
|
622
|
+
3. Add `<a href="/connect/<provider>">Login with Provider</a>` to your frontend
|
|
623
|
+
|
|
624
|
+
### Categories of Additional Providers
|
|
625
|
+
|
|
626
|
+
#### Developer & DevOps Platforms
|
|
627
|
+
`atlassian`, `azure`, `digitalocean`, `heroku`, `figma`, `vercel`
|
|
628
|
+
|
|
629
|
+
#### Social & Communication
|
|
630
|
+
`instagram`, `snapchat`, `tiktok`, `telegram`, `line`, `kakao`, `vk`, `weibo`, `wechat`, `yandex`
|
|
631
|
+
|
|
632
|
+
#### Enterprise & Productivity
|
|
633
|
+
`salesforce`, `hubspot`, `asana`, `basecamp`, `box`, `docusign`, `freshbooks`, `intuit`, `quickbooks`, `zendesk`
|
|
634
|
+
|
|
635
|
+
#### Gaming
|
|
636
|
+
`battlenet`, `epicgames`, `steam`, `riotgames`
|
|
637
|
+
|
|
638
|
+
#### Music & Media
|
|
639
|
+
`deezer`, `soundcloud`, `vimeo`, `dailymotion`
|
|
640
|
+
|
|
641
|
+
#### Finance & Payments
|
|
642
|
+
`paypal`, `square`, `coinbase`
|
|
643
|
+
|
|
644
|
+
#### Identity Providers
|
|
645
|
+
`okta`, `onelogin`, `keycloak`
|
|
646
|
+
|
|
647
|
+
#### Email & Marketing
|
|
648
|
+
`mailchimp`, `constantcontact`, `mailgun`
|
|
649
|
+
|
|
650
|
+
### Example: Adding any provider
|
|
651
|
+
|
|
652
|
+
The configuration pattern is identical for all providers:
|
|
653
|
+
|
|
654
|
+
```yaml
|
|
655
|
+
oauth:
|
|
656
|
+
providers:
|
|
657
|
+
<provider-name>:
|
|
658
|
+
scope:
|
|
659
|
+
- required-scope-1
|
|
660
|
+
- required-scope-2
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
OAUTH_<PROVIDER_NAME>_KEY=your-client-id
|
|
665
|
+
OAUTH_<PROVIDER_NAME>_SECRET=your-client-secret
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
```html
|
|
669
|
+
<a href="/connect/<provider-name>">Login with Provider</a>
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
!!! tip
|
|
673
|
+
Check the provider's documentation for the list of available scopes. Grant handles the OAuth protocol differences (OAuth 1.0, 1.0a, 2.0, and OpenID Connect) automatically.
|
|
674
|
+
|
|
675
|
+
## How It Works
|
|
676
|
+
|
|
677
|
+
### OAuth Flow
|
|
678
|
+
|
|
679
|
+
```
|
|
680
|
+
┌──────────┐ 1. Click login ┌────────────┐
|
|
681
|
+
│ Browser │ ──────────────────────▶ │ ChadStart │
|
|
682
|
+
│ │ │ /connect/ │
|
|
683
|
+
│ │ 2. Redirect to │ google │
|
|
684
|
+
│ │ ◀────────────────────── │ │
|
|
685
|
+
│ │ └────────────┘
|
|
686
|
+
│ │ 3. Login at Google
|
|
687
|
+
│ │ ──────────────────────▶ ┌────────────┐
|
|
688
|
+
│ │ │ Google │
|
|
689
|
+
│ │ 4. Redirect back │ OAuth │
|
|
690
|
+
│ │ ◀────────────────────── │ Server │
|
|
691
|
+
│ │ └────────────┘
|
|
692
|
+
│ │ 5. Exchange code
|
|
693
|
+
│ │ ──────────────────────▶ ┌────────────┐
|
|
694
|
+
│ │ │ ChadStart │
|
|
695
|
+
│ │ 6. JWT token │ /callback │
|
|
696
|
+
│ │ ◀────────────────────── │ │
|
|
697
|
+
└──────────┘ └────────────┘
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
1. User clicks a **"Login with Google"** button that links to `/connect/google`.
|
|
701
|
+
2. ChadStart (via Grant) redirects the user to Google's authorization page.
|
|
702
|
+
3. User authenticates with Google and grants permissions.
|
|
703
|
+
4. Google redirects back to ChadStart's callback URL with an authorization code.
|
|
704
|
+
5. Grant exchanges the code for tokens and fetches the user profile.
|
|
705
|
+
6. ChadStart finds or creates the user and returns a **JWT token**.
|
|
706
|
+
|
|
707
|
+
### User Creation
|
|
708
|
+
|
|
709
|
+
When a user logs in via OAuth for the first time:
|
|
710
|
+
|
|
711
|
+
- ChadStart looks for an existing user **by email address**.
|
|
712
|
+
- If found, the existing user is authenticated (no duplicate accounts).
|
|
713
|
+
- If not found, a **new user is created** with:
|
|
714
|
+
- `email` from the OAuth profile
|
|
715
|
+
- A random secure password (user authenticates via OAuth, not password)
|
|
716
|
+
- `name` from the profile (if the entity has a `name` property)
|
|
717
|
+
|
|
718
|
+
### Token Usage
|
|
719
|
+
|
|
720
|
+
The JWT token returned from OAuth login works exactly the same as tokens from email/password login:
|
|
721
|
+
|
|
722
|
+
```http
|
|
723
|
+
GET /api/dynamic/posts
|
|
724
|
+
Authorization: Bearer <token-from-oauth>
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
## Frontend Integration
|
|
728
|
+
|
|
729
|
+
### HTML Buttons
|
|
730
|
+
|
|
731
|
+
```html
|
|
732
|
+
<!-- Simple login buttons -->
|
|
733
|
+
<a href="/connect/google" class="btn">Login with Google</a>
|
|
734
|
+
<a href="/connect/github" class="btn">Login with GitHub</a>
|
|
735
|
+
<a href="/connect/discord" class="btn">Login with Discord</a>
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
### React Example
|
|
739
|
+
|
|
740
|
+
```jsx
|
|
741
|
+
function OAuthButtons() {
|
|
742
|
+
return (
|
|
743
|
+
<div>
|
|
744
|
+
<a href="/connect/google">Login with Google</a>
|
|
745
|
+
<a href="/connect/github">Login with GitHub</a>
|
|
746
|
+
</div>
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// Handle the redirect (on your successRedirect page)
|
|
751
|
+
function Dashboard() {
|
|
752
|
+
useEffect(() => {
|
|
753
|
+
const params = new URLSearchParams(window.location.search);
|
|
754
|
+
const token = params.get('token');
|
|
755
|
+
if (token) {
|
|
756
|
+
localStorage.setItem('token', token);
|
|
757
|
+
// Clean up URL
|
|
758
|
+
window.history.replaceState({}, '', window.location.pathname);
|
|
759
|
+
}
|
|
760
|
+
}, []);
|
|
761
|
+
|
|
762
|
+
return <div>Welcome!</div>;
|
|
763
|
+
}
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
### Vue Example
|
|
767
|
+
|
|
768
|
+
```vue
|
|
769
|
+
<template>
|
|
770
|
+
<div>
|
|
771
|
+
<a href="/connect/google">Login with Google</a>
|
|
772
|
+
<a href="/connect/github">Login with GitHub</a>
|
|
773
|
+
</div>
|
|
774
|
+
</template>
|
|
775
|
+
|
|
776
|
+
<script setup>
|
|
777
|
+
import { onMounted } from 'vue'
|
|
778
|
+
|
|
779
|
+
onMounted(() => {
|
|
780
|
+
const params = new URLSearchParams(window.location.search)
|
|
781
|
+
const token = params.get('token')
|
|
782
|
+
if (token) {
|
|
783
|
+
localStorage.setItem('token', token)
|
|
784
|
+
window.history.replaceState({}, '', window.location.pathname)
|
|
785
|
+
}
|
|
786
|
+
})
|
|
787
|
+
</script>
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
### Dynamic Provider Buttons
|
|
791
|
+
|
|
792
|
+
```javascript
|
|
793
|
+
// Fetch available providers and render buttons dynamically
|
|
794
|
+
async function renderOAuthButtons(containerId) {
|
|
795
|
+
const res = await fetch('/api/auth/oauth/providers');
|
|
796
|
+
const { providers } = await res.json();
|
|
797
|
+
|
|
798
|
+
const container = document.getElementById(containerId);
|
|
799
|
+
providers.forEach(provider => {
|
|
800
|
+
const link = document.createElement('a');
|
|
801
|
+
link.href = `/connect/${provider}`;
|
|
802
|
+
link.textContent = `Login with ${provider.charAt(0).toUpperCase() + provider.slice(1)}`;
|
|
803
|
+
link.className = 'oauth-btn';
|
|
804
|
+
container.appendChild(link);
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
## Multiple Providers
|
|
810
|
+
|
|
811
|
+
You can configure as many providers as you need:
|
|
812
|
+
|
|
813
|
+
```yaml
|
|
814
|
+
oauth:
|
|
815
|
+
entity: User
|
|
816
|
+
successRedirect: /dashboard
|
|
817
|
+
providers:
|
|
818
|
+
google:
|
|
819
|
+
scope: [openid, email, profile]
|
|
820
|
+
github:
|
|
821
|
+
scope: [user:email]
|
|
822
|
+
discord:
|
|
823
|
+
scope: [identify, email]
|
|
824
|
+
microsoft:
|
|
825
|
+
scope: [openid, email, profile]
|
|
826
|
+
spotify:
|
|
827
|
+
scope: [user-read-email]
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
All providers share the same callback endpoint and user entity — a user who has signed in with Google and later tries GitHub (with the same email) will be matched to their existing account.
|
|
831
|
+
|
|
832
|
+
## Security Considerations
|
|
833
|
+
|
|
834
|
+
!!! warning "Important"
|
|
835
|
+
- **Never** put OAuth client secrets in your YAML file — always use environment variables.
|
|
836
|
+
- **Always** use HTTPS in production. OAuth tokens transmitted over HTTP can be intercepted.
|
|
837
|
+
- Set `BASE_URL` in your `.env` to your production URL so redirect URIs are correct.
|
|
838
|
+
- Some providers (like Apple) require HTTPS even for development.
|
|
839
|
+
|
|
840
|
+
### PKCE Support
|
|
841
|
+
|
|
842
|
+
For enhanced security, enable [PKCE](https://oauth.net/2/pkce/) on providers that support it:
|
|
843
|
+
|
|
844
|
+
```yaml
|
|
845
|
+
oauth:
|
|
846
|
+
providers:
|
|
847
|
+
google:
|
|
848
|
+
pkce: true
|
|
849
|
+
scope: [openid, email, profile]
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
## Troubleshooting
|
|
853
|
+
|
|
854
|
+
### Common Issues
|
|
855
|
+
|
|
856
|
+
| Issue | Solution |
|
|
857
|
+
|-------|----------|
|
|
858
|
+
| "redirect_uri_mismatch" | Make sure the redirect URI in your provider's console exactly matches `http(s)://your-domain/connect/<provider>/callback` |
|
|
859
|
+
| "invalid_client" | Double-check your `OAUTH_<PROVIDER>_KEY` and `OAUTH_<PROVIDER>_SECRET` environment variables |
|
|
860
|
+
| User not created | Ensure you have at least one entity with `authenticable: true` |
|
|
861
|
+
| Token not received | Check that `successRedirect` points to a valid page in your app |
|
|
862
|
+
| Provider not found | The provider name must be lowercase and match grant's naming (e.g., `github`, not `GitHub`) |
|
|
863
|
+
|
|
864
|
+
### Debug Tips
|
|
865
|
+
|
|
866
|
+
1. Check available providers: `GET /api/auth/oauth/providers`
|
|
867
|
+
2. Verify environment variables are set correctly
|
|
868
|
+
3. Check server logs for OAuth callback errors
|
|
869
|
+
4. Make sure `BASE_URL` is set in production
|