@rpcbase/auth 0.89.0 → 0.91.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/README.md CHANGED
@@ -2,15 +2,6 @@
2
2
 
3
3
  UI helpers + API routes for authentication.
4
4
 
5
- ## OAuth (OIDC Authorization Code + PKCE)
6
-
7
- OAuth support lives behind two framework routes:
8
-
9
- - `GET /api/rb/auth/oauth/:provider/start` (initiates the flow)
10
- - `GET /api/rb/auth/oauth/:provider/callback` (handles the return from the provider)
11
-
12
- `provider` is the provider id you configure (for example `mock`, `google`, `github`).
13
-
14
5
  ### 1) Register auth routes in your API
15
6
 
16
7
  Example (like `sample-app`):
@@ -39,13 +30,15 @@ Call `configureOAuthProviders()` before initializing your API routes:
39
30
 
40
31
  ```ts
41
32
  import { initApi } from "@rpcbase/api"
42
- import { configureOAuthProviders, routes as authRoutes } from "@rpcbase/auth/routes"
33
+ import { configureOAuthProviders } from "@rpcbase/auth/oauth"
34
+ import { routes as authRoutes } from "@rpcbase/auth/routes"
43
35
 
44
36
  configureOAuthProviders({
45
37
  mock: {
46
38
  issuer: "http://localhost:9400",
47
39
  clientId: "rpcbase-sample-app",
48
40
  scope: "openid email profile",
41
+ callbackPath: "/api/auth/oauth/mock/callback",
49
42
  },
50
43
  })
51
44
 
@@ -61,10 +54,55 @@ export const runApi = async ({ app }) => {
61
54
 
62
55
  The app is responsible for sourcing secrets (env, vault, etc.) and passing them to `configureOAuthProviders()`.
63
56
 
57
+ Each provider must define a `scope` and a `callbackPath` so the generated `redirect_uri` matches your routing:
58
+
59
+ ```ts
60
+ configureOAuthProviders({
61
+ google: {
62
+ issuer: "https://accounts.google.com",
63
+ clientId: process.env.GOOGLE_CLIENT_ID!,
64
+ scope: "openid email profile",
65
+ callbackPath: "/api/auth/oauth/google/callback",
66
+ },
67
+ })
68
+ ```
69
+
64
70
  ### 3) Start the OAuth flow from the client
65
71
 
66
72
  ```ts
67
- window.location.assign("/api/rb/auth/oauth/mock/start")
73
+ window.location.assign("/api/auth/oauth/mock/start")
74
+ ```
75
+
76
+ You can optionally pass a return path:
77
+
78
+ ```ts
79
+ window.location.assign("/api/auth/oauth/mock/start?returnTo=/app")
80
+ ```
81
+
82
+ ### Optional: declare OAuth routes yourself
83
+
84
+ If you don’t want to mount the full `authRoutes`, you can register the OAuth handlers manually:
85
+
86
+ ```ts
87
+ import { createOAuthCallbackHandler, createOAuthStartHandler } from "@rpcbase/auth/oauth"
88
+
89
+ export default (api) => {
90
+ api.get("/api/auth/oauth/:provider/start", createOAuthStartHandler({
91
+ getAuthorizationParams: (providerId) =>
92
+ providerId === "apple"
93
+ ? { response_mode: "form_post" }
94
+ : undefined,
95
+ }))
96
+
97
+ const callback = createOAuthCallbackHandler({
98
+ createUserOnFirstSignIn: false,
99
+ missingUserRedirectPath: "/auth/sign-up",
100
+ successRedirectPath: "/app",
101
+ })
102
+
103
+ api.get("/api/auth/oauth/:provider/callback", callback)
104
+ api.post("/api/auth/oauth/:provider/callback", callback)
105
+ }
68
106
  ```
69
107
 
70
108
  ### 4) What happens on callback
@@ -76,6 +114,16 @@ On a successful callback:
76
114
  - the matching `RBUser` is created on first-seen identity (and the OAuth credentials are saved under `RBUser.oauthProviders[provider]`)
77
115
  - the session is signed in, and the user is redirected to `/onboarding`
78
116
 
117
+ If the callback handler is configured with `createUserOnFirstSignIn: false` and no matching user is found, it redirects to `missingUserRedirectPath` (when provided).
118
+
119
+ ### Apple (helper)
120
+
121
+ Apple requires a JWT `clientSecret`. You can generate it server-side:
122
+
123
+ ```ts
124
+ import { createAppleClientSecret } from "@rpcbase/auth/oauth"
125
+ ```
126
+
79
127
  ### Mock provider (dev/tests)
80
128
 
81
129
  This repo uses `oauth2-mock-server` in `sample-app/server.js` to spin up a local OIDC provider for development and Playwright tests.
@@ -83,5 +131,4 @@ This repo uses `oauth2-mock-server` in `sample-app/server.js` to spin up a local
83
131
  Notes:
84
132
 
85
133
  - `oauth2-mock-server` simulates auth and immediately redirects back on `/authorize` (it does not provide a UI to pick an account).
86
- - Disable it with `RB_DISABLE_OAUTH_MOCK=1`
87
134
  - Override the port with `RB_OAUTH_MOCK_SERVER_PORT` (default `9400`)
@@ -2,7 +2,8 @@ export type OAuthProviderConfig = {
2
2
  issuer: string;
3
3
  clientId: string;
4
4
  clientSecret?: string;
5
- scope?: string;
5
+ scope: string;
6
+ callbackPath: string;
6
7
  };
7
8
  export declare const configureOAuthProviders: (providers: Record<string, OAuthProviderConfig>) => void;
8
9
  export declare const setOAuthProviders: (providers: Record<string, OAuthProviderConfig>) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/oauth/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAoDD,eAAO,MAAM,uBAAuB,GAAI,WAAW,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,SAIrF,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,SAG/E,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,YAAY,MAAM,KAAG,mBAAmB,GAAG,IAGjF,CAAA"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/oauth/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA;AAiED,eAAO,MAAM,uBAAuB,GAAI,WAAW,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,SAIrF,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,SAG/E,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,YAAY,MAAM,KAAG,mBAAmB,GAAG,IAGjF,CAAA"}
@@ -0,0 +1,5 @@
1
+ export { configureOAuthProviders, setOAuthProviders } from './config';
2
+ export type { OAuthProviderConfig } from './config';
3
+ export { createAppleClientSecret, createOAuthCallbackHandler, createOAuthStartHandler, getOAuthStartRedirectUrl, processOAuthCallback, } from './lib';
4
+ export type { OAuthCallbackResult, OAuthStartResult } from './lib';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/oauth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACrE,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAEnD,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,OAAO,CAAA;AACd,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAA"}