@iqauth/sdk 2.0.4 → 2.0.5

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.
Files changed (43) hide show
  1. package/dist/browser-session.d.mts +1 -1
  2. package/dist/browser-session.d.ts +1 -1
  3. package/dist/browser-session.js +4 -1
  4. package/dist/browser-session.mjs +1 -1
  5. package/dist/{chunk-JQWYIIIS.mjs → chunk-MDUHPQMM.mjs} +4 -1
  6. package/dist/{chunk-73R6BEGO.mjs → chunk-ZESHDJDU.mjs} +1 -1
  7. package/dist/{client-CggvJmmm.d.ts → client-DXbHb2ul.d.ts} +1 -1
  8. package/dist/{client-C1DXfB8Z.d.mts → client-Dv4v92Mj.d.mts} +1 -1
  9. package/dist/{express-BKAXB5Nl.d.ts → express-B4o3P8vK.d.ts} +1 -1
  10. package/dist/{express-CpfyYTmw.d.mts → express-BZmF1llh.d.mts} +1 -1
  11. package/dist/express.d.mts +3 -3
  12. package/dist/express.d.ts +3 -3
  13. package/dist/express.js +4 -1
  14. package/dist/express.mjs +2 -2
  15. package/dist/fastify.d.mts +6 -0
  16. package/dist/fastify.d.ts +6 -0
  17. package/dist/fastify.js +21 -3
  18. package/dist/fastify.mjs +18 -3
  19. package/dist/hono.js +4 -1
  20. package/dist/hono.mjs +1 -1
  21. package/dist/index.d.mts +2 -2
  22. package/dist/index.d.ts +2 -2
  23. package/dist/index.js +4 -1
  24. package/dist/index.mjs +2 -2
  25. package/dist/mobile.d.mts +1 -1
  26. package/dist/mobile.d.ts +1 -1
  27. package/dist/mobile.js +4 -1
  28. package/dist/mobile.mjs +1 -1
  29. package/dist/next.js +4 -1
  30. package/dist/next.mjs +1 -1
  31. package/dist/react.d.mts +7 -0
  32. package/dist/react.d.ts +7 -0
  33. package/dist/react.js +147 -33
  34. package/dist/react.mjs +147 -33
  35. package/dist/server.d.mts +2 -2
  36. package/dist/server.d.ts +2 -2
  37. package/dist/server.js +4 -1
  38. package/dist/server.mjs +2 -2
  39. package/dist/service.d.mts +1 -1
  40. package/dist/service.d.ts +1 -1
  41. package/dist/service.js +4 -1
  42. package/dist/service.mjs +1 -1
  43. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { c as IQAuthBrowserSessionClientConfig, d as SessionUser } from './types-Cxl3bQHt.mjs';
2
- import { I as IQAuthClient } from './client-C1DXfB8Z.mjs';
2
+ import { I as IQAuthClient } from './client-Dv4v92Mj.mjs';
3
3
  export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.mjs';
4
4
  import 'jsonwebtoken';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { c as IQAuthBrowserSessionClientConfig, d as SessionUser } from './types-Cxl3bQHt.js';
2
- import { I as IQAuthClient } from './client-CggvJmmm.js';
2
+ import { I as IQAuthClient } from './client-DXbHb2ul.js';
3
3
  export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.js';
4
4
  import 'jsonwebtoken';
5
5
 
@@ -449,7 +449,10 @@ function parseMfaResponse(data, browserSessionMode) {
449
449
  var import_crypto = __toESM(require("crypto"));
450
450
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
451
451
  var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
452
- var DEFAULT_TOKEN_ISSUER = "auth.dispositioniq.com";
452
+ var DEFAULT_TOKEN_ISSUER = [
453
+ "https://auth.dispositioniq.com",
454
+ "auth.dispositioniq.com"
455
+ ];
453
456
  var DEFAULT_TOKEN_AUDIENCE = [
454
457
  "dispositioniq",
455
458
  "iqcapture",
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  IQAuthClient
3
- } from "./chunk-JQWYIIIS.mjs";
3
+ } from "./chunk-MDUHPQMM.mjs";
4
4
  import {
5
5
  ErrorCodes,
6
6
  IQAuthError
@@ -164,7 +164,10 @@ function parseMfaResponse(data, browserSessionMode) {
164
164
  import crypto from "crypto";
165
165
  import jwt from "jsonwebtoken";
166
166
  var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
167
- var DEFAULT_TOKEN_ISSUER = "auth.dispositioniq.com";
167
+ var DEFAULT_TOKEN_ISSUER = [
168
+ "https://auth.dispositioniq.com",
169
+ "auth.dispositioniq.com"
170
+ ];
168
171
  var DEFAULT_TOKEN_AUDIENCE = [
169
172
  "dispositioniq",
170
173
  "iqcapture",
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-5WFR6Y33.mjs";
4
4
  import {
5
5
  IQAuthClient
6
- } from "./chunk-JQWYIIIS.mjs";
6
+ } from "./chunk-MDUHPQMM.mjs";
7
7
  import {
8
8
  IQAuthError
9
9
  } from "./chunk-6I6RM4MN.mjs";
@@ -92,7 +92,7 @@ declare class AuthModule {
92
92
  * - Last verified: Phase 0 Research Summary
93
93
  */
94
94
 
95
- declare const DEFAULT_TOKEN_ISSUER = "auth.dispositioniq.com";
95
+ declare const DEFAULT_TOKEN_ISSUER: string[];
96
96
  declare const DEFAULT_TOKEN_AUDIENCE: string[];
97
97
  declare const DEFAULT_CLOCK_TOLERANCE_SECONDS = 30;
98
98
  interface TokenVerifyOptions {
@@ -92,7 +92,7 @@ declare class AuthModule {
92
92
  * - Last verified: Phase 0 Research Summary
93
93
  */
94
94
 
95
- declare const DEFAULT_TOKEN_ISSUER = "auth.dispositioniq.com";
95
+ declare const DEFAULT_TOKEN_ISSUER: string[];
96
96
  declare const DEFAULT_TOKEN_AUDIENCE: string[];
97
97
  declare const DEFAULT_CLOCK_TOLERANCE_SECONDS = 30;
98
98
  interface TokenVerifyOptions {
@@ -1,4 +1,4 @@
1
- import { I as IQAuthClient } from './client-CggvJmmm.js';
1
+ import { I as IQAuthClient } from './client-DXbHb2ul.js';
2
2
  import { J as JwtClaims, N as ExpressMiddlewareOptions, Q as IQAuthRequestLike, R as IQAuthResponseLike, V as IQAuthNextFunction } from './types-Cxl3bQHt.js';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { I as IQAuthClient } from './client-C1DXfB8Z.mjs';
1
+ import { I as IQAuthClient } from './client-Dv4v92Mj.mjs';
2
2
  import { J as JwtClaims, N as ExpressMiddlewareOptions, Q as IQAuthRequestLike, R as IQAuthResponseLike, V as IQAuthNextFunction } from './types-Cxl3bQHt.mjs';
3
3
 
4
4
  /**
@@ -1,6 +1,6 @@
1
- import { I as IQAuthClient } from './client-C1DXfB8Z.mjs';
2
- import { C as CookieAwareMiddlewareOptions } from './express-CpfyYTmw.mjs';
3
- export { i as iqAuthMiddleware } from './express-CpfyYTmw.mjs';
1
+ import { I as IQAuthClient } from './client-Dv4v92Mj.mjs';
2
+ import { C as CookieAwareMiddlewareOptions } from './express-BZmF1llh.mjs';
3
+ export { i as iqAuthMiddleware } from './express-BZmF1llh.mjs';
4
4
  import { IQAuthHelperConfig } from './server/handlers.mjs';
5
5
  import { Q as IQAuthRequestLike, R as IQAuthResponseLike, V as IQAuthNextFunction } from './types-Cxl3bQHt.mjs';
6
6
  export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.mjs';
package/dist/express.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { I as IQAuthClient } from './client-CggvJmmm.js';
2
- import { C as CookieAwareMiddlewareOptions } from './express-BKAXB5Nl.js';
3
- export { i as iqAuthMiddleware } from './express-BKAXB5Nl.js';
1
+ import { I as IQAuthClient } from './client-DXbHb2ul.js';
2
+ import { C as CookieAwareMiddlewareOptions } from './express-B4o3P8vK.js';
3
+ export { i as iqAuthMiddleware } from './express-B4o3P8vK.js';
4
4
  import { IQAuthHelperConfig } from './server/handlers.js';
5
5
  import { Q as IQAuthRequestLike, R as IQAuthResponseLike, V as IQAuthNextFunction } from './types-Cxl3bQHt.js';
6
6
  export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.js';
package/dist/express.js CHANGED
@@ -448,7 +448,10 @@ function parseMfaResponse(data, browserSessionMode) {
448
448
  var import_crypto = __toESM(require("crypto"));
449
449
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
450
450
  var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
451
- var DEFAULT_TOKEN_ISSUER = "auth.dispositioniq.com";
451
+ var DEFAULT_TOKEN_ISSUER = [
452
+ "https://auth.dispositioniq.com",
453
+ "auth.dispositioniq.com"
454
+ ];
452
455
  var DEFAULT_TOKEN_AUDIENCE = [
453
456
  "dispositioniq",
454
457
  "iqcapture",
package/dist/express.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DEFAULT_REFRESH_COOKIE,
3
3
  iqAuthMiddleware
4
- } from "./chunk-73R6BEGO.mjs";
4
+ } from "./chunk-ZESHDJDU.mjs";
5
5
  import {
6
6
  handleCallback,
7
7
  handleRefresh,
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-5WFR6Y33.mjs";
13
13
  import {
14
14
  IQAuthClient
15
- } from "./chunk-JQWYIIIS.mjs";
15
+ } from "./chunk-MDUHPQMM.mjs";
16
16
  import {
17
17
  ErrorCodes,
18
18
  IQAuthError
@@ -17,6 +17,12 @@ interface IQAuthFastifyOptions extends IQAuthHelperConfig {
17
17
  mountHelperRoutes?: boolean;
18
18
  /** Routes that bypass verification (e.g. health checks). */
19
19
  publicPaths?: string[] | ((path: string) => boolean);
20
+ /** Override token verification options (issuer / audience / clock tolerance). */
21
+ verify?: {
22
+ issuer?: string | string[];
23
+ audience?: string | string[];
24
+ clockTolerance?: number;
25
+ };
20
26
  }
21
27
  declare function iqAuth(fastify: any, options: IQAuthFastifyOptions): Promise<void>;
22
28
 
package/dist/fastify.d.ts CHANGED
@@ -17,6 +17,12 @@ interface IQAuthFastifyOptions extends IQAuthHelperConfig {
17
17
  mountHelperRoutes?: boolean;
18
18
  /** Routes that bypass verification (e.g. health checks). */
19
19
  publicPaths?: string[] | ((path: string) => boolean);
20
+ /** Override token verification options (issuer / audience / clock tolerance). */
21
+ verify?: {
22
+ issuer?: string | string[];
23
+ audience?: string | string[];
24
+ clockTolerance?: number;
25
+ };
20
26
  }
21
27
  declare function iqAuth(fastify: any, options: IQAuthFastifyOptions): Promise<void>;
22
28
 
package/dist/fastify.js CHANGED
@@ -410,7 +410,10 @@ function parseMfaResponse(data, browserSessionMode) {
410
410
  var import_crypto = __toESM(require("crypto"));
411
411
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
412
412
  var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
413
- var DEFAULT_TOKEN_ISSUER = "auth.dispositioniq.com";
413
+ var DEFAULT_TOKEN_ISSUER = [
414
+ "https://auth.dispositioniq.com",
415
+ "auth.dispositioniq.com"
416
+ ];
414
417
  var DEFAULT_TOKEN_AUDIENCE = [
415
418
  "dispositioniq",
416
419
  "iqcapture",
@@ -2024,7 +2027,16 @@ async function iqAuth(fastify, options) {
2024
2027
  if (!parsed) throw new Error("@iqauth/sdk/fastify: invalid publishable key");
2025
2028
  const issuer = (options.issuer ?? (parsed.iss.startsWith("http") ? parsed.iss : `https://${parsed.iss}`)).replace(/\/+$/, "");
2026
2029
  const helperConfig = { ...options, issuer };
2027
- const client = new IQAuthClient({ baseUrl: issuer, environment: "server" });
2030
+ const client = new IQAuthClient({
2031
+ baseUrl: issuer,
2032
+ environment: "server",
2033
+ verify: options.verify
2034
+ });
2035
+ const perCallVerify = options.verify ? {
2036
+ issuer: options.verify.issuer,
2037
+ audience: options.verify.audience,
2038
+ clockTolerance: options.verify.clockTolerance
2039
+ } : void 0;
2028
2040
  const accessCookie = options.accessCookieName ?? "iqauth_at";
2029
2041
  const refreshCookie = options.refreshCookieName ?? "iqauth_rt";
2030
2042
  const mount = (options.mountPath ?? "/api/iqauth").replace(/\/+$/, "");
@@ -2047,7 +2059,7 @@ async function iqAuth(fastify, options) {
2047
2059
  return reply;
2048
2060
  }
2049
2061
  try {
2050
- req.auth = await client.tokens.verify(token);
2062
+ req.auth = await client.tokens.verify(token, perCallVerify);
2051
2063
  } catch (err) {
2052
2064
  if (err instanceof IQAuthError && KNOWN_AUTH_ERRORS.has(err.code)) {
2053
2065
  reply.code(401).send({ success: false, error: { code: err.code, message: err.message } });
@@ -2079,6 +2091,12 @@ async function iqAuth(fastify, options) {
2079
2091
  }
2080
2092
  fastify.decorate("iqauth", { client, issuer });
2081
2093
  }
2094
+ iqAuth[/* @__PURE__ */ Symbol.for("skip-override")] = true;
2095
+ iqAuth[/* @__PURE__ */ Symbol.for("fastify.display-name")] = "@iqauth/sdk/fastify";
2096
+ iqAuth[/* @__PURE__ */ Symbol.for("plugin-meta")] = {
2097
+ name: "@iqauth/sdk/fastify",
2098
+ fastify: ">=4.0.0"
2099
+ };
2082
2100
  var fastify_default = iqAuth;
2083
2101
  // Annotate the CommonJS export names for ESM import in node:
2084
2102
  0 && (module.exports = {
package/dist/fastify.mjs CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-5WFR6Y33.mjs";
10
10
  import {
11
11
  IQAuthClient
12
- } from "./chunk-JQWYIIIS.mjs";
12
+ } from "./chunk-MDUHPQMM.mjs";
13
13
  import {
14
14
  IQAuthError
15
15
  } from "./chunk-6I6RM4MN.mjs";
@@ -56,7 +56,16 @@ async function iqAuth(fastify, options) {
56
56
  if (!parsed) throw new Error("@iqauth/sdk/fastify: invalid publishable key");
57
57
  const issuer = (options.issuer ?? (parsed.iss.startsWith("http") ? parsed.iss : `https://${parsed.iss}`)).replace(/\/+$/, "");
58
58
  const helperConfig = { ...options, issuer };
59
- const client = new IQAuthClient({ baseUrl: issuer, environment: "server" });
59
+ const client = new IQAuthClient({
60
+ baseUrl: issuer,
61
+ environment: "server",
62
+ verify: options.verify
63
+ });
64
+ const perCallVerify = options.verify ? {
65
+ issuer: options.verify.issuer,
66
+ audience: options.verify.audience,
67
+ clockTolerance: options.verify.clockTolerance
68
+ } : void 0;
60
69
  const accessCookie = options.accessCookieName ?? "iqauth_at";
61
70
  const refreshCookie = options.refreshCookieName ?? "iqauth_rt";
62
71
  const mount = (options.mountPath ?? "/api/iqauth").replace(/\/+$/, "");
@@ -79,7 +88,7 @@ async function iqAuth(fastify, options) {
79
88
  return reply;
80
89
  }
81
90
  try {
82
- req.auth = await client.tokens.verify(token);
91
+ req.auth = await client.tokens.verify(token, perCallVerify);
83
92
  } catch (err) {
84
93
  if (err instanceof IQAuthError && KNOWN_AUTH_ERRORS.has(err.code)) {
85
94
  reply.code(401).send({ success: false, error: { code: err.code, message: err.message } });
@@ -111,6 +120,12 @@ async function iqAuth(fastify, options) {
111
120
  }
112
121
  fastify.decorate("iqauth", { client, issuer });
113
122
  }
123
+ iqAuth[/* @__PURE__ */ Symbol.for("skip-override")] = true;
124
+ iqAuth[/* @__PURE__ */ Symbol.for("fastify.display-name")] = "@iqauth/sdk/fastify";
125
+ iqAuth[/* @__PURE__ */ Symbol.for("plugin-meta")] = {
126
+ name: "@iqauth/sdk/fastify",
127
+ fastify: ">=4.0.0"
128
+ };
114
129
  var fastify_default = iqAuth;
115
130
  export {
116
131
  fastify_default as default,
package/dist/hono.js CHANGED
@@ -409,7 +409,10 @@ function parseMfaResponse(data, browserSessionMode) {
409
409
  var import_crypto = __toESM(require("crypto"));
410
410
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
411
411
  var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
412
- var DEFAULT_TOKEN_ISSUER = "auth.dispositioniq.com";
412
+ var DEFAULT_TOKEN_ISSUER = [
413
+ "https://auth.dispositioniq.com",
414
+ "auth.dispositioniq.com"
415
+ ];
413
416
  var DEFAULT_TOKEN_AUDIENCE = [
414
417
  "dispositioniq",
415
418
  "iqcapture",
package/dist/hono.mjs CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-5WFR6Y33.mjs";
10
10
  import {
11
11
  IQAuthClient
12
- } from "./chunk-JQWYIIIS.mjs";
12
+ } from "./chunk-MDUHPQMM.mjs";
13
13
  import {
14
14
  IQAuthError
15
15
  } from "./chunk-6I6RM4MN.mjs";
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- export { o as ApiKeysModule, l as AppsModule, A as AuthModule, B as BrandingModule, r as ClientsModule, C as CreateAppRequest, m as CreateAppResponse, h as DEFAULT_CLOCK_TOLERANCE_SECONDS, g as DEFAULT_TOKEN_AUDIENCE, D as DEFAULT_TOKEN_ISSUER, E as EntitlementsModule, G as GdprModule, H as HierarchyModule, I as IQAuthClient, a as InMemoryOidcStateStore, p as InvitesModule, M as MembershipsModule, u as MfaModule, d as OidcAuthRequest, e as OidcCallbackResult, O as OidcModule, f as OidcModuleOptions, b as OidcStateStore, c as OidcStoredRequest, n as PermissionGroupsModule, P as PermissionsModule, t as PinModule, R as RolesModule, s as ScopeModule, S as SessionsModule, q as SourcesModule, k as TenantsModule, i as TokenVerifyOptions, T as TokensModule, j as TokensModuleOptions, U as UsersModule, V as VendorsModule, W as WebhooksModule } from './client-C1DXfB8Z.mjs';
1
+ export { o as ApiKeysModule, l as AppsModule, A as AuthModule, B as BrandingModule, r as ClientsModule, C as CreateAppRequest, m as CreateAppResponse, h as DEFAULT_CLOCK_TOLERANCE_SECONDS, g as DEFAULT_TOKEN_AUDIENCE, D as DEFAULT_TOKEN_ISSUER, E as EntitlementsModule, G as GdprModule, H as HierarchyModule, I as IQAuthClient, a as InMemoryOidcStateStore, p as InvitesModule, M as MembershipsModule, u as MfaModule, d as OidcAuthRequest, e as OidcCallbackResult, O as OidcModule, f as OidcModuleOptions, b as OidcStateStore, c as OidcStoredRequest, n as PermissionGroupsModule, P as PermissionsModule, t as PinModule, R as RolesModule, s as ScopeModule, S as SessionsModule, q as SourcesModule, k as TenantsModule, i as TokenVerifyOptions, T as TokensModule, j as TokensModuleOptions, U as UsersModule, V as VendorsModule, W as WebhooksModule } from './client-Dv4v92Mj.mjs';
2
2
  export { a as ErrorCode, E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.mjs';
3
- export { i as iqAuthMiddleware } from './express-CpfyYTmw.mjs';
3
+ export { i as iqAuthMiddleware } from './express-BZmF1llh.mjs';
4
4
  export { K as KeyMode, b as ParsedPublishableKey, P as PublishableKeyPayload, e as encodePublishableKey, i as isPublishableKey, a as isSecretKey, p as parsePublishableKey } from './publishableKey-B5DIK81A.mjs';
5
5
  export { an as AcceptInviteRequest, aa as AddGroupPermissionRequest, ad as AddUserOverrideRequest, v as ApiErrorResponse, ag as ApiKeyInfo, aj as ApiKeyIntrospection, w as ApiResponse, A as ApiSuccessResponse, _ as AppInfo, Z as AppManifest, a0 as AppSyncResult, a4 as AssignRoleRequest, aM as AvailableScopesTree, a_ as BackupCodeCountResult, aZ as BackupCodesResult, p as BrandingAsset, B as BrandingConfig, r as BrandingDomainMapping, aB as Client, ah as CreateApiKeyRequest, ai as CreateApiKeyResult, aC as CreateClientRequest, al as CreateInviteRequest, aJ as CreateMembershipRequest, a2 as CreateRoleRequest, az as CreateSourceRequest, C as CreateTenantRequest, aw as CreateVendorRequest, ap as CreateWebhookRequest, aq as CreateWebhookResult, ae as EffectivePermission, aY as EmailEnrollResult, at as Entitlement, N as ExpressMiddlewareOptions, aR as GdprExportData, au as GrantEntitlementRequest, a9 as GroupPermission, aG as HierarchyClient, aH as HierarchyLink, aF as HierarchySource, aE as HierarchyVendor, c as IQAuthBrowserSessionClientConfig, a as IQAuthClientConfig, I as IQAuthEnvironment, V as IQAuthNextFunction, Q as IQAuthRequestLike, R as IQAuthResponseLike, W as IQAuthRetryConfig, b as IQAuthTokenClientConfig, X as IQAuthVerifyConfig, ab as InheritanceRelation, ak as Invitation, l as InviteTenantUserRequest, m as InviteTenantUserResult, am as InviteValidation, s as JwksKey, t as JwksResponse, J as JwtClaims, L as LoginResult, aI as Membership, aL as MembershipWithDetails, aU as MfaAvailableMethods, y as MfaEnrollment, x as MfaMethod, F as MfaPolicy, D as MfaVerifyResult, M as MigrateUserRequest, O as OidcDiscovery, u as OidcTokenResponse, E as PasswordPolicy, af as PermissionCheckResult, a8 as PermissionGroup, $ as PermissionNodeInfo, Y as PermissionNodeManifest, aT as PinLoginResult, aS as PinStatus, P as PromoteToVendorRequest, k as PromoteToVendorResult, H as ProvisionUserRequest, K as ProvisionUserResponse, a1 as Role, S as ScopeContext, aQ as ScopeSwitchResult, aN as ScopeTreeClient, aO as ScopeTreeSource, aP as ScopeTreeVendor, h as Session, g as SessionAuthenticatedLoginResult, d as SessionUser, aX as SmsEnrollResult, ay as Source, e as Tenant, i as TenantInfo, a7 as TenantUser, n as TenantUserRoleUpdate, f as TokenAuthenticatedLoginResult, T as TokenPair, aV as TotpEnrollResult, z as TotpEnrollmentResult, aW as TotpVerifyResult, o as UpdateBrandingRequest, aD as UpdateClientRequest, aK as UpdateMembershipRequest, a3 as UpdateRoleRequest, aA as UpdateSourceRequest, j as UpdateTenantRequest, ax as UpdateVendorRequest, q as UploadAssetRequest, a6 as UserGroupAssignment, ac as UserPermissionOverride, G as UserPermissions, U as UserProfile, a5 as UserRoleAssignment, av as Vendor, ar as WebhookDelivery, ao as WebhookEndpoint, as as WebhookTestResult } from './types-Cxl3bQHt.mjs';
6
6
  import 'jsonwebtoken';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export { o as ApiKeysModule, l as AppsModule, A as AuthModule, B as BrandingModule, r as ClientsModule, C as CreateAppRequest, m as CreateAppResponse, h as DEFAULT_CLOCK_TOLERANCE_SECONDS, g as DEFAULT_TOKEN_AUDIENCE, D as DEFAULT_TOKEN_ISSUER, E as EntitlementsModule, G as GdprModule, H as HierarchyModule, I as IQAuthClient, a as InMemoryOidcStateStore, p as InvitesModule, M as MembershipsModule, u as MfaModule, d as OidcAuthRequest, e as OidcCallbackResult, O as OidcModule, f as OidcModuleOptions, b as OidcStateStore, c as OidcStoredRequest, n as PermissionGroupsModule, P as PermissionsModule, t as PinModule, R as RolesModule, s as ScopeModule, S as SessionsModule, q as SourcesModule, k as TenantsModule, i as TokenVerifyOptions, T as TokensModule, j as TokensModuleOptions, U as UsersModule, V as VendorsModule, W as WebhooksModule } from './client-CggvJmmm.js';
1
+ export { o as ApiKeysModule, l as AppsModule, A as AuthModule, B as BrandingModule, r as ClientsModule, C as CreateAppRequest, m as CreateAppResponse, h as DEFAULT_CLOCK_TOLERANCE_SECONDS, g as DEFAULT_TOKEN_AUDIENCE, D as DEFAULT_TOKEN_ISSUER, E as EntitlementsModule, G as GdprModule, H as HierarchyModule, I as IQAuthClient, a as InMemoryOidcStateStore, p as InvitesModule, M as MembershipsModule, u as MfaModule, d as OidcAuthRequest, e as OidcCallbackResult, O as OidcModule, f as OidcModuleOptions, b as OidcStateStore, c as OidcStoredRequest, n as PermissionGroupsModule, P as PermissionsModule, t as PinModule, R as RolesModule, s as ScopeModule, S as SessionsModule, q as SourcesModule, k as TenantsModule, i as TokenVerifyOptions, T as TokensModule, j as TokensModuleOptions, U as UsersModule, V as VendorsModule, W as WebhooksModule } from './client-DXbHb2ul.js';
2
2
  export { a as ErrorCode, E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.js';
3
- export { i as iqAuthMiddleware } from './express-BKAXB5Nl.js';
3
+ export { i as iqAuthMiddleware } from './express-B4o3P8vK.js';
4
4
  export { K as KeyMode, b as ParsedPublishableKey, P as PublishableKeyPayload, e as encodePublishableKey, i as isPublishableKey, a as isSecretKey, p as parsePublishableKey } from './publishableKey-B5DIK81A.js';
5
5
  export { an as AcceptInviteRequest, aa as AddGroupPermissionRequest, ad as AddUserOverrideRequest, v as ApiErrorResponse, ag as ApiKeyInfo, aj as ApiKeyIntrospection, w as ApiResponse, A as ApiSuccessResponse, _ as AppInfo, Z as AppManifest, a0 as AppSyncResult, a4 as AssignRoleRequest, aM as AvailableScopesTree, a_ as BackupCodeCountResult, aZ as BackupCodesResult, p as BrandingAsset, B as BrandingConfig, r as BrandingDomainMapping, aB as Client, ah as CreateApiKeyRequest, ai as CreateApiKeyResult, aC as CreateClientRequest, al as CreateInviteRequest, aJ as CreateMembershipRequest, a2 as CreateRoleRequest, az as CreateSourceRequest, C as CreateTenantRequest, aw as CreateVendorRequest, ap as CreateWebhookRequest, aq as CreateWebhookResult, ae as EffectivePermission, aY as EmailEnrollResult, at as Entitlement, N as ExpressMiddlewareOptions, aR as GdprExportData, au as GrantEntitlementRequest, a9 as GroupPermission, aG as HierarchyClient, aH as HierarchyLink, aF as HierarchySource, aE as HierarchyVendor, c as IQAuthBrowserSessionClientConfig, a as IQAuthClientConfig, I as IQAuthEnvironment, V as IQAuthNextFunction, Q as IQAuthRequestLike, R as IQAuthResponseLike, W as IQAuthRetryConfig, b as IQAuthTokenClientConfig, X as IQAuthVerifyConfig, ab as InheritanceRelation, ak as Invitation, l as InviteTenantUserRequest, m as InviteTenantUserResult, am as InviteValidation, s as JwksKey, t as JwksResponse, J as JwtClaims, L as LoginResult, aI as Membership, aL as MembershipWithDetails, aU as MfaAvailableMethods, y as MfaEnrollment, x as MfaMethod, F as MfaPolicy, D as MfaVerifyResult, M as MigrateUserRequest, O as OidcDiscovery, u as OidcTokenResponse, E as PasswordPolicy, af as PermissionCheckResult, a8 as PermissionGroup, $ as PermissionNodeInfo, Y as PermissionNodeManifest, aT as PinLoginResult, aS as PinStatus, P as PromoteToVendorRequest, k as PromoteToVendorResult, H as ProvisionUserRequest, K as ProvisionUserResponse, a1 as Role, S as ScopeContext, aQ as ScopeSwitchResult, aN as ScopeTreeClient, aO as ScopeTreeSource, aP as ScopeTreeVendor, h as Session, g as SessionAuthenticatedLoginResult, d as SessionUser, aX as SmsEnrollResult, ay as Source, e as Tenant, i as TenantInfo, a7 as TenantUser, n as TenantUserRoleUpdate, f as TokenAuthenticatedLoginResult, T as TokenPair, aV as TotpEnrollResult, z as TotpEnrollmentResult, aW as TotpVerifyResult, o as UpdateBrandingRequest, aD as UpdateClientRequest, aK as UpdateMembershipRequest, a3 as UpdateRoleRequest, aA as UpdateSourceRequest, j as UpdateTenantRequest, ax as UpdateVendorRequest, q as UploadAssetRequest, a6 as UserGroupAssignment, ac as UserPermissionOverride, G as UserPermissions, U as UserProfile, a5 as UserRoleAssignment, av as Vendor, ar as WebhookDelivery, ao as WebhookEndpoint, as as WebhookTestResult } from './types-Cxl3bQHt.js';
6
6
  import 'jsonwebtoken';
package/dist/index.js CHANGED
@@ -480,7 +480,10 @@ function parseMfaResponse(data, browserSessionMode) {
480
480
  var import_crypto = __toESM(require("crypto"));
481
481
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
482
482
  var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
483
- var DEFAULT_TOKEN_ISSUER = "auth.dispositioniq.com";
483
+ var DEFAULT_TOKEN_ISSUER = [
484
+ "https://auth.dispositioniq.com",
485
+ "auth.dispositioniq.com"
486
+ ];
484
487
  var DEFAULT_TOKEN_AUDIENCE = [
485
488
  "dispositioniq",
486
489
  "iqcapture",
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  iqAuthMiddleware
3
- } from "./chunk-73R6BEGO.mjs";
3
+ } from "./chunk-ZESHDJDU.mjs";
4
4
  import {
5
5
  encodePublishableKey,
6
6
  isPublishableKey,
@@ -37,7 +37,7 @@ import {
37
37
  UsersModule,
38
38
  VendorsModule,
39
39
  WebhooksModule
40
- } from "./chunk-JQWYIIIS.mjs";
40
+ } from "./chunk-MDUHPQMM.mjs";
41
41
  import {
42
42
  ErrorCodes,
43
43
  IQAuthError
package/dist/mobile.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { I as IQAuthClient } from './client-C1DXfB8Z.mjs';
1
+ import { I as IQAuthClient } from './client-Dv4v92Mj.mjs';
2
2
  import { b as IQAuthTokenClientConfig } from './types-Cxl3bQHt.mjs';
3
3
  export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.mjs';
4
4
  import 'jsonwebtoken';
package/dist/mobile.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { I as IQAuthClient } from './client-CggvJmmm.js';
1
+ import { I as IQAuthClient } from './client-DXbHb2ul.js';
2
2
  import { b as IQAuthTokenClientConfig } from './types-Cxl3bQHt.js';
3
3
  export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.js';
4
4
  import 'jsonwebtoken';
package/dist/mobile.js CHANGED
@@ -449,7 +449,10 @@ function parseMfaResponse(data, browserSessionMode) {
449
449
  var import_crypto = __toESM(require("crypto"));
450
450
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
451
451
  var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
452
- var DEFAULT_TOKEN_ISSUER = "auth.dispositioniq.com";
452
+ var DEFAULT_TOKEN_ISSUER = [
453
+ "https://auth.dispositioniq.com",
454
+ "auth.dispositioniq.com"
455
+ ];
453
456
  var DEFAULT_TOKEN_AUDIENCE = [
454
457
  "dispositioniq",
455
458
  "iqcapture",
package/dist/mobile.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  IQAuthClient
3
- } from "./chunk-JQWYIIIS.mjs";
3
+ } from "./chunk-MDUHPQMM.mjs";
4
4
  import {
5
5
  ErrorCodes,
6
6
  IQAuthError
package/dist/next.js CHANGED
@@ -643,7 +643,10 @@ function parseMfaResponse(data, browserSessionMode) {
643
643
  var import_crypto = __toESM(require("crypto"));
644
644
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
645
645
  var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
646
- var DEFAULT_TOKEN_ISSUER = "auth.dispositioniq.com";
646
+ var DEFAULT_TOKEN_ISSUER = [
647
+ "https://auth.dispositioniq.com",
648
+ "auth.dispositioniq.com"
649
+ ];
647
650
  var DEFAULT_TOKEN_AUDIENCE = [
648
651
  "dispositioniq",
649
652
  "iqcapture",
package/dist/next.mjs CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-5WFR6Y33.mjs";
10
10
  import {
11
11
  IQAuthClient
12
- } from "./chunk-JQWYIIIS.mjs";
12
+ } from "./chunk-MDUHPQMM.mjs";
13
13
  import "./chunk-6I6RM4MN.mjs";
14
14
  import "./chunk-Y6FXYEAI.mjs";
15
15
 
package/dist/react.d.mts CHANGED
@@ -122,6 +122,8 @@ declare function AuthCallback({ onComplete, fallback }?: AuthCallbackProps): Rea
122
122
  interface IQAuthBranding {
123
123
  brandName: string | null;
124
124
  logoUrl: string | null;
125
+ logoDarkUrl?: string | null;
126
+ faviconUrl?: string | null;
125
127
  loginHeadline: string | null;
126
128
  loginSubheadline: string | null;
127
129
  primaryColor: string | null;
@@ -129,6 +131,11 @@ interface IQAuthBranding {
129
131
  backgroundColor: string | null;
130
132
  surfaceColor: string | null;
131
133
  textColor: string | null;
134
+ heroImageUrl?: string | null;
135
+ tagline?: string | null;
136
+ loginSideCopy?: string | null;
137
+ googleButtonLabel?: string | null;
138
+ customCss?: string | null;
132
139
  supportEmail?: string | null;
133
140
  supportUrl?: string | null;
134
141
  termsUrl?: string | null;
package/dist/react.d.ts CHANGED
@@ -122,6 +122,8 @@ declare function AuthCallback({ onComplete, fallback }?: AuthCallbackProps): Rea
122
122
  interface IQAuthBranding {
123
123
  brandName: string | null;
124
124
  logoUrl: string | null;
125
+ logoDarkUrl?: string | null;
126
+ faviconUrl?: string | null;
125
127
  loginHeadline: string | null;
126
128
  loginSubheadline: string | null;
127
129
  primaryColor: string | null;
@@ -129,6 +131,11 @@ interface IQAuthBranding {
129
131
  backgroundColor: string | null;
130
132
  surfaceColor: string | null;
131
133
  textColor: string | null;
134
+ heroImageUrl?: string | null;
135
+ tagline?: string | null;
136
+ loginSideCopy?: string | null;
137
+ googleButtonLabel?: string | null;
138
+ customCss?: string | null;
132
139
  supportEmail?: string | null;
133
140
  supportUrl?: string | null;
134
141
  termsUrl?: string | null;
package/dist/react.js CHANGED
@@ -950,29 +950,147 @@ function useIQAuthSignInContext(iqAuthBaseUrl, appKey, returnTo) {
950
950
  }, [iqAuthBaseUrl, appKey, returnTo]);
951
951
  return { ctx, loading, error };
952
952
  }
953
+ var SHELL_CSS = `
954
+ .iqauth-sdk-shell {
955
+ min-height: 100vh;
956
+ display: grid;
957
+ grid-template-columns: 1fr;
958
+ background: var(--brand-bg, #f7f7f6);
959
+ color: var(--brand-text, #0f172a);
960
+ }
961
+ .iqauth-sdk-hero { display: none; }
962
+ .iqauth-sdk-pane {
963
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
964
+ padding: 40px 16px; min-height: 100vh;
965
+ }
966
+ .iqauth-sdk-card {
967
+ width: 100%; max-width: 420px;
968
+ background: var(--brand-surface, #ffffff);
969
+ border: 1px solid rgba(15,23,42,0.08);
970
+ border-radius: 14px;
971
+ box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 8px 24px rgba(15,23,42,0.04);
972
+ overflow: hidden;
973
+ }
974
+ .iqauth-sdk-card-header { padding: 28px 28px 0; }
975
+ .iqauth-sdk-card-header h1 { font-size: 22px; font-weight: 600; margin: 0; line-height: 1.2; }
976
+ .iqauth-sdk-card-header p { margin: 8px 0 0; font-size: 14px; color: rgba(15,23,42,0.65); line-height: 1.5; }
977
+ .iqauth-sdk-card-body { padding: 28px 28px 24px; display: flex; flex-direction: column; gap: 18px; }
978
+ .iqauth-sdk-mobile-brand { display: flex; align-items: center; gap: 10px; margin-bottom: 20px; }
979
+ .iqauth-sdk-mobile-brand img { height: 36px; width: auto; }
980
+ .iqauth-sdk-mobile-brand span { font-size: 16px; font-weight: 600; }
981
+ .iqauth-sdk-footer { margin-top: 20px; text-align: center; font-size: 13px; color: rgba(15,23,42,0.55); display: flex; flex-direction: column; gap: 8px; align-items: center; }
982
+ .iqauth-sdk-footer-links { display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; }
983
+ .iqauth-sdk-footer-links a { color: inherit; opacity: 0.75; text-decoration: none; }
984
+ .iqauth-sdk-footer-links a:hover { opacity: 1; text-decoration: underline; }
985
+ .iqauth-sdk-divider { display: flex; align-items: center; gap: 10px; font-size: 12px; color: rgba(15,23,42,0.45); text-transform: uppercase; letter-spacing: 0.08em; }
986
+ .iqauth-sdk-divider::before, .iqauth-sdk-divider::after { content: ""; flex: 1; height: 1px; background: rgba(15,23,42,0.1); }
987
+ .iqauth-sdk-google-btn {
988
+ display: inline-flex; align-items: center; justify-content: center; gap: 10px;
989
+ width: 100%; padding: 10px 16px; border-radius: 8px;
990
+ background: #fff; color: #0f172a;
991
+ border: 1px solid rgba(15,23,42,0.18);
992
+ font-size: 14px; font-weight: 500; cursor: pointer;
993
+ transition: background 120ms ease, border-color 120ms ease;
994
+ }
995
+ .iqauth-sdk-google-btn:hover { background: #f8fafc; border-color: rgba(15,23,42,0.28); }
996
+ .iqauth-sdk-google-btn[disabled] { opacity: 0.6; cursor: not-allowed; }
997
+
998
+ @media (min-width: 900px) {
999
+ .iqauth-sdk-shell { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }
1000
+ .iqauth-sdk-hero {
1001
+ display: flex; flex-direction: column; justify-content: space-between;
1002
+ padding: 48px 56px; color: #ffffff;
1003
+ background: linear-gradient(135deg, var(--brand-primary, #3b82f6) 0%, var(--brand-accent, #6366f1) 100%);
1004
+ background-size: cover; background-position: center;
1005
+ position: relative; overflow: hidden; min-height: 100vh;
1006
+ }
1007
+ .iqauth-sdk-hero[data-bg-image="true"] {
1008
+ background-image: var(--iqauth-sdk-hero-image), linear-gradient(135deg, var(--brand-primary, #3b82f6), var(--brand-accent, #6366f1));
1009
+ background-blend-mode: multiply;
1010
+ }
1011
+ .iqauth-sdk-hero-brand img { height: 44px; width: auto; filter: brightness(0) invert(1); opacity: 0.96; }
1012
+ .iqauth-sdk-hero-brand .iqauth-sdk-hero-name { font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
1013
+ .iqauth-sdk-hero-content h2 { font-size: 34px; font-weight: 600; line-height: 1.15; margin: 0 0 14px; letter-spacing: -0.015em; }
1014
+ .iqauth-sdk-hero-content p { font-size: 15px; line-height: 1.6; opacity: 0.92; margin: 0; max-width: 460px; white-space: pre-wrap; }
1015
+ .iqauth-sdk-hero-foot { font-size: 12px; opacity: 0.7; }
1016
+ .iqauth-sdk-mobile-brand { display: none; }
1017
+ }
1018
+ `;
1019
+ var sdkShellStylesInjected = false;
1020
+ function ensureSdkShellStyles() {
1021
+ if (typeof document === "undefined" || sdkShellStylesInjected) return;
1022
+ const tag = document.createElement("style");
1023
+ tag.setAttribute("data-iqauth-sdk-shell", "");
1024
+ tag.textContent = SHELL_CSS;
1025
+ document.head.appendChild(tag);
1026
+ sdkShellStylesInjected = true;
1027
+ }
1028
+ function useDocumentBranding(branding, fallbackTitle) {
1029
+ (0, import_react.useEffect)(() => {
1030
+ if (typeof document === "undefined") return;
1031
+ const prevTitle = document.title;
1032
+ const brandName = branding?.brandName || "IQAuth";
1033
+ document.title = `${fallbackTitle} \xB7 ${brandName}`;
1034
+ let linkEl = null;
1035
+ let prevHref = null;
1036
+ if (branding?.faviconUrl) {
1037
+ linkEl = document.querySelector("link[rel='icon']");
1038
+ if (!linkEl) {
1039
+ linkEl = document.createElement("link");
1040
+ linkEl.rel = "icon";
1041
+ document.head.appendChild(linkEl);
1042
+ } else {
1043
+ prevHref = linkEl.href;
1044
+ }
1045
+ linkEl.href = branding.faviconUrl;
1046
+ }
1047
+ return () => {
1048
+ document.title = prevTitle;
1049
+ if (linkEl && prevHref !== null) linkEl.href = prevHref;
1050
+ };
1051
+ }, [branding?.brandName, branding?.faviconUrl, fallbackTitle]);
1052
+ }
953
1053
  function Shell({
954
1054
  branding,
955
1055
  className,
956
- children
1056
+ children,
1057
+ title,
1058
+ subtitle
957
1059
  }) {
958
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
959
- "div",
960
- {
961
- className,
962
- style: {
963
- background: "var(--brand-surface, #ffffff)",
964
- color: "var(--brand-text, #0f172a)",
965
- border: "1px solid rgba(15,23,42,0.08)",
966
- borderRadius: 12,
967
- padding: 24,
968
- ...brandStyle(branding)
969
- },
970
- children: [
971
- branding?.logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: branding.logoUrl, alt: branding.brandName || "", style: { height: 28, width: "auto", marginBottom: 16 } }) : null,
972
- children
973
- ]
974
- }
975
- );
1060
+ ensureSdkShellStyles();
1061
+ useDocumentBranding(branding, title || "Sign in");
1062
+ const brandVars = brandStyle(branding);
1063
+ const brandName = branding?.brandName || "IQAuth";
1064
+ const heroImage = branding?.heroImageUrl || null;
1065
+ const heroStyle = heroImage ? { ["--iqauth-sdk-hero-image"]: `url("${heroImage.replace(/"/g, '\\"')}")` } : {};
1066
+ const supportLink = branding?.supportUrl ? branding.supportUrl : branding?.supportEmail ? `mailto:${branding.supportEmail}` : null;
1067
+ const hasFooterLinks = !!(branding?.termsUrl || branding?.privacyUrl || supportLink);
1068
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `iqauth-sdk-shell${className ? ` ${className}` : ""}`, style: brandVars, "data-iqauth-shell": "", children: [
1069
+ branding?.customCss ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { "data-iqauth-sdk-custom": true, children: branding.customCss }) : null,
1070
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", { className: "iqauth-sdk-hero", "data-bg-image": heroImage ? "true" : "false", style: heroStyle, "aria-hidden": "true", children: [
1071
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "iqauth-sdk-hero-brand", style: { display: "flex", alignItems: "center", gap: 12 }, children: branding?.logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: branding.logoUrl, alt: "" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "iqauth-sdk-hero-name", children: brandName }) }),
1072
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "iqauth-sdk-hero-content", children: [
1073
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: branding?.tagline || `Welcome to ${brandName}` }),
1074
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: branding?.loginSideCopy || branding?.loginSubheadline || `Sign in to continue to your ${brandName} workspace.` })
1075
+ ] }),
1076
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "iqauth-sdk-hero-foot", children: `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} ${brandName}` })
1077
+ ] }),
1078
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "iqauth-sdk-pane", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", { style: { width: "100%", maxWidth: 420 }, children: [
1079
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "iqauth-sdk-mobile-brand", children: branding?.logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: branding.logoUrl, alt: `${brandName} logo` }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: brandName }) }),
1080
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "iqauth-sdk-card", children: [
1081
+ title || subtitle ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "iqauth-sdk-card-header", children: [
1082
+ title ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { children: title }) : null,
1083
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: subtitle }) : null
1084
+ ] }) : null,
1085
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "iqauth-sdk-card-body", children })
1086
+ ] }),
1087
+ hasFooterLinks ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("footer", { className: "iqauth-sdk-footer", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "iqauth-sdk-footer-links", children: [
1088
+ branding?.termsUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: branding.termsUrl, target: "_blank", rel: "noreferrer noopener", children: "Terms" }) : null,
1089
+ branding?.privacyUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: branding.privacyUrl, target: "_blank", rel: "noreferrer noopener", children: "Privacy" }) : null,
1090
+ supportLink ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: supportLink, target: "_blank", rel: "noreferrer noopener", children: "Support" }) : null
1091
+ ] }) }) : null
1092
+ ] }) })
1093
+ ] });
976
1094
  }
977
1095
  function Field({ label, children }) {
978
1096
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: { display: "flex", flexDirection: "column", gap: 6, fontSize: 13 }, children: [
@@ -1174,13 +1292,13 @@ function SignIn({ iqAuthBaseUrl, appKey, returnTo, onRedirect, className }) {
1174
1292
  setOauthExchanging(false);
1175
1293
  })();
1176
1294
  }, [ctx?.app.defaultClientId]);
1177
- if (loading || oauthExchanging) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { branding: ctx?.branding || null, className, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: oauthExchanging ? "Completing sign-in\u2026" : "Loading\u2026" }) });
1178
- if (error || !ctx) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { branding: null, className, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorBanner, { message: error || "Failed to load app context" }) });
1179
- if (!ctx.returnAllowed) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { branding: ctx.branding, className, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorBanner, { message: `returnTo "${returnTo}" is not in this app's allowed origins.` }) });
1180
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Shell, { branding: ctx.branding, className, children: [
1181
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { style: { fontSize: 20, fontWeight: 600, margin: "0 0 12px" }, children: ctx.branding?.loginHeadline || `Sign in to ${ctx.app.name}` }),
1182
- ctx.branding?.loginSubheadline ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { marginBottom: 16, fontSize: 13, opacity: 0.7 }, children: ctx.branding.loginSubheadline }) : null,
1183
- formError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorBanner, { message: formError }) }) : null,
1295
+ if (loading || oauthExchanging) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { branding: ctx?.branding || null, className, title: oauthExchanging ? "Completing sign-in\u2026" : "Loading\u2026", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: oauthExchanging ? "Completing sign-in\u2026" : "Loading\u2026" }) });
1296
+ if (error || !ctx) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { branding: null, className, title: "Application unavailable", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorBanner, { message: error || "Failed to load app context" }) });
1297
+ if (!ctx.returnAllowed) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { branding: ctx.branding, className, title: "Invalid redirect", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorBanner, { message: `returnTo "${returnTo}" is not in this app's allowed origins.` }) });
1298
+ const cardTitle = ctx.branding?.loginHeadline || `Sign in to ${ctx.app.name}`;
1299
+ const cardSubtitle = ctx.branding?.loginSubheadline || void 0;
1300
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Shell, { branding: ctx.branding, className, title: cardTitle, subtitle: cardSubtitle, children: [
1301
+ formError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorBanner, { message: formError }) : null,
1184
1302
  tenantSel ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { role: "radiogroup", "aria-label": "Choose tenant", style: { display: "flex", flexDirection: "column", gap: 8 }, children: tenantSel.tenants.map((t) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1185
1303
  "button",
1186
1304
  {
@@ -1210,20 +1328,16 @@ function SignIn({ iqAuthBaseUrl, appKey, returnTo, onRedirect, className }) {
1210
1328
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GhostButton, { type: "button", onClick: () => setMfa({ ...mfa, backup: !mfa.backup, code: "" }), children: mfa.backup ? "Use verification code" : "Use backup code" })
1211
1329
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: [
1212
1330
  ctx.providers?.google ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1213
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(GhostButton, { type: "button", onClick: startGoogleLogin, disabled: submitting, "aria-label": "Continue with Google", style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 10 }, children: [
1331
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", className: "iqauth-sdk-google-btn", onClick: startGoogleLogin, disabled: submitting, "aria-label": ctx.branding?.googleButtonLabel || "Continue with Google", children: [
1214
1332
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", "aria-hidden": "true", children: [
1215
1333
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "#4285F4", d: "M17.64 9.2c0-.64-.06-1.25-.17-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.71v2.26h2.92a8.78 8.78 0 0 0 2.68-6.61z" }),
1216
1334
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "#34A853", d: "M9 18c2.43 0 4.47-.81 5.96-2.18l-2.92-2.26a5.4 5.4 0 0 1-8.04-2.83H.96v2.33A9 9 0 0 0 9 18z" }),
1217
1335
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "#FBBC05", d: "M3.96 10.71A5.41 5.41 0 0 1 3.68 9c0-.59.1-1.17.29-1.71V4.96H.96a9 9 0 0 0 0 8.08l3-2.33z" }),
1218
1336
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "#EA4335", d: "M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.59A9 9 0 0 0 .96 4.96l3 2.33A5.4 5.4 0 0 1 9 3.58z" })
1219
1337
  ] }),
1220
- "Continue with Google"
1338
+ ctx.branding?.googleButtonLabel || "Continue with Google"
1221
1339
  ] }),
1222
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { role: "separator", "aria-label": "or", style: { display: "flex", alignItems: "center", gap: 10, fontSize: 12, opacity: 0.6 }, children: [
1223
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { flex: 1, height: 1, background: "rgba(15,23,42,0.12)" } }),
1224
- "OR",
1225
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { flex: 1, height: 1, background: "rgba(15,23,42,0.12)" } })
1226
- ] })
1340
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { role: "separator", "aria-label": "or", className: "iqauth-sdk-divider", children: "OR" })
1227
1341
  ] }) : null,
1228
1342
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: submitLogin, style: { display: "flex", flexDirection: "column", gap: 12 }, "aria-label": `Sign in to ${ctx.app.name}`, children: [
1229
1343
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, { label: "Email", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { style: inputStyle(), type: "email", autoComplete: "email", required: true, value: email, onChange: (e) => setEmail(e.target.value) }) }),
package/dist/react.mjs CHANGED
@@ -251,29 +251,147 @@ function useIQAuthSignInContext(iqAuthBaseUrl, appKey, returnTo) {
251
251
  }, [iqAuthBaseUrl, appKey, returnTo]);
252
252
  return { ctx, loading, error };
253
253
  }
254
+ var SHELL_CSS = `
255
+ .iqauth-sdk-shell {
256
+ min-height: 100vh;
257
+ display: grid;
258
+ grid-template-columns: 1fr;
259
+ background: var(--brand-bg, #f7f7f6);
260
+ color: var(--brand-text, #0f172a);
261
+ }
262
+ .iqauth-sdk-hero { display: none; }
263
+ .iqauth-sdk-pane {
264
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
265
+ padding: 40px 16px; min-height: 100vh;
266
+ }
267
+ .iqauth-sdk-card {
268
+ width: 100%; max-width: 420px;
269
+ background: var(--brand-surface, #ffffff);
270
+ border: 1px solid rgba(15,23,42,0.08);
271
+ border-radius: 14px;
272
+ box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 8px 24px rgba(15,23,42,0.04);
273
+ overflow: hidden;
274
+ }
275
+ .iqauth-sdk-card-header { padding: 28px 28px 0; }
276
+ .iqauth-sdk-card-header h1 { font-size: 22px; font-weight: 600; margin: 0; line-height: 1.2; }
277
+ .iqauth-sdk-card-header p { margin: 8px 0 0; font-size: 14px; color: rgba(15,23,42,0.65); line-height: 1.5; }
278
+ .iqauth-sdk-card-body { padding: 28px 28px 24px; display: flex; flex-direction: column; gap: 18px; }
279
+ .iqauth-sdk-mobile-brand { display: flex; align-items: center; gap: 10px; margin-bottom: 20px; }
280
+ .iqauth-sdk-mobile-brand img { height: 36px; width: auto; }
281
+ .iqauth-sdk-mobile-brand span { font-size: 16px; font-weight: 600; }
282
+ .iqauth-sdk-footer { margin-top: 20px; text-align: center; font-size: 13px; color: rgba(15,23,42,0.55); display: flex; flex-direction: column; gap: 8px; align-items: center; }
283
+ .iqauth-sdk-footer-links { display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; }
284
+ .iqauth-sdk-footer-links a { color: inherit; opacity: 0.75; text-decoration: none; }
285
+ .iqauth-sdk-footer-links a:hover { opacity: 1; text-decoration: underline; }
286
+ .iqauth-sdk-divider { display: flex; align-items: center; gap: 10px; font-size: 12px; color: rgba(15,23,42,0.45); text-transform: uppercase; letter-spacing: 0.08em; }
287
+ .iqauth-sdk-divider::before, .iqauth-sdk-divider::after { content: ""; flex: 1; height: 1px; background: rgba(15,23,42,0.1); }
288
+ .iqauth-sdk-google-btn {
289
+ display: inline-flex; align-items: center; justify-content: center; gap: 10px;
290
+ width: 100%; padding: 10px 16px; border-radius: 8px;
291
+ background: #fff; color: #0f172a;
292
+ border: 1px solid rgba(15,23,42,0.18);
293
+ font-size: 14px; font-weight: 500; cursor: pointer;
294
+ transition: background 120ms ease, border-color 120ms ease;
295
+ }
296
+ .iqauth-sdk-google-btn:hover { background: #f8fafc; border-color: rgba(15,23,42,0.28); }
297
+ .iqauth-sdk-google-btn[disabled] { opacity: 0.6; cursor: not-allowed; }
298
+
299
+ @media (min-width: 900px) {
300
+ .iqauth-sdk-shell { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }
301
+ .iqauth-sdk-hero {
302
+ display: flex; flex-direction: column; justify-content: space-between;
303
+ padding: 48px 56px; color: #ffffff;
304
+ background: linear-gradient(135deg, var(--brand-primary, #3b82f6) 0%, var(--brand-accent, #6366f1) 100%);
305
+ background-size: cover; background-position: center;
306
+ position: relative; overflow: hidden; min-height: 100vh;
307
+ }
308
+ .iqauth-sdk-hero[data-bg-image="true"] {
309
+ background-image: var(--iqauth-sdk-hero-image), linear-gradient(135deg, var(--brand-primary, #3b82f6), var(--brand-accent, #6366f1));
310
+ background-blend-mode: multiply;
311
+ }
312
+ .iqauth-sdk-hero-brand img { height: 44px; width: auto; filter: brightness(0) invert(1); opacity: 0.96; }
313
+ .iqauth-sdk-hero-brand .iqauth-sdk-hero-name { font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
314
+ .iqauth-sdk-hero-content h2 { font-size: 34px; font-weight: 600; line-height: 1.15; margin: 0 0 14px; letter-spacing: -0.015em; }
315
+ .iqauth-sdk-hero-content p { font-size: 15px; line-height: 1.6; opacity: 0.92; margin: 0; max-width: 460px; white-space: pre-wrap; }
316
+ .iqauth-sdk-hero-foot { font-size: 12px; opacity: 0.7; }
317
+ .iqauth-sdk-mobile-brand { display: none; }
318
+ }
319
+ `;
320
+ var sdkShellStylesInjected = false;
321
+ function ensureSdkShellStyles() {
322
+ if (typeof document === "undefined" || sdkShellStylesInjected) return;
323
+ const tag = document.createElement("style");
324
+ tag.setAttribute("data-iqauth-sdk-shell", "");
325
+ tag.textContent = SHELL_CSS;
326
+ document.head.appendChild(tag);
327
+ sdkShellStylesInjected = true;
328
+ }
329
+ function useDocumentBranding(branding, fallbackTitle) {
330
+ useEffect(() => {
331
+ if (typeof document === "undefined") return;
332
+ const prevTitle = document.title;
333
+ const brandName = branding?.brandName || "IQAuth";
334
+ document.title = `${fallbackTitle} \xB7 ${brandName}`;
335
+ let linkEl = null;
336
+ let prevHref = null;
337
+ if (branding?.faviconUrl) {
338
+ linkEl = document.querySelector("link[rel='icon']");
339
+ if (!linkEl) {
340
+ linkEl = document.createElement("link");
341
+ linkEl.rel = "icon";
342
+ document.head.appendChild(linkEl);
343
+ } else {
344
+ prevHref = linkEl.href;
345
+ }
346
+ linkEl.href = branding.faviconUrl;
347
+ }
348
+ return () => {
349
+ document.title = prevTitle;
350
+ if (linkEl && prevHref !== null) linkEl.href = prevHref;
351
+ };
352
+ }, [branding?.brandName, branding?.faviconUrl, fallbackTitle]);
353
+ }
254
354
  function Shell({
255
355
  branding,
256
356
  className,
257
- children
357
+ children,
358
+ title,
359
+ subtitle
258
360
  }) {
259
- return /* @__PURE__ */ jsxs(
260
- "div",
261
- {
262
- className,
263
- style: {
264
- background: "var(--brand-surface, #ffffff)",
265
- color: "var(--brand-text, #0f172a)",
266
- border: "1px solid rgba(15,23,42,0.08)",
267
- borderRadius: 12,
268
- padding: 24,
269
- ...brandStyle(branding)
270
- },
271
- children: [
272
- branding?.logoUrl ? /* @__PURE__ */ jsx("img", { src: branding.logoUrl, alt: branding.brandName || "", style: { height: 28, width: "auto", marginBottom: 16 } }) : null,
273
- children
274
- ]
275
- }
276
- );
361
+ ensureSdkShellStyles();
362
+ useDocumentBranding(branding, title || "Sign in");
363
+ const brandVars = brandStyle(branding);
364
+ const brandName = branding?.brandName || "IQAuth";
365
+ const heroImage = branding?.heroImageUrl || null;
366
+ const heroStyle = heroImage ? { ["--iqauth-sdk-hero-image"]: `url("${heroImage.replace(/"/g, '\\"')}")` } : {};
367
+ const supportLink = branding?.supportUrl ? branding.supportUrl : branding?.supportEmail ? `mailto:${branding.supportEmail}` : null;
368
+ const hasFooterLinks = !!(branding?.termsUrl || branding?.privacyUrl || supportLink);
369
+ return /* @__PURE__ */ jsxs("div", { className: `iqauth-sdk-shell${className ? ` ${className}` : ""}`, style: brandVars, "data-iqauth-shell": "", children: [
370
+ branding?.customCss ? /* @__PURE__ */ jsx("style", { "data-iqauth-sdk-custom": true, children: branding.customCss }) : null,
371
+ /* @__PURE__ */ jsxs("aside", { className: "iqauth-sdk-hero", "data-bg-image": heroImage ? "true" : "false", style: heroStyle, "aria-hidden": "true", children: [
372
+ /* @__PURE__ */ jsx("div", { className: "iqauth-sdk-hero-brand", style: { display: "flex", alignItems: "center", gap: 12 }, children: branding?.logoUrl ? /* @__PURE__ */ jsx("img", { src: branding.logoUrl, alt: "" }) : /* @__PURE__ */ jsx("span", { className: "iqauth-sdk-hero-name", children: brandName }) }),
373
+ /* @__PURE__ */ jsxs("div", { className: "iqauth-sdk-hero-content", children: [
374
+ /* @__PURE__ */ jsx("h2", { children: branding?.tagline || `Welcome to ${brandName}` }),
375
+ /* @__PURE__ */ jsx("p", { children: branding?.loginSideCopy || branding?.loginSubheadline || `Sign in to continue to your ${brandName} workspace.` })
376
+ ] }),
377
+ /* @__PURE__ */ jsx("div", { className: "iqauth-sdk-hero-foot", children: `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} ${brandName}` })
378
+ ] }),
379
+ /* @__PURE__ */ jsx("div", { className: "iqauth-sdk-pane", children: /* @__PURE__ */ jsxs("main", { style: { width: "100%", maxWidth: 420 }, children: [
380
+ /* @__PURE__ */ jsx("div", { className: "iqauth-sdk-mobile-brand", children: branding?.logoUrl ? /* @__PURE__ */ jsx("img", { src: branding.logoUrl, alt: `${brandName} logo` }) : /* @__PURE__ */ jsx("span", { children: brandName }) }),
381
+ /* @__PURE__ */ jsxs("section", { className: "iqauth-sdk-card", children: [
382
+ title || subtitle ? /* @__PURE__ */ jsxs("div", { className: "iqauth-sdk-card-header", children: [
383
+ title ? /* @__PURE__ */ jsx("h1", { children: title }) : null,
384
+ subtitle ? /* @__PURE__ */ jsx("p", { children: subtitle }) : null
385
+ ] }) : null,
386
+ /* @__PURE__ */ jsx("div", { className: "iqauth-sdk-card-body", children })
387
+ ] }),
388
+ hasFooterLinks ? /* @__PURE__ */ jsx("footer", { className: "iqauth-sdk-footer", children: /* @__PURE__ */ jsxs("div", { className: "iqauth-sdk-footer-links", children: [
389
+ branding?.termsUrl ? /* @__PURE__ */ jsx("a", { href: branding.termsUrl, target: "_blank", rel: "noreferrer noopener", children: "Terms" }) : null,
390
+ branding?.privacyUrl ? /* @__PURE__ */ jsx("a", { href: branding.privacyUrl, target: "_blank", rel: "noreferrer noopener", children: "Privacy" }) : null,
391
+ supportLink ? /* @__PURE__ */ jsx("a", { href: supportLink, target: "_blank", rel: "noreferrer noopener", children: "Support" }) : null
392
+ ] }) }) : null
393
+ ] }) })
394
+ ] });
277
395
  }
278
396
  function Field({ label, children }) {
279
397
  return /* @__PURE__ */ jsxs("label", { style: { display: "flex", flexDirection: "column", gap: 6, fontSize: 13 }, children: [
@@ -475,13 +593,13 @@ function SignIn({ iqAuthBaseUrl, appKey, returnTo, onRedirect, className }) {
475
593
  setOauthExchanging(false);
476
594
  })();
477
595
  }, [ctx?.app.defaultClientId]);
478
- if (loading || oauthExchanging) return /* @__PURE__ */ jsx(Shell, { branding: ctx?.branding || null, className, children: /* @__PURE__ */ jsx("p", { children: oauthExchanging ? "Completing sign-in\u2026" : "Loading\u2026" }) });
479
- if (error || !ctx) return /* @__PURE__ */ jsx(Shell, { branding: null, className, children: /* @__PURE__ */ jsx(ErrorBanner, { message: error || "Failed to load app context" }) });
480
- if (!ctx.returnAllowed) return /* @__PURE__ */ jsx(Shell, { branding: ctx.branding, className, children: /* @__PURE__ */ jsx(ErrorBanner, { message: `returnTo "${returnTo}" is not in this app's allowed origins.` }) });
481
- return /* @__PURE__ */ jsxs(Shell, { branding: ctx.branding, className, children: [
482
- /* @__PURE__ */ jsx("h2", { style: { fontSize: 20, fontWeight: 600, margin: "0 0 12px" }, children: ctx.branding?.loginHeadline || `Sign in to ${ctx.app.name}` }),
483
- ctx.branding?.loginSubheadline ? /* @__PURE__ */ jsx("p", { style: { marginBottom: 16, fontSize: 13, opacity: 0.7 }, children: ctx.branding.loginSubheadline }) : null,
484
- formError ? /* @__PURE__ */ jsx("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ jsx(ErrorBanner, { message: formError }) }) : null,
596
+ if (loading || oauthExchanging) return /* @__PURE__ */ jsx(Shell, { branding: ctx?.branding || null, className, title: oauthExchanging ? "Completing sign-in\u2026" : "Loading\u2026", children: /* @__PURE__ */ jsx("p", { children: oauthExchanging ? "Completing sign-in\u2026" : "Loading\u2026" }) });
597
+ if (error || !ctx) return /* @__PURE__ */ jsx(Shell, { branding: null, className, title: "Application unavailable", children: /* @__PURE__ */ jsx(ErrorBanner, { message: error || "Failed to load app context" }) });
598
+ if (!ctx.returnAllowed) return /* @__PURE__ */ jsx(Shell, { branding: ctx.branding, className, title: "Invalid redirect", children: /* @__PURE__ */ jsx(ErrorBanner, { message: `returnTo "${returnTo}" is not in this app's allowed origins.` }) });
599
+ const cardTitle = ctx.branding?.loginHeadline || `Sign in to ${ctx.app.name}`;
600
+ const cardSubtitle = ctx.branding?.loginSubheadline || void 0;
601
+ return /* @__PURE__ */ jsxs(Shell, { branding: ctx.branding, className, title: cardTitle, subtitle: cardSubtitle, children: [
602
+ formError ? /* @__PURE__ */ jsx(ErrorBanner, { message: formError }) : null,
485
603
  tenantSel ? /* @__PURE__ */ jsx("div", { role: "radiogroup", "aria-label": "Choose tenant", style: { display: "flex", flexDirection: "column", gap: 8 }, children: tenantSel.tenants.map((t) => /* @__PURE__ */ jsxs(
486
604
  "button",
487
605
  {
@@ -511,20 +629,16 @@ function SignIn({ iqAuthBaseUrl, appKey, returnTo, onRedirect, className }) {
511
629
  /* @__PURE__ */ jsx(GhostButton, { type: "button", onClick: () => setMfa({ ...mfa, backup: !mfa.backup, code: "" }), children: mfa.backup ? "Use verification code" : "Use backup code" })
512
630
  ] }) : /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: [
513
631
  ctx.providers?.google ? /* @__PURE__ */ jsxs(Fragment2, { children: [
514
- /* @__PURE__ */ jsxs(GhostButton, { type: "button", onClick: startGoogleLogin, disabled: submitting, "aria-label": "Continue with Google", style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 10 }, children: [
632
+ /* @__PURE__ */ jsxs("button", { type: "button", className: "iqauth-sdk-google-btn", onClick: startGoogleLogin, disabled: submitting, "aria-label": ctx.branding?.googleButtonLabel || "Continue with Google", children: [
515
633
  /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 18 18", "aria-hidden": "true", children: [
516
634
  /* @__PURE__ */ jsx("path", { fill: "#4285F4", d: "M17.64 9.2c0-.64-.06-1.25-.17-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.71v2.26h2.92a8.78 8.78 0 0 0 2.68-6.61z" }),
517
635
  /* @__PURE__ */ jsx("path", { fill: "#34A853", d: "M9 18c2.43 0 4.47-.81 5.96-2.18l-2.92-2.26a5.4 5.4 0 0 1-8.04-2.83H.96v2.33A9 9 0 0 0 9 18z" }),
518
636
  /* @__PURE__ */ jsx("path", { fill: "#FBBC05", d: "M3.96 10.71A5.41 5.41 0 0 1 3.68 9c0-.59.1-1.17.29-1.71V4.96H.96a9 9 0 0 0 0 8.08l3-2.33z" }),
519
637
  /* @__PURE__ */ jsx("path", { fill: "#EA4335", d: "M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.59A9 9 0 0 0 .96 4.96l3 2.33A5.4 5.4 0 0 1 9 3.58z" })
520
638
  ] }),
521
- "Continue with Google"
639
+ ctx.branding?.googleButtonLabel || "Continue with Google"
522
640
  ] }),
523
- /* @__PURE__ */ jsxs("div", { role: "separator", "aria-label": "or", style: { display: "flex", alignItems: "center", gap: 10, fontSize: 12, opacity: 0.6 }, children: [
524
- /* @__PURE__ */ jsx("span", { style: { flex: 1, height: 1, background: "rgba(15,23,42,0.12)" } }),
525
- "OR",
526
- /* @__PURE__ */ jsx("span", { style: { flex: 1, height: 1, background: "rgba(15,23,42,0.12)" } })
527
- ] })
641
+ /* @__PURE__ */ jsx("div", { role: "separator", "aria-label": "or", className: "iqauth-sdk-divider", children: "OR" })
528
642
  ] }) : null,
529
643
  /* @__PURE__ */ jsxs("form", { onSubmit: submitLogin, style: { display: "flex", flexDirection: "column", gap: 12 }, "aria-label": `Sign in to ${ctx.app.name}`, children: [
530
644
  /* @__PURE__ */ jsx(Field, { label: "Email", children: /* @__PURE__ */ jsx("input", { style: inputStyle(), type: "email", autoComplete: "email", required: true, value: email, onChange: (e) => setEmail(e.target.value) }) }),
package/dist/server.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { b as IQAuthTokenClientConfig, N as ExpressMiddlewareOptions, Q as IQAuthRequestLike, R as IQAuthResponseLike, V as IQAuthNextFunction } from './types-Cxl3bQHt.mjs';
2
- import { I as IQAuthClient } from './client-C1DXfB8Z.mjs';
2
+ import { I as IQAuthClient } from './client-Dv4v92Mj.mjs';
3
3
  export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.mjs';
4
- export { C as CookieAwareMiddlewareOptions, D as DEFAULT_ACCESS_COOKIE, a as DEFAULT_REFRESH_COOKIE, i as iqAuthMiddleware } from './express-CpfyYTmw.mjs';
4
+ export { C as CookieAwareMiddlewareOptions, D as DEFAULT_ACCESS_COOKIE, a as DEFAULT_REFRESH_COOKIE, i as iqAuthMiddleware } from './express-BZmF1llh.mjs';
5
5
  export { HandlerResponse, IQAuthHelperConfig, SetCookieDirective, handleCallback, handleRefresh, handleSignout, serializeCookie } from './server/handlers.mjs';
6
6
  import 'jsonwebtoken';
7
7
 
package/dist/server.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { b as IQAuthTokenClientConfig, N as ExpressMiddlewareOptions, Q as IQAuthRequestLike, R as IQAuthResponseLike, V as IQAuthNextFunction } from './types-Cxl3bQHt.js';
2
- import { I as IQAuthClient } from './client-CggvJmmm.js';
2
+ import { I as IQAuthClient } from './client-DXbHb2ul.js';
3
3
  export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.js';
4
- export { C as CookieAwareMiddlewareOptions, D as DEFAULT_ACCESS_COOKIE, a as DEFAULT_REFRESH_COOKIE, i as iqAuthMiddleware } from './express-BKAXB5Nl.js';
4
+ export { C as CookieAwareMiddlewareOptions, D as DEFAULT_ACCESS_COOKIE, a as DEFAULT_REFRESH_COOKIE, i as iqAuthMiddleware } from './express-B4o3P8vK.js';
5
5
  export { HandlerResponse, IQAuthHelperConfig, SetCookieDirective, handleCallback, handleRefresh, handleSignout, serializeCookie } from './server/handlers.js';
6
6
  import 'jsonwebtoken';
7
7
 
package/dist/server.js CHANGED
@@ -456,7 +456,10 @@ function parseMfaResponse(data, browserSessionMode) {
456
456
  var import_crypto = __toESM(require("crypto"));
457
457
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
458
458
  var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
459
- var DEFAULT_TOKEN_ISSUER = "auth.dispositioniq.com";
459
+ var DEFAULT_TOKEN_ISSUER = [
460
+ "https://auth.dispositioniq.com",
461
+ "auth.dispositioniq.com"
462
+ ];
460
463
  var DEFAULT_TOKEN_AUDIENCE = [
461
464
  "dispositioniq",
462
465
  "iqcapture",
package/dist/server.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  DEFAULT_ACCESS_COOKIE,
3
3
  DEFAULT_REFRESH_COOKIE,
4
4
  iqAuthMiddleware
5
- } from "./chunk-73R6BEGO.mjs";
5
+ } from "./chunk-ZESHDJDU.mjs";
6
6
  import {
7
7
  handleCallback,
8
8
  handleRefresh,
@@ -12,7 +12,7 @@ import {
12
12
  import "./chunk-5WFR6Y33.mjs";
13
13
  import {
14
14
  IQAuthClient
15
- } from "./chunk-JQWYIIIS.mjs";
15
+ } from "./chunk-MDUHPQMM.mjs";
16
16
  import {
17
17
  ErrorCodes,
18
18
  IQAuthError
@@ -1,4 +1,4 @@
1
- import { I as IQAuthClient } from './client-C1DXfB8Z.mjs';
1
+ import { I as IQAuthClient } from './client-Dv4v92Mj.mjs';
2
2
  import { b as IQAuthTokenClientConfig } from './types-Cxl3bQHt.mjs';
3
3
  export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.mjs';
4
4
  import 'jsonwebtoken';
package/dist/service.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { I as IQAuthClient } from './client-CggvJmmm.js';
1
+ import { I as IQAuthClient } from './client-DXbHb2ul.js';
2
2
  import { b as IQAuthTokenClientConfig } from './types-Cxl3bQHt.js';
3
3
  export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.js';
4
4
  import 'jsonwebtoken';
package/dist/service.js CHANGED
@@ -449,7 +449,10 @@ function parseMfaResponse(data, browserSessionMode) {
449
449
  var import_crypto = __toESM(require("crypto"));
450
450
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
451
451
  var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
452
- var DEFAULT_TOKEN_ISSUER = "auth.dispositioniq.com";
452
+ var DEFAULT_TOKEN_ISSUER = [
453
+ "https://auth.dispositioniq.com",
454
+ "auth.dispositioniq.com"
455
+ ];
453
456
  var DEFAULT_TOKEN_AUDIENCE = [
454
457
  "dispositioniq",
455
458
  "iqcapture",
package/dist/service.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  IQAuthClient
3
- } from "./chunk-JQWYIIIS.mjs";
3
+ } from "./chunk-MDUHPQMM.mjs";
4
4
  import {
5
5
  ErrorCodes,
6
6
  IQAuthError
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iqauth/sdk",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "description": "TypeScript SDK for IQAuth — the canonical way for all IQ projects to integrate with IQAuthService",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",