rastack 0.0.62 → 0.0.63

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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.0.63](https://github.com/theserverkid/reactapistack/compare/v0.0.62...v0.0.63) (2026-07-20)
6
+
7
+
8
+ ### Features
9
+
10
+ * **deploy:** dev + prod environments with per-env Cognito, proxy, and .env ([996e726](https://github.com/theserverkid/reactapistack/commit/996e726e7e0d55f01e3111579594c2b66e88a79c))
11
+
5
12
  ### [0.0.62](https://github.com/theserverkid/reactapistack/compare/v0.0.61...v0.0.62) (2026-07-19)
6
13
 
7
14
 
package/auth/provider.ts CHANGED
@@ -74,10 +74,7 @@ export interface CognitoAuthProviderConfig extends Partial<CognitoAuthConfig> {
74
74
  }
75
75
 
76
76
  export type CognitoAuthStatus =
77
- | "loading"
78
- | "authenticated"
79
- | "unauthenticated"
80
- | "error";
77
+ "loading" | "authenticated" | "unauthenticated" | "error";
81
78
 
82
79
  /** What `useCognitoAuth()` returns. */
83
80
  export interface CognitoAuthContextValue {
@@ -178,7 +175,8 @@ export function CognitoAuthProvider({
178
175
  const keyBase = config.storageKey ?? "rastack.auth";
179
176
  const sessionKey = `${keyBase}.session`;
180
177
  const pkceKey = `${keyBase}.pkce`;
181
- const doFetch = config.fetchImpl ?? (globalThis.fetch?.bind(globalThis) as typeof fetch);
178
+ const doFetch =
179
+ config.fetchImpl ?? (globalThis.fetch?.bind(globalThis) as typeof fetch);
182
180
 
183
181
  const [session, setSession] = useState<CognitoSession | null>(null);
184
182
  const [status, setStatus] = useState<CognitoAuthStatus>("loading");
@@ -242,7 +240,8 @@ export function CognitoAuthProvider({
242
240
  const redirect = parseRedirect(dom.window.location.search);
243
241
  if (redirect.error) {
244
242
  clearUrl();
245
- if (!cancelled) fail(new Error(redirect.errorDescription ?? redirect.error));
243
+ if (!cancelled)
244
+ fail(new Error(redirect.errorDescription ?? redirect.error));
246
245
  return;
247
246
  }
248
247
  if (redirect.code) {
@@ -288,14 +287,17 @@ export function CognitoAuthProvider({
288
287
  ): Promise<CognitoSession> {
289
288
  const hosted = requireHostedConfig(config);
290
289
  const pending = storage.getItem(pkceKey);
291
- if (!pending) throw new Error("No pending PKCE verifier — restart sign-in.");
290
+ if (!pending)
291
+ throw new Error("No pending PKCE verifier — restart sign-in.");
292
292
  const { verifier, state: expectedState } = JSON.parse(pending) as {
293
293
  verifier: string;
294
294
  state: string;
295
295
  };
296
296
  storage.removeItem(pkceKey);
297
297
  if (expectedState && state && expectedState !== state) {
298
- throw new Error("OAuth state mismatch — possible CSRF, sign-in rejected.");
298
+ throw new Error(
299
+ "OAuth state mismatch — possible CSRF, sign-in rejected.",
300
+ );
299
301
  }
300
302
  const response = await doFetch(tokenEndpoint(hosted), {
301
303
  method: "POST",
@@ -484,3 +486,64 @@ export function useRastackAuthFromCognito(): RastackAuth {
484
486
  [auth.isAuthenticated, auth.claims],
485
487
  );
486
488
  }
489
+
490
+ // -- Dev-time Cognito runtime config (real dev pool, opt-in) ------------------
491
+ // `rastack dev` serves the dev environment's Cognito coordinates at
492
+ // `/__rastack/cognito.json` so a locally-running app can sign in against the
493
+ // *real* dev user pool (to obtain real tokens — e.g. for the deployed
494
+ // external-API proxy) instead of the unsigned `mode:"local"` shim. These
495
+ // helpers turn that JSON into a `<CognitoAuthProvider config>`; a developer opts
496
+ // in with `cognitoConfigFromGlobal() ?? { mode: "local" }`.
497
+
498
+ /** The shape `rastack dev` serves at `/__rastack/cognito.json`. */
499
+ export interface RastackCognitoRuntime {
500
+ userPoolId?: string;
501
+ clientId: string;
502
+ /** Hosted UI base URL (`https://…amazoncognito.com`). */
503
+ hostedUiUrl: string;
504
+ region: string;
505
+ }
506
+
507
+ /**
508
+ * Map a served runtime config into a `CognitoAuthProviderConfig` for the real
509
+ * Hosted UI flow. `redirectUri` defaults to the current page origin (where
510
+ * `rastack dev` serves the app), so local sign-in round-trips back correctly.
511
+ */
512
+ export function cognitoRuntimeToConfig(
513
+ runtime: RastackCognitoRuntime,
514
+ opts: { redirectUri?: string } & Partial<CognitoAuthProviderConfig> = {},
515
+ ): CognitoAuthProviderConfig {
516
+ const origin = dom.window?.location?.origin as string | undefined;
517
+ const { redirectUri, ...rest } = opts;
518
+ return {
519
+ mode: "hosted-ui",
520
+ domain: runtime.hostedUiUrl,
521
+ clientId: runtime.clientId,
522
+ region: runtime.region,
523
+ userPoolId: runtime.userPoolId,
524
+ redirectUri: redirectUri ?? origin ?? "",
525
+ ...rest,
526
+ };
527
+ }
528
+
529
+ /**
530
+ * Read the runtime Cognito config `rastack dev` injects as
531
+ * `globalThis.__RASTACK_COGNITO__`, mapped to a provider config — or undefined
532
+ * when none is present (so the caller falls back to `{ mode: "local" }`). Set
533
+ * the global from the served JSON, e.g.:
534
+ *
535
+ * ```html
536
+ * <script>
537
+ * fetch("/__rastack/cognito.json").then(r => r.ok && r.json())
538
+ * .then(c => { if (c) window.__RASTACK_COGNITO__ = c; })
539
+ * </script>
540
+ * ```
541
+ */
542
+ export function cognitoConfigFromGlobal(
543
+ opts: { redirectUri?: string } & Partial<CognitoAuthProviderConfig> = {},
544
+ ): CognitoAuthProviderConfig | undefined {
545
+ const runtime = (dom as { __RASTACK_COGNITO__?: RastackCognitoRuntime })
546
+ .__RASTACK_COGNITO__;
547
+ if (!runtime?.clientId || !runtime?.hostedUiUrl) return undefined;
548
+ return cognitoRuntimeToConfig(runtime, opts);
549
+ }