@happyvertical/smrt-users 0.54.3 → 0.55.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/README.md CHANGED
@@ -378,6 +378,43 @@ export const GET = createOidcCallbackHandler({
378
378
  });
379
379
  ```
380
380
 
381
+ #### Register the client: redirect URL and landing URL
382
+
383
+ Register two URLs with the IdP, not one. `getOidcClientRegistration()` derives
384
+ both from the same `callbackPath`/`loginPath` options the route handlers use
385
+ (defaults `/auth/<provider>/callback` and `/auth/<provider>/login`):
386
+
387
+ ```typescript
388
+ import { getOidcClientRegistration } from '@happyvertical/smrt-users/sveltekit';
389
+
390
+ const { redirectUri, landingUrl } = getOidcClientRegistration(
391
+ 'https://app.example.com',
392
+ { provider: 'kanidm' },
393
+ );
394
+ // redirectUri: https://app.example.com/auth/kanidm/callback
395
+ // landingUrl: https://app.example.com/auth/kanidm/login
396
+ ```
397
+
398
+ For Kanidm:
399
+
400
+ ```sh
401
+ kanidm system oauth2 add-redirect-url <client> https://app.example.com/auth/kanidm/callback
402
+ kanidm system oauth2 set-landing-url <client> https://app.example.com/auth/kanidm/login
403
+ ```
404
+
405
+ The landing URL must be the login **start** route, not the app's home page.
406
+ Kanidm (verified through 1.11) holds the app's pending authorization in a
407
+ short-lived cookie. It discards that cookie whenever the user passes through its
408
+ own `/ui/login` page, for example by pressing "Return to Login" after a
409
+ mistyped password, and also after 15 minutes. After signing in, the user then
410
+ lands in Kanidm's apps panel instead of returning to the app. The app never
411
+ sees this happen, so the app tile in that panel, which links to the landing URL,
412
+ is the only way back. When the tile points at the login start route, one click
413
+ signs the user in, because their Kanidm session already exists. When it points at
414
+ the home page, the user arrives signed out and has to start sign-in again. Other
415
+ IdPs that offer an "initiate login URI" or app-launcher URL should use the same
416
+ `landingUrl`.
417
+
381
418
  The callback verifies `state`, PKCE, issuer, audience, nonce, and the provider
382
419
  JWKS-signed ID token, falling back to the OIDC UserInfo endpoint when the ID
383
420
  token omits required profile claims like `email`. Temporary transaction cookies
@@ -1188,6 +1225,7 @@ TenantService supports three modes: `flexible` (no auto-create), `personal` (aut
1188
1225
  | `switchSessionTenant` | Change tenant context for current session |
1189
1226
  | `beginOidcLogin`, `completeOidcLogin` | Low-level SvelteKit helpers for custom OIDC login routes |
1190
1227
  | `createOidcLoginHandler`, `createOidcCallbackHandler` | Ready-to-use SvelteKit route handlers for OIDC login and callback |
1228
+ | `getOidcClientRegistration` | Redirect URL and landing (login start) URL to register with the IdP for an OIDC client |
1191
1229
  | `createMobileAuthHandlers` | Mountable `/api/mobile` PKCE, bearer session, bootstrap, logout, and route-guard handlers |
1192
1230
  | `createDeviceCredentialHandlers` | Mountable PIN sign-in, sign-out, and PIN management handlers for enrolled devices |
1193
1231
  | `createPasswordCredentialHandlers` | Mountable password sign-in (sets the session cookie) and password set/change/reset/clear handlers |
@@ -12,6 +12,12 @@ OIDC handlers, or identity migrations. The canonical scenario matrix is
12
12
  `iss` against discovered metadata with exact string comparison before trusting
13
13
  a code or error. If metadata advertises issuer-response support, `iss` is
14
14
  required.
15
+ - **The login start route is the IdP landing URL (#3569).** Kanidm drops a
16
+ pending authorization after any detour through its `/ui/login` and strands the
17
+ user in its apps panel; the client landing URL is the only way back.
18
+ `getOidcClientRegistration()` derives it from `loginPath` (default
19
+ `/auth/<provider>/login`) alongside the callback URL; keep the login handler
20
+ safe to enter with no query string.
15
21
  - **Verified-email Profile reuse is fail-closed.** The typed canonical scenarios
16
22
  live in
17
23
  `packages/profiles/src/testing/oidcProvisioningDecisionMatrix.ts`; both