@poly-x/core 0.1.0-alpha.1 → 0.1.0-alpha.3

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/dist/index.cjs CHANGED
@@ -747,6 +747,27 @@ function parseAuthorizeOutcome(status, body) {
747
747
  if (statusField === "login_required" || b.code === "LOGIN_REQUIRED") return { type: "login_required" };
748
748
  return { type: "login_required" };
749
749
  }
750
+ function parsePasswordOutcome(status, body) {
751
+ const b = asRecord$1(body);
752
+ const statusField = typeof b.status === "string" ? b.status : void 0;
753
+ if (statusField === "authorized" && typeof b.code === "string") return {
754
+ type: "authorized",
755
+ code: b.code,
756
+ state: typeof b.state === "string" ? b.state : "",
757
+ redirectUri: typeof b.redirectUri === "string" ? b.redirectUri : void 0
758
+ };
759
+ if (statusField === "select_tenant") return {
760
+ type: "select_tenant",
761
+ state: typeof b.state === "string" ? b.state : "",
762
+ tenants: parseTenants(b.tenants)
763
+ };
764
+ if (status === 403 && b.userPasswordSet === true && typeof b.userId === "string") return {
765
+ type: "password_change_required",
766
+ userId: b.userId
767
+ };
768
+ if (status === 403) return { type: "no_access" };
769
+ return { type: "invalid_credentials" };
770
+ }
750
771
  //#endregion
751
772
  //#region src/auth/normalize.ts
752
773
  const FALLBACK_TTL_MS = 5 * 6e4;
@@ -859,6 +880,34 @@ var AuthClient = class {
859
880
  if (response.status >= 500) throw this.toError(response);
860
881
  return parseAuthorizeOutcome(response.status, response.body);
861
882
  }
883
+ /**
884
+ * The embedded `<SignIn/>` credential flow (D2b): POST `/idp/authorize` with
885
+ * email/password + PKCE. On `authorized` the caller exchanges the returned
886
+ * `code` (server-side, via the BFF) for a session — no redirect to a hosted
887
+ * login page. Creds live only for the duration of this request; the SDK never
888
+ * stores them. 5xx surfaces as a typed error; every other status is a typed
889
+ * outcome the UI branches on.
890
+ */
891
+ async authorizeWithPassword(params) {
892
+ const response = await this.transport.request({
893
+ method: "POST",
894
+ url: this.config.baseUrl + ENDPOINTS.authorize,
895
+ body: {
896
+ response_type: "code",
897
+ client_id: this.config.key.raw,
898
+ redirect_uri: params.redirectUri,
899
+ state: params.state,
900
+ code_challenge: params.challenge,
901
+ code_challenge_method: "S256",
902
+ email: params.email,
903
+ password: params.password,
904
+ ...params.organizationCode ? { organizationCode: params.organizationCode } : {},
905
+ ...params.tenantId ? { tenantId: params.tenantId } : {}
906
+ }
907
+ });
908
+ if (response.status >= 500) throw this.toError(response);
909
+ return parsePasswordOutcome(response.status, response.body);
910
+ }
862
911
  async exchangeCode(params) {
863
912
  const response = await this.transport.request({
864
913
  method: "POST",
@@ -955,6 +1004,7 @@ exports.mapPlatformError = mapPlatformError;
955
1004
  exports.normalizeExchange = normalizeExchange;
956
1005
  exports.normalizeRefresh = normalizeRefresh;
957
1006
  exports.parseAuthorizeOutcome = parseAuthorizeOutcome;
1007
+ exports.parsePasswordOutcome = parsePasswordOutcome;
958
1008
  exports.parsePolyXKey = parsePolyXKey;
959
1009
  exports.randomState = randomState;
960
1010
  exports.redactSensitive = redactSensitive;
package/dist/index.d.cts CHANGED
@@ -421,6 +421,30 @@ type AuthorizeOutcome = {
421
421
  type: "login_required";
422
422
  };
423
423
  declare function parseAuthorizeOutcome(status: number, body: unknown): AuthorizeOutcome;
424
+ /**
425
+ * Outcome of a PASSWORD authorize (`POST /idp/authorize` with credentials) — the
426
+ * embedded `<SignIn/>` flow. Distinguishes invalid-credentials and the
427
+ * must-set-password step from the membership outcomes (the GET warm-hop parser
428
+ * collapses those into login_required).
429
+ */
430
+ type PasswordAuthOutcome = {
431
+ type: "authorized";
432
+ code: string;
433
+ state: string;
434
+ redirectUri?: string;
435
+ } | {
436
+ type: "select_tenant";
437
+ state: string;
438
+ tenants: TenantOption[];
439
+ } | {
440
+ type: "invalid_credentials";
441
+ } | {
442
+ type: "password_change_required";
443
+ userId: string;
444
+ } | {
445
+ type: "no_access";
446
+ };
447
+ declare function parsePasswordOutcome(status: number, body: unknown): PasswordAuthOutcome;
424
448
  //#endregion
425
449
  //#region src/auth/normalize.d.ts
426
450
  declare function decodeJwtExp(token: string): number | null;
@@ -472,6 +496,16 @@ interface ExchangeCodeParams {
472
496
  codeVerifier: string;
473
497
  redirectUri: string;
474
498
  }
499
+ interface AuthorizeWithPasswordParams {
500
+ email: string;
501
+ password: string;
502
+ redirectUri: string;
503
+ state: string;
504
+ challenge: string;
505
+ organizationCode?: string;
506
+ /** Set on the re-attempt after the user picks a workspace (select_tenant). */
507
+ tenantId?: string;
508
+ }
475
509
  declare class AuthClient {
476
510
  private readonly config;
477
511
  private readonly transport;
@@ -489,6 +523,15 @@ declare class AuthClient {
489
523
  buildSignInUrl(params: BuildAuthorizeUrlParams): string;
490
524
  /** Probe the warm hop (GET /idp/authorize) and return the typed outcome. */
491
525
  completeAuthorize(params: BuildAuthorizeUrlParams): Promise<AuthorizeOutcome>;
526
+ /**
527
+ * The embedded `<SignIn/>` credential flow (D2b): POST `/idp/authorize` with
528
+ * email/password + PKCE. On `authorized` the caller exchanges the returned
529
+ * `code` (server-side, via the BFF) for a session — no redirect to a hosted
530
+ * login page. Creds live only for the duration of this request; the SDK never
531
+ * stores them. 5xx surfaces as a typed error; every other status is a typed
532
+ * outcome the UI branches on.
533
+ */
534
+ authorizeWithPassword(params: AuthorizeWithPasswordParams): Promise<PasswordAuthOutcome>;
492
535
  exchangeCode(params: ExchangeCodeParams): Promise<StoredSession>;
493
536
  /** The `RefreshTokens` function the SessionEngine (F003) injects. */
494
537
  createRefresher(): RefreshTokens;
@@ -507,4 +550,4 @@ declare class AuthClient {
507
550
  declare const PACKAGE_NAME = "@poly-x/core";
508
551
  declare const version = "0.0.0";
509
552
  //#endregion
510
- export { AuthClient, type AuthClientOptions, type AuthorizeOutcome, type BuildAuthorizeUrlParams, type Clock, DEFAULT_RETRY_POLICY, DEFAULT_TIMEOUT_MS, ENDPOINTS, type ExchangeCodeParams, FetchTransport, type FieldError, ForbiddenError, type HttpMethod, INITIAL_STATE as INITIAL_SESSION_STATE, InMemoryLock, InMemoryPkceStore, InMemorySessionChannel, InMemorySessionStore, type KeyEnv, type KeyKind, type Lock, type MockRoute, MockTransport, PACKAGE_NAME, type ParsedKey, type PkceEntry, type PkcePair, type PkceStore, type PlatformResponseLike, PolyXConfigError, PolyXError, type PolyXErrorOptions, RateLimitedError, type RefreshTokens, type ResolveConfigInput, type ResolvedConfig, type RetryPolicy, type RuntimeContext, type Session, type SessionChannel, type SessionChannelEvent, type SessionClaims, SessionEngine, type SessionEngineOptions, type SessionEvent, SessionExpiredError, SessionRevokedError, type SessionState, type SessionStore, type SignedOutReason, type StoredSession, SystemClock, type TenantOption, type TimerHandle, type TokenSet, type Transport, type TransportRequest, type TransportResponse, UnauthenticatedError, UpstreamError, ValidationError, computeChallenge, createSessionEngine, decodeJwtExp, generatePkce, isTransientStatus, mapPlatformError, normalizeExchange, normalizeRefresh, parseAuthorizeOutcome, parsePolyXKey, randomState, redactSensitive, reduce as reduceSessionState, resolveConfig, version };
553
+ export { AuthClient, type AuthClientOptions, type AuthorizeOutcome, type AuthorizeWithPasswordParams, type BuildAuthorizeUrlParams, type Clock, DEFAULT_RETRY_POLICY, DEFAULT_TIMEOUT_MS, ENDPOINTS, type ExchangeCodeParams, FetchTransport, type FieldError, ForbiddenError, type HttpMethod, INITIAL_STATE as INITIAL_SESSION_STATE, InMemoryLock, InMemoryPkceStore, InMemorySessionChannel, InMemorySessionStore, type KeyEnv, type KeyKind, type Lock, type MockRoute, MockTransport, PACKAGE_NAME, type ParsedKey, type PasswordAuthOutcome, type PkceEntry, type PkcePair, type PkceStore, type PlatformResponseLike, PolyXConfigError, PolyXError, type PolyXErrorOptions, RateLimitedError, type RefreshTokens, type ResolveConfigInput, type ResolvedConfig, type RetryPolicy, type RuntimeContext, type Session, type SessionChannel, type SessionChannelEvent, type SessionClaims, SessionEngine, type SessionEngineOptions, type SessionEvent, SessionExpiredError, SessionRevokedError, type SessionState, type SessionStore, type SignedOutReason, type StoredSession, SystemClock, type TenantOption, type TimerHandle, type TokenSet, type Transport, type TransportRequest, type TransportResponse, UnauthenticatedError, UpstreamError, ValidationError, computeChallenge, createSessionEngine, decodeJwtExp, generatePkce, isTransientStatus, mapPlatformError, normalizeExchange, normalizeRefresh, parseAuthorizeOutcome, parsePasswordOutcome, parsePolyXKey, randomState, redactSensitive, reduce as reduceSessionState, resolveConfig, version };
package/dist/index.d.mts CHANGED
@@ -421,6 +421,30 @@ type AuthorizeOutcome = {
421
421
  type: "login_required";
422
422
  };
423
423
  declare function parseAuthorizeOutcome(status: number, body: unknown): AuthorizeOutcome;
424
+ /**
425
+ * Outcome of a PASSWORD authorize (`POST /idp/authorize` with credentials) — the
426
+ * embedded `<SignIn/>` flow. Distinguishes invalid-credentials and the
427
+ * must-set-password step from the membership outcomes (the GET warm-hop parser
428
+ * collapses those into login_required).
429
+ */
430
+ type PasswordAuthOutcome = {
431
+ type: "authorized";
432
+ code: string;
433
+ state: string;
434
+ redirectUri?: string;
435
+ } | {
436
+ type: "select_tenant";
437
+ state: string;
438
+ tenants: TenantOption[];
439
+ } | {
440
+ type: "invalid_credentials";
441
+ } | {
442
+ type: "password_change_required";
443
+ userId: string;
444
+ } | {
445
+ type: "no_access";
446
+ };
447
+ declare function parsePasswordOutcome(status: number, body: unknown): PasswordAuthOutcome;
424
448
  //#endregion
425
449
  //#region src/auth/normalize.d.ts
426
450
  declare function decodeJwtExp(token: string): number | null;
@@ -472,6 +496,16 @@ interface ExchangeCodeParams {
472
496
  codeVerifier: string;
473
497
  redirectUri: string;
474
498
  }
499
+ interface AuthorizeWithPasswordParams {
500
+ email: string;
501
+ password: string;
502
+ redirectUri: string;
503
+ state: string;
504
+ challenge: string;
505
+ organizationCode?: string;
506
+ /** Set on the re-attempt after the user picks a workspace (select_tenant). */
507
+ tenantId?: string;
508
+ }
475
509
  declare class AuthClient {
476
510
  private readonly config;
477
511
  private readonly transport;
@@ -489,6 +523,15 @@ declare class AuthClient {
489
523
  buildSignInUrl(params: BuildAuthorizeUrlParams): string;
490
524
  /** Probe the warm hop (GET /idp/authorize) and return the typed outcome. */
491
525
  completeAuthorize(params: BuildAuthorizeUrlParams): Promise<AuthorizeOutcome>;
526
+ /**
527
+ * The embedded `<SignIn/>` credential flow (D2b): POST `/idp/authorize` with
528
+ * email/password + PKCE. On `authorized` the caller exchanges the returned
529
+ * `code` (server-side, via the BFF) for a session — no redirect to a hosted
530
+ * login page. Creds live only for the duration of this request; the SDK never
531
+ * stores them. 5xx surfaces as a typed error; every other status is a typed
532
+ * outcome the UI branches on.
533
+ */
534
+ authorizeWithPassword(params: AuthorizeWithPasswordParams): Promise<PasswordAuthOutcome>;
492
535
  exchangeCode(params: ExchangeCodeParams): Promise<StoredSession>;
493
536
  /** The `RefreshTokens` function the SessionEngine (F003) injects. */
494
537
  createRefresher(): RefreshTokens;
@@ -507,4 +550,4 @@ declare class AuthClient {
507
550
  declare const PACKAGE_NAME = "@poly-x/core";
508
551
  declare const version = "0.0.0";
509
552
  //#endregion
510
- export { AuthClient, type AuthClientOptions, type AuthorizeOutcome, type BuildAuthorizeUrlParams, type Clock, DEFAULT_RETRY_POLICY, DEFAULT_TIMEOUT_MS, ENDPOINTS, type ExchangeCodeParams, FetchTransport, type FieldError, ForbiddenError, type HttpMethod, INITIAL_STATE as INITIAL_SESSION_STATE, InMemoryLock, InMemoryPkceStore, InMemorySessionChannel, InMemorySessionStore, type KeyEnv, type KeyKind, type Lock, type MockRoute, MockTransport, PACKAGE_NAME, type ParsedKey, type PkceEntry, type PkcePair, type PkceStore, type PlatformResponseLike, PolyXConfigError, PolyXError, type PolyXErrorOptions, RateLimitedError, type RefreshTokens, type ResolveConfigInput, type ResolvedConfig, type RetryPolicy, type RuntimeContext, type Session, type SessionChannel, type SessionChannelEvent, type SessionClaims, SessionEngine, type SessionEngineOptions, type SessionEvent, SessionExpiredError, SessionRevokedError, type SessionState, type SessionStore, type SignedOutReason, type StoredSession, SystemClock, type TenantOption, type TimerHandle, type TokenSet, type Transport, type TransportRequest, type TransportResponse, UnauthenticatedError, UpstreamError, ValidationError, computeChallenge, createSessionEngine, decodeJwtExp, generatePkce, isTransientStatus, mapPlatformError, normalizeExchange, normalizeRefresh, parseAuthorizeOutcome, parsePolyXKey, randomState, redactSensitive, reduce as reduceSessionState, resolveConfig, version };
553
+ export { AuthClient, type AuthClientOptions, type AuthorizeOutcome, type AuthorizeWithPasswordParams, type BuildAuthorizeUrlParams, type Clock, DEFAULT_RETRY_POLICY, DEFAULT_TIMEOUT_MS, ENDPOINTS, type ExchangeCodeParams, FetchTransport, type FieldError, ForbiddenError, type HttpMethod, INITIAL_STATE as INITIAL_SESSION_STATE, InMemoryLock, InMemoryPkceStore, InMemorySessionChannel, InMemorySessionStore, type KeyEnv, type KeyKind, type Lock, type MockRoute, MockTransport, PACKAGE_NAME, type ParsedKey, type PasswordAuthOutcome, type PkceEntry, type PkcePair, type PkceStore, type PlatformResponseLike, PolyXConfigError, PolyXError, type PolyXErrorOptions, RateLimitedError, type RefreshTokens, type ResolveConfigInput, type ResolvedConfig, type RetryPolicy, type RuntimeContext, type Session, type SessionChannel, type SessionChannelEvent, type SessionClaims, SessionEngine, type SessionEngineOptions, type SessionEvent, SessionExpiredError, SessionRevokedError, type SessionState, type SessionStore, type SignedOutReason, type StoredSession, SystemClock, type TenantOption, type TimerHandle, type TokenSet, type Transport, type TransportRequest, type TransportResponse, UnauthenticatedError, UpstreamError, ValidationError, computeChallenge, createSessionEngine, decodeJwtExp, generatePkce, isTransientStatus, mapPlatformError, normalizeExchange, normalizeRefresh, parseAuthorizeOutcome, parsePasswordOutcome, parsePolyXKey, randomState, redactSensitive, reduce as reduceSessionState, resolveConfig, version };
package/dist/index.mjs CHANGED
@@ -746,6 +746,27 @@ function parseAuthorizeOutcome(status, body) {
746
746
  if (statusField === "login_required" || b.code === "LOGIN_REQUIRED") return { type: "login_required" };
747
747
  return { type: "login_required" };
748
748
  }
749
+ function parsePasswordOutcome(status, body) {
750
+ const b = asRecord$1(body);
751
+ const statusField = typeof b.status === "string" ? b.status : void 0;
752
+ if (statusField === "authorized" && typeof b.code === "string") return {
753
+ type: "authorized",
754
+ code: b.code,
755
+ state: typeof b.state === "string" ? b.state : "",
756
+ redirectUri: typeof b.redirectUri === "string" ? b.redirectUri : void 0
757
+ };
758
+ if (statusField === "select_tenant") return {
759
+ type: "select_tenant",
760
+ state: typeof b.state === "string" ? b.state : "",
761
+ tenants: parseTenants(b.tenants)
762
+ };
763
+ if (status === 403 && b.userPasswordSet === true && typeof b.userId === "string") return {
764
+ type: "password_change_required",
765
+ userId: b.userId
766
+ };
767
+ if (status === 403) return { type: "no_access" };
768
+ return { type: "invalid_credentials" };
769
+ }
749
770
  //#endregion
750
771
  //#region src/auth/normalize.ts
751
772
  const FALLBACK_TTL_MS = 5 * 6e4;
@@ -858,6 +879,34 @@ var AuthClient = class {
858
879
  if (response.status >= 500) throw this.toError(response);
859
880
  return parseAuthorizeOutcome(response.status, response.body);
860
881
  }
882
+ /**
883
+ * The embedded `<SignIn/>` credential flow (D2b): POST `/idp/authorize` with
884
+ * email/password + PKCE. On `authorized` the caller exchanges the returned
885
+ * `code` (server-side, via the BFF) for a session — no redirect to a hosted
886
+ * login page. Creds live only for the duration of this request; the SDK never
887
+ * stores them. 5xx surfaces as a typed error; every other status is a typed
888
+ * outcome the UI branches on.
889
+ */
890
+ async authorizeWithPassword(params) {
891
+ const response = await this.transport.request({
892
+ method: "POST",
893
+ url: this.config.baseUrl + ENDPOINTS.authorize,
894
+ body: {
895
+ response_type: "code",
896
+ client_id: this.config.key.raw,
897
+ redirect_uri: params.redirectUri,
898
+ state: params.state,
899
+ code_challenge: params.challenge,
900
+ code_challenge_method: "S256",
901
+ email: params.email,
902
+ password: params.password,
903
+ ...params.organizationCode ? { organizationCode: params.organizationCode } : {},
904
+ ...params.tenantId ? { tenantId: params.tenantId } : {}
905
+ }
906
+ });
907
+ if (response.status >= 500) throw this.toError(response);
908
+ return parsePasswordOutcome(response.status, response.body);
909
+ }
861
910
  async exchangeCode(params) {
862
911
  const response = await this.transport.request({
863
912
  method: "POST",
@@ -922,4 +971,4 @@ var AuthClient = class {
922
971
  const PACKAGE_NAME = "@poly-x/core";
923
972
  const version = "0.0.0";
924
973
  //#endregion
925
- export { AuthClient, DEFAULT_RETRY_POLICY, DEFAULT_TIMEOUT_MS, ENDPOINTS, FetchTransport, ForbiddenError, INITIAL_STATE as INITIAL_SESSION_STATE, InMemoryLock, InMemoryPkceStore, InMemorySessionChannel, InMemorySessionStore, MockTransport, PACKAGE_NAME, PolyXConfigError, PolyXError, RateLimitedError, SessionEngine, SessionExpiredError, SessionRevokedError, SystemClock, UnauthenticatedError, UpstreamError, ValidationError, computeChallenge, createSessionEngine, decodeJwtExp, generatePkce, isTransientStatus, mapPlatformError, normalizeExchange, normalizeRefresh, parseAuthorizeOutcome, parsePolyXKey, randomState, redactSensitive, reduce as reduceSessionState, resolveConfig, version };
974
+ export { AuthClient, DEFAULT_RETRY_POLICY, DEFAULT_TIMEOUT_MS, ENDPOINTS, FetchTransport, ForbiddenError, INITIAL_STATE as INITIAL_SESSION_STATE, InMemoryLock, InMemoryPkceStore, InMemorySessionChannel, InMemorySessionStore, MockTransport, PACKAGE_NAME, PolyXConfigError, PolyXError, RateLimitedError, SessionEngine, SessionExpiredError, SessionRevokedError, SystemClock, UnauthenticatedError, UpstreamError, ValidationError, computeChallenge, createSessionEngine, decodeJwtExp, generatePkce, isTransientStatus, mapPlatformError, normalizeExchange, normalizeRefresh, parseAuthorizeOutcome, parsePasswordOutcome, parsePolyXKey, randomState, redactSensitive, reduce as reduceSessionState, resolveConfig, version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poly-x/core",
3
- "version": "0.1.0-alpha.1",
3
+ "version": "0.1.0-alpha.3",
4
4
  "description": "Framework-agnostic core of the PolyX SDK",
5
5
  "license": "MIT",
6
6
  "type": "module",