@orangecheck/me-client 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +36 -66
- package/dist/index.d.ts +36 -66
- package/dist/index.js +363 -140
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +361 -128
- package/dist/index.mjs.map +1 -1
- package/dist/popup.d.mts +22 -0
- package/dist/popup.d.ts +22 -0
- package/dist/popup.js +70 -0
- package/dist/popup.js.map +1 -0
- package/dist/popup.mjs +68 -0
- package/dist/popup.mjs.map +1 -0
- package/dist/server.d.mts +51 -0
- package/dist/server.d.ts +51 -0
- package/dist/server.js +73 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +65 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +29 -4
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/transport.ts","../src/session.ts","../src/SignInButton.tsx","../src/payment.ts","../src/types.ts","../src/config.ts","../src/webhook.ts","../src/delegation.ts","../src/event.ts","../src/index.ts"],"names":["event"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Tiny HTTP transport layer. The me.ochk.io origin is configurable so\n * staging deployments and self-hosted me-equivalents can swap it.\n */\n\nlet origin = 'https://me.ochk.io';\n\nexport function setOrigin(url: string): void {\n origin = url.replace(/\\/$/, '');\n}\n\nexport function getOrigin(): string {\n return origin;\n}\n\nexport interface FetchOptions {\n method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';\n body?: unknown;\n signal?: AbortSignal;\n}\n\nexport async function api<T>(path: string, opts: FetchOptions = {}): Promise<T> {\n const res = await fetch(`${origin}${path}`, {\n method: opts.method ?? 'GET',\n credentials: 'include',\n headers: { 'content-type': 'application/json', accept: 'application/json' },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: opts.signal,\n });\n if (!res.ok) {\n let message = `me.ochk.io ${res.status}`;\n try {\n const data = (await res.json()) as { error?: string };\n if (data?.error) message = data.error;\n } catch {\n /* ignore */\n }\n throw new MeClientError(message, res.status);\n }\n return (await res.json()) as T;\n}\n\nexport class MeClientError extends Error {\n public readonly status: number;\n constructor(message: string, status: number) {\n super(message);\n this.name = 'MeClientError';\n this.status = status;\n }\n}\n","import type { Session, SessionPolicy, SignInOptions, TelemetryEvent } from './types';\n\nimport { api } from './transport';\n\nconst DEFAULT_POLICY: SessionPolicy = {\n duration_seconds: 7 * 24 * 60 * 60, // 7 days, standard SaaS shape\n refresh: 'sliding',\n sensitive_actions: 're-auth',\n};\n\nconst telemetrySubscribers = new Set<(e: TelemetryEvent) => void>();\n\n/** Subscribe to non-billable developer telemetry events. Call the returned\n * function to unsubscribe. */\nexport function onTelemetry(listener: (e: TelemetryEvent) => void): () => void {\n telemetrySubscribers.add(listener);\n return () => {\n telemetrySubscribers.delete(listener);\n };\n}\n\nfunction emitTelemetry(code: TelemetryEvent['code'], session_id?: string): void {\n const e: TelemetryEvent = {\n code,\n timestamp: new Date().toISOString(),\n ...(session_id ? { session_id } : {}),\n };\n for (const fn of telemetrySubscribers) {\n try {\n fn(e);\n } catch {\n /* listener errors must not break the session flow */\n }\n }\n}\n\n/**\n * Open a sign-in flow at me.ochk.io. Returns the resulting Session once\n * the user consents (Class C billable event for the integrating site,\n * cashback for the user). Internally this opens the OC consent UI in a\n * popup; v1 implementations may also redirect.\n */\nasync function create(opts: SignInOptions): Promise<Session> {\n const policy: SessionPolicy = { ...DEFAULT_POLICY, ...(opts.sessionPolicy ?? {}) };\n return api<Session>('/api/session/create', {\n method: 'POST',\n body: {\n scope: opts.scope,\n policy,\n return_to:\n opts.returnTo ?? (typeof window !== 'undefined' ? window.location.href : undefined),\n ...(opts.project_key ? { project_key: opts.project_key } : {}),\n },\n });\n}\n\n/**\n * Refresh a still-valid session inside its policy window. Free for the\n * integrating site (does NOT instantiate a billable event); emits a\n * `session.token_refresh` telemetry record.\n */\nasync function refresh(sessionId: string): Promise<Session> {\n emitTelemetry('session.token_refresh', sessionId);\n return api<Session>('/api/session/refresh', {\n method: 'POST',\n body: { session_id: sessionId },\n });\n}\n\n/** Invalidate a session. Free, telemetry-only. */\nasync function invalidate(sessionId: string): Promise<void> {\n emitTelemetry('session.intra_signin', sessionId);\n await api<{ ok: true }>('/api/session/invalidate', {\n method: 'POST',\n body: { session_id: sessionId },\n });\n}\n\nexport const session = { create, refresh, invalidate };\n","import * as React from 'react';\n\nimport { session } from './session';\nimport type { Session, SessionPolicy } from './types';\n\nexport interface OcSignInButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onError'> {\n scope: string[];\n sessionPolicy?: Partial<SessionPolicy>;\n returnTo?: string;\n onSignin?: (session: Session) => void;\n /** Called when the sign-in flow fails. Renamed from `onError` to avoid\n * shadowing the native button error handler. */\n onSignInError?: (error: Error) => void;\n /** Custom button text. Defaults to \"sign in with oc\". */\n label?: string;\n}\n\n/**\n * Drop-in Sign-in-with-OC button. Triggers the me.ochk.io consent flow\n * for the requested scope, opens (or refreshes) a session, and calls\n * onSignin(session) on success. Class C billable event for the\n * integrating site; cashback flows to the user.\n *\n * Mounting requires <OcSessionProvider> from @orangecheck/auth-client\n * somewhere up the React tree so the resulting session can be read by\n * useOcSession() across the rest of the app.\n */\nexport function OcSignInButton({\n scope,\n sessionPolicy,\n returnTo,\n onSignin,\n onSignInError,\n label = 'sign in with oc',\n children,\n onClick,\n style,\n ...rest\n}: OcSignInButtonProps) {\n const [pending, setPending] = React.useState(false);\n\n return (\n <button\n type=\"button\"\n onClick={async (event) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n setPending(true);\n try {\n const result = await session.create({ scope, sessionPolicy, returnTo });\n onSignin?.(result);\n } catch (err) {\n onSignInError?.(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setPending(false);\n }\n }}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n padding: '10px 16px',\n fontSize: 13,\n fontWeight: 600,\n fontFamily: 'ui-monospace, \"JetBrains Mono\", \"SF Mono\", Menlo, monospace',\n letterSpacing: '0.18em',\n textTransform: 'uppercase',\n background: '#f97316',\n color: '#0b0909',\n border: '1px solid #f97316',\n borderRadius: 4,\n cursor: pending ? 'progress' : 'pointer',\n opacity: pending ? 0.7 : 1,\n ...(style ?? {}),\n }}\n disabled={pending || rest.disabled}\n data-oc-signin\n {...rest}\n >\n {/* compact OC mark */}\n <span\n aria-hidden\n style={{\n display: 'inline-block',\n width: 12,\n height: 12,\n background: '#0b0909',\n }}\n />\n {children ?? (pending ? 'opening…' : label)}\n </button>\n );\n}\n","import type { PaymentAuthorizeOptions, PaymentResult } from './types';\n\nimport { api } from './transport';\n\n/**\n * Authorize a payment through the user's OC identity. Class B billable\n * event for the integrating site (sub-Stripe rate, percentage-based);\n * cashback flows to the user as Lightning credit on /me/earn.\n *\n * The user is prompted by me.ochk.io to consent to the specific payment\n * before this resolves. If the user declines or cancels, the result has\n * status `'cancelled'`, a non-billable telemetry record is emitted, and\n * NO billable event is created.\n */\nasync function authorize(opts: PaymentAuthorizeOptions): Promise<PaymentResult> {\n if (opts.amount_sats == null && opts.usd_cents == null) {\n throw new Error('payment.authorize requires amount_sats or usd_cents');\n }\n return api<PaymentResult>('/api/payment/authorize', {\n method: 'POST',\n body: opts,\n });\n}\n\nexport const payment = { authorize };\n","/**\n * Canonical types for me.ochk.io integrators.\n *\n * Mirrors the source of truth at oc-me-web/src/lib/events/types.ts. Two\n * layers:\n * - Platform-level (PLATFORM_FEE_POLICY, MIN_INTEGRATOR_PRICE_SATS) —\n * fixed by OC, surfaced as constants here so integrators can validate\n * their config client-side before posting it.\n * - Integrator-level (IntegratorPriceConfig) — every integrator declares\n * their own per-event prices and user-share splits.\n *\n * Per Addendum 01: every chargeable event is in exactly one of three\n * classes. Sites pay for sessions and actions, not for clicks. Free\n * events never instantiate a BillableEvent.\n */\n\n// ── platform constants (fixed by OC) ──────────────────────────────────────\n\nexport const PLATFORM_FEE_POLICY = {\n /** Fraction of every gross_fee that OC retains. */\n pct: 0.2,\n /** Absolute minimum platform fee, in sats. */\n min_floor_sats: 1,\n /** Date this policy was last ratified. Changes require an oc-me-protocol PR. */\n ratified: '2026-04-30',\n} as const;\n\n/** Anti-spam price floor. No integrator can configure a per-event price\n * below this. */\nexport const MIN_INTEGRATOR_PRICE_SATS = 5;\n\n// ── event taxonomy ────────────────────────────────────────────────────────\n\nexport type EventClass = 'A' | 'B' | 'C';\n\nexport type ClassASubtype =\n | 'account_creation'\n | 'account_recovery'\n | 'kyc_tier_upgrade'\n | 'payment_method_connected'\n | 'agent_delegation_issued'\n | 'recovery_method_updated';\n\nexport type ClassBSubtype =\n | 'payment_authorization'\n | 'scoped_action_authorization'\n | 'attest_verification_at_gate'\n | 'stamp_signing'\n | 'pledge_resolution';\n\nexport type ClassCSubtype = 'session_creation';\n\nexport type EventSubtype = ClassASubtype | ClassBSubtype | ClassCSubtype;\n\nexport type AttestTier = 'anonymous' | 'bonded' | 'kyc_light' | 'kyc_strong';\n\n/** The shape of a per-event fee — either a fixed sats amount or a percent\n * of the underlying transaction amount (used for payments + pledges). */\nexport type SiteFeeShape =\n | { kind: 'fixed_sats'; sats: number }\n | { kind: 'percent_of_amount'; pct: number };\n\n/** What an integrator declares for a single event subtype. */\nexport interface IntegratorEventConfig {\n /** Whether this site bills this event subtype at all. */\n enabled: boolean;\n /** The per-event fee the site pays. */\n site_pays: SiteFeeShape;\n /** Fraction of post-platform-fee that flows to the user (0–0.8 since\n * platform_fee is 20%). The remainder is a rebate to the site's OC\n * project balance. */\n user_share_pct: number;\n}\n\n/** A complete integrator pricing config. Posted to me.ochk.io once at\n * integration time, mutable via the configurator UI or this SDK any time\n * after. */\nexport interface IntegratorPriceConfig {\n project_key: string;\n display_name: string;\n domain: string;\n /** ISO-8601 timestamp the config was last updated. */\n updated_at: string;\n /** Per-subtype configs. Subtypes not listed are disabled by default. */\n events: Partial<Record<EventSubtype, IntegratorEventConfig>>;\n}\n\n/** A computed fee breakdown for a single event. site_rebate_sats is what\n * flows back to the integrator's OC balance after OC's platform fee and\n * the user's cashback. */\nexport interface ComputedFees {\n gross_fee_sats: number;\n platform_fee_sats: number;\n user_earned_sats: number;\n site_rebate_sats: number;\n}\n\n/** Compute the four-way fee split for an event given an integrator's\n * config and (for percent_of_amount events) the underlying payment\n * amount.\n *\n * Invariants (verified by tests in oc-me-web/src/lib/events/types.test.ts):\n * 1. gross_fee_sats >= MIN_INTEGRATOR_PRICE_SATS\n * 2. platform_fee_sats >= PLATFORM_FEE_POLICY.min_floor_sats\n * 3. user_share_pct is clamped to [0, 0.8]\n * 4. site_rebate_sats >= 0\n * 5. gross == platform + user + rebate (exact, modulo rounding into rebate)\n */\nexport function computeFees(\n cfg: IntegratorEventConfig,\n payment_amount_sats?: number\n): ComputedFees {\n let gross = 0;\n if (cfg.site_pays.kind === 'fixed_sats') {\n gross = Math.max(MIN_INTEGRATOR_PRICE_SATS, Math.round(cfg.site_pays.sats));\n } else {\n if (payment_amount_sats == null) {\n throw new Error('percent_of_amount config requires payment_amount_sats');\n }\n gross = Math.max(\n MIN_INTEGRATOR_PRICE_SATS,\n Math.round(payment_amount_sats * cfg.site_pays.pct)\n );\n }\n const platform_fee_sats = Math.max(\n PLATFORM_FEE_POLICY.min_floor_sats,\n Math.round(gross * PLATFORM_FEE_POLICY.pct)\n );\n const user_share = Math.min(0.8, Math.max(0, cfg.user_share_pct));\n const user_earned_sats = Math.round(gross * user_share);\n const site_rebate_sats = Math.max(0, gross - platform_fee_sats - user_earned_sats);\n return { gross_fee_sats: gross, platform_fee_sats, user_earned_sats, site_rebate_sats };\n}\n\n/** Result of validating an IntegratorPriceConfig. */\nexport interface ValidationResult {\n ok: boolean;\n errors: { subtype?: EventSubtype; message: string }[];\n}\n\n/**\n * Validate an integrator's pricing config against the platform's\n * non-negotiable rules. Run client-side before posting; the server runs\n * the same checks and rejects anything that fails.\n */\nexport function validateIntegratorConfig(cfg: IntegratorPriceConfig): ValidationResult {\n const errors: ValidationResult['errors'] = [];\n\n if (!cfg.project_key) errors.push({ message: 'project_key is required' });\n if (!cfg.display_name) errors.push({ message: 'display_name is required' });\n if (!cfg.domain) errors.push({ message: 'domain is required' });\n\n for (const [key, eventCfg] of Object.entries(cfg.events)) {\n if (!eventCfg) continue;\n const subtype = key as EventSubtype;\n if (!eventCfg.enabled) continue;\n\n if (eventCfg.site_pays.kind === 'fixed_sats') {\n if (eventCfg.site_pays.sats < MIN_INTEGRATOR_PRICE_SATS) {\n errors.push({\n subtype,\n message: `site_pays.sats (${eventCfg.site_pays.sats}) is below MIN_INTEGRATOR_PRICE_SATS (${MIN_INTEGRATOR_PRICE_SATS})`,\n });\n }\n } else {\n const pct = eventCfg.site_pays.pct;\n if (!(pct > 0 && pct <= 1)) {\n errors.push({\n subtype,\n message: `site_pays.pct (${pct}) must be in (0, 1]`,\n });\n }\n }\n\n const u = eventCfg.user_share_pct;\n if (u < 0 || u > 0.8) {\n errors.push({\n subtype,\n message: `user_share_pct (${u}) must be in [0, 0.8]; max is 0.8 because platform_fee is ${PLATFORM_FEE_POLICY.pct}`,\n });\n }\n }\n\n return { ok: errors.length === 0, errors };\n}\n\n// ── canonical envelope ────────────────────────────────────────────────────\n\nexport interface BillableEvent {\n id: string;\n occurred_at: string;\n class: EventClass;\n subtype: EventSubtype;\n site: { domain: string; display_name: string };\n gross_fee_sats: number;\n platform_fee_sats: number;\n user_earned_sats: number;\n site_rebate_sats: number;\n verify_url: string;\n}\n\n// ── session lifecycle ────────────────────────────────────────────────────\n\nexport interface SessionPolicy {\n duration_seconds: number;\n refresh: 'sliding' | 'rolling' | 'none';\n sensitive_actions?: 're-auth' | 'none';\n}\n\nexport interface Session {\n id: string;\n identity: string;\n opens_at: string;\n expires_at: string;\n policy: SessionPolicy;\n scope: string[];\n}\n\nexport interface SignInOptions {\n scope: string[];\n sessionPolicy?: Partial<SessionPolicy>;\n returnTo?: string;\n /** Project this session is opened under. When omitted, the session\n * is created as a free telemetry record (not billable). When set,\n * OC records a Class C billable envelope under the project's\n * IntegratorPriceConfig and credits cashback to the user. */\n project_key?: string;\n}\n\nexport interface PaymentAuthorizeOptions {\n identity: string;\n amount_sats?: number;\n usd_cents?: number;\n description: string;\n external_ref?: string;\n /** Project this payment is authorized under. Required for the\n * envelope to be attributed to your project's billing. */\n project_key?: string;\n}\n\nexport interface PaymentResult {\n id: string;\n status: 'authorized' | 'failed' | 'cancelled';\n sats_charged?: number;\n user_envelope_id?: string;\n verify_url?: string;\n}\n\nexport interface TelemetryEvent {\n code:\n | 'session.intra_signin'\n | 'session.token_refresh'\n | 'session.navigation'\n | 'auth.signin_failed'\n | 'auth.signin_cancelled'\n | 'auth.signin_rejected'\n | 'verify.passive_check';\n timestamp: string;\n session_id?: string;\n}\n","import type { IntegratorPriceConfig, ValidationResult } from './types';\n\nimport { validateIntegratorConfig } from './types';\nimport { api } from './transport';\n\n/**\n * Read the integrator's currently-stored IntegratorPriceConfig from\n * me.ochk.io. The endpoint reads from the federation index in production;\n * in v1 it returns the project's last-stored config from the in-memory\n * store keyed on the authenticated project_key.\n */\nasync function get(): Promise<IntegratorPriceConfig> {\n return api<IntegratorPriceConfig>('/api/developer/config', { method: 'GET' });\n}\n\n/**\n * Persist a new IntegratorPriceConfig. Validates client-side first so the\n * caller gets a structured error before a round trip; the server runs the\n * same validator and rejects with 422 + a list of offending subtypes if\n * anything slipped past.\n *\n * Throws an Error containing the validation report if the config is\n * invalid client-side. Throws MeClientError on server rejection.\n */\nasync function update(cfg: IntegratorPriceConfig): Promise<IntegratorPriceConfig> {\n const result = validateIntegratorConfig(cfg);\n if (!result.ok) {\n const summary = result.errors\n .map((e) => (e.subtype ? `${e.subtype}: ${e.message}` : e.message))\n .join('; ');\n throw new Error(`IntegratorPriceConfig invalid · ${summary}`);\n }\n return api<IntegratorPriceConfig>('/api/developer/config', {\n method: 'POST',\n body: cfg,\n });\n}\n\n/** Run the validator without making a network call. Useful for live\n * feedback in a dashboard form. */\nfunction validate(cfg: IntegratorPriceConfig): ValidationResult {\n return validateIntegratorConfig(cfg);\n}\n\nexport const config = { get, update, validate };\n","import { ed25519 } from '@noble/curves/ed25519';\nimport { sha256 } from '@noble/hashes/sha256';\n\n/**\n * Public Ed25519 JWK published at ochk.io/.well-known/jwks.json. Webhook\n * verification uses the key matching the OC-Key-Id header.\n */\nexport interface OcPublicJwk {\n kty: 'OKP';\n crv: 'Ed25519';\n x: string;\n kid: string;\n alg?: string;\n use?: string;\n}\n\nexport interface VerifyResult {\n ok: boolean;\n /** Reason verification failed. Undefined when ok is true. */\n reason?: string;\n /** kid that was matched (or attempted). */\n key_id?: string;\n}\n\nconst FAMILY_JWKS_URL = 'https://ochk.io/.well-known/jwks.json';\n\nlet cachedJwks: { fetched_at: number; keys: OcPublicJwk[] } | null = null;\nconst JWKS_TTL_MS = 60 * 60 * 1000;\n\n/** Fetch (and short-cache) the OC public JWKS. */\nasync function fetchJwks(): Promise<OcPublicJwk[]> {\n if (cachedJwks && Date.now() - cachedJwks.fetched_at < JWKS_TTL_MS) {\n return cachedJwks.keys;\n }\n const res = await fetch(FAMILY_JWKS_URL, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n });\n if (!res.ok) {\n throw new Error(`failed to fetch JWKS: ${res.status} ${res.statusText}`);\n }\n const data = (await res.json()) as { keys: OcPublicJwk[] };\n cachedJwks = { fetched_at: Date.now(), keys: data.keys };\n return data.keys;\n}\n\nfunction base64urlDecode(input: string): Uint8Array {\n const padded = input.replace(/-/g, '+').replace(/_/g, '/').padEnd(\n Math.ceil(input.length / 4) * 4,\n '='\n );\n const bin =\n typeof atob === 'function'\n ? atob(padded)\n : Buffer.from(padded, 'base64').toString('binary');\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nfunction hexDecode(input: string): Uint8Array {\n const clean = input.toLowerCase().replace(/^0x/, '');\n if (clean.length % 2 !== 0) throw new Error('hex string has odd length');\n const out = new Uint8Array(clean.length / 2);\n for (let i = 0; i < out.length; i++) {\n out[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n }\n return out;\n}\n\n/**\n * Verify a webhook signature against the raw request body. The signature\n * is hex-encoded in the OC-Signature header; the kid is in OC-Key-Id.\n *\n * NOTE: pass the *raw* body bytes (not the parsed JSON). Frameworks that\n * re-serialize before your handler runs produce a different byte sequence\n * and verification will fail. In Express set\n * app.use(express.text({ type: '*\\/*' }));\n * In Next.js Pages API routes set\n * export const config = { api: { bodyParser: false } };\n *\n * If `jwk` is omitted the function fetches and caches OC's published JWKS\n * for an hour. Pre-fetching once on boot and passing the matching JWK\n * here is the recommended hot path.\n */\nexport async function verify(\n rawBody: string | Uint8Array,\n sigHex: string,\n kid: string,\n jwk?: OcPublicJwk\n): Promise<VerifyResult> {\n let key = jwk;\n if (!key || key.kid !== kid) {\n const keys = await fetchJwks();\n key = keys.find((k) => k.kid === kid);\n if (!key) {\n return { ok: false, reason: `no JWK with kid=${kid} in published JWKS`, key_id: kid };\n }\n }\n if (key.kty !== 'OKP' || key.crv !== 'Ed25519') {\n return { ok: false, reason: `JWK kid=${kid} is not Ed25519`, key_id: kid };\n }\n\n let pubKey: Uint8Array;\n try {\n pubKey = base64urlDecode(key.x);\n } catch (err) {\n return {\n ok: false,\n reason: `failed to decode JWK x: ${(err as Error).message}`,\n key_id: kid,\n };\n }\n if (pubKey.length !== 32) {\n return {\n ok: false,\n reason: `Ed25519 public key must be 32 bytes; got ${pubKey.length}`,\n key_id: kid,\n };\n }\n\n let sig: Uint8Array;\n try {\n sig = hexDecode(sigHex);\n } catch (err) {\n return {\n ok: false,\n reason: `failed to decode signature: ${(err as Error).message}`,\n key_id: kid,\n };\n }\n if (sig.length !== 64) {\n return {\n ok: false,\n reason: `Ed25519 signature must be 64 bytes; got ${sig.length}`,\n key_id: kid,\n };\n }\n\n const bodyBytes =\n typeof rawBody === 'string' ? new TextEncoder().encode(rawBody) : rawBody;\n const hash = sha256(bodyBytes);\n\n try {\n const ok = ed25519.verify(sig, hash, pubKey);\n return ok\n ? { ok: true, key_id: kid }\n : { ok: false, reason: 'signature does not match', key_id: kid };\n } catch (err) {\n return { ok: false, reason: (err as Error).message, key_id: kid };\n }\n}\n\nexport const webhook = { verify, fetchJwks };\n","import { api } from './transport';\n\n/** A scope token an agent delegation can carry. */\nexport type DelegationScope =\n | 'identity.read'\n | 'inbox.read'\n | 'attest.verify'\n | 'stamp.sign'\n | 'payment.authorize';\n\nexport interface IssueDelegationOptions {\n /** Agent identifier — usually the agent's own pubkey or DID. */\n agent_id: string;\n /** Scopes the agent is allowed to act on. */\n scope: DelegationScope[];\n /** ISO-8601 expiration timestamp. Max 30 days in the future. */\n expires_at: string;\n /** Optional human-readable reason shown in /me/agents. */\n reason?: string;\n}\n\nexport interface DelegationEnvelope {\n /** Content-addressed envelope id. */\n id: string;\n /** Scope tokens the agent is allowed. */\n scope: DelegationScope[];\n /** ISO-8601 expiration. */\n expires_at: string;\n /** ISO-8601 issuance time. */\n issued_at: string;\n /** Public verifier URL. */\n verify_url: string;\n}\n\n/**\n * Issue an agent delegation. Class A billable event for the integrating\n * site that initiates it (the user authorizes from /me/agents).\n *\n * v1: returns a stub envelope until the federation signing service ships.\n * The shape is canonical and matches what production will return.\n */\nasync function issue(opts: IssueDelegationOptions): Promise<DelegationEnvelope> {\n if (!opts.agent_id) throw new Error('agent_id is required');\n if (!opts.scope?.length) throw new Error('scope must contain at least one token');\n if (!opts.expires_at) throw new Error('expires_at is required');\n return api<DelegationEnvelope>('/api/delegation/issue', {\n method: 'POST',\n body: opts,\n });\n}\n\n/** Revoke a previously-issued delegation by envelope id. Verifier rejects\n * any envelope signed under the delegation after revocation. */\nasync function revoke(delegation_id: string): Promise<{ ok: true }> {\n return api<{ ok: true }>('/api/delegation/revoke', {\n method: 'POST',\n body: { delegation_id },\n });\n}\n\nexport const delegation = { issue, revoke };\n","import type { BillableEvent, EventSubtype } from './types';\n\nimport { api } from './transport';\n\nexport interface FireEventOptions {\n project_key: string;\n subtype: EventSubtype;\n /** Required for percent_of_amount-priced subtypes. */\n payment_amount_sats?: number;\n action_label?: string;\n note?: string;\n}\n\n/**\n * Fire any billable envelope under a project_key. Most integrations\n * use the higher-level helpers (oc.session.create, oc.payment.authorize),\n * but this lets you record any subtype your IntegratorPriceConfig\n * enables — stamp_signing, attest_verification_at_gate,\n * scoped_action_authorization, kyc_tier_upgrade, etc.\n *\n * Returns the canonical BillableEvent the server recorded.\n */\nasync function fire(opts: FireEventOptions): Promise<BillableEvent> {\n const result = await api<{ event: BillableEvent }>('/api/integrator/event', {\n method: 'POST',\n body: opts,\n });\n return result.event;\n}\n\nexport const event = { fire };\n","/**\n * @orangecheck/me-client\n *\n * Drop-in client for me.ochk.io. Exports the canonical billable-event\n * taxonomy as TypeScript types, session lifecycle hooks, payment\n * authorization, integrator-config CRUD, agent-delegation issue/revoke,\n * webhook signature verification, the developer telemetry stream, and\n * the React sign-in button + `useOcSession` hook.\n *\n * Sign-in-with-OC. You pay for sessions and actions, not for clicks.\n */\n\nexport { OcSignInButton } from './SignInButton';\nexport type { OcSignInButtonProps } from './SignInButton';\n\n// Re-export the React session primitives so integrators can pull every\n// auth surface from a single package.\nexport { OcSessionProvider, useOcSession, useOptionalOcSession } from '@orangecheck/auth-client';\nexport type {\n OcAccount,\n OcSessionState,\n OcSessionStatus,\n OcAuthConfig,\n} from '@orangecheck/auth-client';\n\nexport { session, onTelemetry } from './session';\nexport { payment } from './payment';\nexport { config } from './config';\nexport { webhook } from './webhook';\nexport type { OcPublicJwk, VerifyResult } from './webhook';\nexport { delegation } from './delegation';\nexport type { DelegationScope, DelegationEnvelope, IssueDelegationOptions } from './delegation';\nexport { event } from './event';\nexport type { FireEventOptions } from './event';\nexport { setOrigin, getOrigin, MeClientError } from './transport';\n\nexport {\n PLATFORM_FEE_POLICY,\n MIN_INTEGRATOR_PRICE_SATS,\n computeFees,\n validateIntegratorConfig,\n} from './types';\n\nexport type {\n EventClass,\n EventSubtype,\n ClassASubtype,\n ClassBSubtype,\n ClassCSubtype,\n AttestTier,\n SiteFeeShape,\n IntegratorEventConfig,\n IntegratorPriceConfig,\n ComputedFees,\n ValidationResult,\n BillableEvent,\n Session,\n SessionPolicy,\n SignInOptions,\n PaymentAuthorizeOptions,\n PaymentResult,\n TelemetryEvent,\n} from './types';\n\nimport { session } from './session';\nimport { payment } from './payment';\nimport { config } from './config';\nimport { webhook } from './webhook';\nimport { delegation } from './delegation';\nimport { event } from './event';\n\n/** Convenience namespace mirroring the public API surface in /integrate\n * code samples — `oc.session.create()`, `oc.payment.authorize()`,\n * `oc.config.update()`, `oc.webhook.verify()`, `oc.delegation.issue()`,\n * `oc.event.fire()`. */\nexport const oc = { session, payment, config, webhook, delegation, event };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/transport.ts","../src/session.ts","../src/SignInButton.tsx","../src/payment.ts","../src/event.ts","../src/types.ts","../src/config.ts","../node_modules/jose/dist/webapi/lib/buffer_utils.js","../node_modules/jose/dist/webapi/lib/base64.js","../node_modules/jose/dist/webapi/util/base64url.js","../node_modules/jose/dist/webapi/util/errors.js","../node_modules/jose/dist/webapi/lib/type_checks.js","../node_modules/jose/dist/webapi/lib/jwk_to_key.js","../node_modules/jose/dist/webapi/key/import.js","../src/webhook.ts","../src/index.ts"],"names":["event"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Tiny HTTP transport layer. The me.ochk.io origin is configurable so\n * staging deployments and self-hosted me-equivalents can swap it.\n *\n * Two auth paths, picked transparently:\n * - Same-origin / family integrators (*.ochk.io): the browser ships\n * the `oc_session` cookie automatically because we set\n * `credentials: 'include'`. Nothing to configure.\n * - Cross-domain integrators: after popup signin, call\n * `setBearerToken(result.token)` once. Subsequent SDK calls add\n * `Authorization: Bearer <token>`. Cookies still ride too — the\n * server accepts whichever arrives.\n */\n\nlet origin = 'https://me.ochk.io';\nlet bearerToken: string | null = null;\n\nexport function setOrigin(url: string): void {\n origin = url.replace(/\\/$/, '');\n}\n\nexport function getOrigin(): string {\n return origin;\n}\n\n/** Cross-domain integrators: store the JWT returned by `signInWithOc()`\n * here so subsequent SDK calls can authenticate via Authorization\n * header. Same-origin integrators don't need this (the cookie rides). */\nexport function setBearerToken(token: string | null): void {\n bearerToken = token && token.length > 0 ? token : null;\n}\n\nexport function getBearerToken(): string | null {\n return bearerToken;\n}\n\nexport function clearBearerToken(): void {\n bearerToken = null;\n}\n\nexport interface FetchOptions {\n method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';\n body?: unknown;\n signal?: AbortSignal;\n}\n\nexport async function api<T>(path: string, opts: FetchOptions = {}): Promise<T> {\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n accept: 'application/json',\n };\n if (bearerToken) headers['authorization'] = `Bearer ${bearerToken}`;\n const res = await fetch(`${origin}${path}`, {\n method: opts.method ?? 'GET',\n credentials: 'include',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: opts.signal,\n });\n if (!res.ok) {\n let message = `me.ochk.io ${res.status}`;\n try {\n const data = (await res.json()) as { error?: string };\n if (data?.error) message = data.error;\n } catch {\n /* ignore */\n }\n throw new MeClientError(message, res.status);\n }\n return (await res.json()) as T;\n}\n\nexport class MeClientError extends Error {\n public readonly status: number;\n constructor(message: string, status: number) {\n super(message);\n this.name = 'MeClientError';\n this.status = status;\n }\n}\n","import type { Session, SessionPolicy, SignInOptions, TelemetryEvent } from './types';\n\nimport { api } from './transport';\n\nconst DEFAULT_POLICY: SessionPolicy = {\n duration_seconds: 7 * 24 * 60 * 60, // 7 days, standard SaaS shape\n refresh: 'sliding',\n sensitive_actions: 're-auth',\n};\n\nconst telemetrySubscribers = new Set<(e: TelemetryEvent) => void>();\n\n/** Subscribe to non-billable developer telemetry events. Call the returned\n * function to unsubscribe. */\nexport function onTelemetry(listener: (e: TelemetryEvent) => void): () => void {\n telemetrySubscribers.add(listener);\n return () => {\n telemetrySubscribers.delete(listener);\n };\n}\n\nfunction emitTelemetry(code: TelemetryEvent['code'], session_id?: string): void {\n const e: TelemetryEvent = {\n code,\n timestamp: new Date().toISOString(),\n ...(session_id ? { session_id } : {}),\n };\n for (const fn of telemetrySubscribers) {\n try {\n fn(e);\n } catch {\n /* listener errors must not break the session flow */\n }\n }\n}\n\n/**\n * Open a sign-in flow at me.ochk.io. Returns the resulting Session once\n * the user consents (Class C billable event for the integrating site,\n * cashback for the user). Internally this opens the OC consent UI in a\n * popup; v1 implementations may also redirect.\n */\nasync function create(opts: SignInOptions): Promise<Session> {\n const policy: SessionPolicy = { ...DEFAULT_POLICY, ...(opts.sessionPolicy ?? {}) };\n return api<Session>('/api/session/create', {\n method: 'POST',\n body: {\n scope: opts.scope,\n policy,\n return_to: opts.returnTo ?? (typeof window !== 'undefined' ? window.location.href : undefined),\n },\n });\n}\n\n/**\n * Refresh a still-valid session inside its policy window. Free for the\n * integrating site (does NOT instantiate a billable event); emits a\n * `session.token_refresh` telemetry record.\n */\nasync function refresh(sessionId: string): Promise<Session> {\n emitTelemetry('session.token_refresh', sessionId);\n return api<Session>('/api/session/refresh', {\n method: 'POST',\n body: { session_id: sessionId },\n });\n}\n\n/** Invalidate a session. Free, telemetry-only. */\nasync function invalidate(sessionId: string): Promise<void> {\n emitTelemetry('session.intra_signin', sessionId);\n await api<{ ok: true }>('/api/session/invalidate', {\n method: 'POST',\n body: { session_id: sessionId },\n });\n}\n\nexport const session = { create, refresh, invalidate };\n","import * as React from 'react';\n\nimport { session } from './session';\nimport type { Session, SessionPolicy } from './types';\n\nexport interface OcSignInButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onError'> {\n scope: string[];\n sessionPolicy?: Partial<SessionPolicy>;\n returnTo?: string;\n onSignin?: (session: Session) => void;\n /** Called when the sign-in flow fails. Renamed from `onError` to avoid\n * shadowing the native button error handler. */\n onSignInError?: (error: Error) => void;\n /** Custom button text. Defaults to \"sign in with oc\". */\n label?: string;\n}\n\n/**\n * Drop-in Sign-in-with-OC button. Triggers the me.ochk.io consent flow\n * for the requested scope, opens (or refreshes) a session, and calls\n * onSignin(session) on success. Class C billable event for the\n * integrating site; cashback flows to the user.\n *\n * Mounting requires <OcSessionProvider> from @orangecheck/auth-client\n * somewhere up the React tree so the resulting session can be read by\n * useOcSession() across the rest of the app.\n */\nexport function OcSignInButton({\n scope,\n sessionPolicy,\n returnTo,\n onSignin,\n onSignInError,\n label = 'sign in with oc',\n children,\n onClick,\n style,\n ...rest\n}: OcSignInButtonProps) {\n const [pending, setPending] = React.useState(false);\n\n return (\n <button\n type=\"button\"\n onClick={async (event) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n setPending(true);\n try {\n const result = await session.create({ scope, sessionPolicy, returnTo });\n onSignin?.(result);\n } catch (err) {\n onSignInError?.(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setPending(false);\n }\n }}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n padding: '10px 16px',\n fontSize: 13,\n fontWeight: 600,\n fontFamily: 'ui-monospace, \"JetBrains Mono\", \"SF Mono\", Menlo, monospace',\n letterSpacing: '0.18em',\n textTransform: 'uppercase',\n background: '#f97316',\n color: '#0b0909',\n border: '1px solid #f97316',\n borderRadius: 4,\n cursor: pending ? 'progress' : 'pointer',\n opacity: pending ? 0.7 : 1,\n ...(style ?? {}),\n }}\n disabled={pending || rest.disabled}\n data-oc-signin\n {...rest}\n >\n {/* compact OC mark */}\n <span\n aria-hidden\n style={{\n display: 'inline-block',\n width: 12,\n height: 12,\n background: '#0b0909',\n }}\n />\n {children ?? (pending ? 'opening…' : label)}\n </button>\n );\n}\n","import type { PaymentAuthorizeOptions, PaymentResult } from './types';\n\nimport { api } from './transport';\n\n/**\n * Authorize a payment through the user's OC identity. Class B billable\n * event for the integrating site (sub-Stripe rate, percentage-based);\n * cashback flows to the user as Lightning credit on /me/earn.\n *\n * The user is prompted by me.ochk.io to consent to the specific payment\n * before this resolves. If the user declines or cancels, the result has\n * status `'cancelled'`, a non-billable telemetry record is emitted, and\n * NO billable event is created.\n */\nasync function authorize(opts: PaymentAuthorizeOptions): Promise<PaymentResult> {\n if (opts.amount_sats == null && opts.usd_cents == null) {\n throw new Error('payment.authorize requires amount_sats or usd_cents');\n }\n return api<PaymentResult>('/api/payment/authorize', {\n method: 'POST',\n body: opts,\n });\n}\n\nexport const payment = { authorize };\n","/**\n * `oc.event.fire` — escape hatch for firing a billable envelope under\n * any subtype that isn't already covered by `oc.session.create` or\n * `oc.payment.authorize`. Useful for `stamp_signing`,\n * `attest_verification_at_gate`, `scoped_action_authorization`,\n * `kyc_tier_upgrade`, etc.\n *\n * import { oc } from '@orangecheck/me-client';\n *\n * const env = await oc.event.fire({\n * project_key: 'pk_live_yourcompany',\n * subtype: 'stamp_signing',\n * action_label: 'review · march invoice',\n * });\n * // env.id, env.gross_fee_sats, env.user_earned_sats, env.verify_url\n *\n * // For percent_of_amount-priced subtypes, include the underlying amount:\n * const verify = await oc.event.fire({\n * project_key: 'pk_live_yourcompany',\n * subtype: 'attest_verification_at_gate',\n * payment_amount_sats: 50_000,\n * });\n *\n * The class is determined by SUBTYPE_CLASS server-side; cashback is\n * computed via computeFees(); the envelope is recorded under the\n * project_key and shows up in /developer/projects/[id]/events.\n */\n\nimport type { BillableEvent, EventSubtype } from './types';\nimport { api } from './transport';\n\nexport interface FireEventOptions {\n /** Your project_key (e.g. `pk_live_yourcompany`). Required. */\n project_key: string;\n /** Canonical billable subtype. Class is inferred by the server. */\n subtype: EventSubtype;\n /** Human-readable action label that appears on the envelope.\n * Optional but encouraged — it's what the user sees in their\n * /me/earn ledger. */\n action_label?: string;\n /** For percent_of_amount-priced subtypes, the underlying amount\n * the fee is computed against. Required for those subtypes. */\n payment_amount_sats?: number;\n /** Override the user identity the envelope is credited to. Default\n * is the currently-authenticated user (cookie / Bearer). Pass\n * this only when firing on a user's behalf in a server-to-server\n * flow — the project must have an explicit allowlist. */\n user_address?: string;\n /** Free-form metadata stored on the envelope. Public — anyone who\n * GETs /api/envelope/<id> sees it. Don't put secrets here. */\n metadata?: Record<string, unknown>;\n}\n\nasync function fire(options: FireEventOptions): Promise<BillableEvent> {\n if (!options.project_key) {\n throw new Error('event.fire requires project_key');\n }\n if (!options.subtype) {\n throw new Error('event.fire requires subtype');\n }\n return api<BillableEvent>('/api/integrator/event', {\n method: 'POST',\n body: options,\n });\n}\n\nexport const event = { fire };\n","/**\n * Canonical types for me.ochk.io integrators.\n *\n * Mirrors the source of truth at oc-me-web/src/lib/events/types.ts. Two\n * layers:\n * - Platform-level (PLATFORM_FEE_POLICY, MIN_INTEGRATOR_PRICE_SATS) —\n * fixed by OC, surfaced as constants here so integrators can validate\n * their config client-side before posting it.\n * - Integrator-level (IntegratorPriceConfig) — every integrator declares\n * their own per-event prices and user-share splits.\n *\n * Per Addendum 01: every chargeable event is in exactly one of three\n * classes. Sites pay for sessions and actions, not for clicks. Free\n * events never instantiate a BillableEvent.\n */\n\n// ── platform constants (fixed by OC) ──────────────────────────────────────\n\nexport const PLATFORM_FEE_POLICY = {\n /** Fraction of every gross_fee that OC retains. */\n pct: 0.2,\n /** Absolute minimum platform fee, in sats. */\n min_floor_sats: 1,\n /** Date this policy was last ratified. Changes require a versioned\n * @orangecheck/me-client release. */\n ratified: '2026-04-30',\n} as const;\n\n/** Anti-spam price floor. No integrator can configure a per-event price\n * below this. */\nexport const MIN_INTEGRATOR_PRICE_SATS = 5;\n\n// ── event taxonomy ────────────────────────────────────────────────────────\n\nexport type EventClass = 'A' | 'B' | 'C';\n\nexport type ClassASubtype =\n | 'account_creation'\n | 'account_recovery'\n | 'kyc_tier_upgrade'\n | 'payment_method_connected'\n | 'agent_delegation_issued'\n | 'recovery_method_updated';\n\nexport type ClassBSubtype =\n | 'payment_authorization'\n | 'scoped_action_authorization'\n | 'attest_verification_at_gate'\n | 'stamp_signing'\n | 'pledge_resolution';\n\nexport type ClassCSubtype = 'session_creation';\n\nexport type EventSubtype = ClassASubtype | ClassBSubtype | ClassCSubtype;\n\nexport type AttestTier = 'anonymous' | 'bonded' | 'kyc_light' | 'kyc_strong';\n\n/** The shape of a per-event fee — either a fixed sats amount or a percent\n * of the underlying transaction amount (used for payments + pledges). */\nexport type SiteFeeShape =\n | { kind: 'fixed_sats'; sats: number }\n | { kind: 'percent_of_amount'; pct: number };\n\n/** What an integrator declares for a single event subtype. */\nexport interface IntegratorEventConfig {\n /** Whether this site bills this event subtype at all. */\n enabled: boolean;\n /** The per-event fee the site pays. */\n site_pays: SiteFeeShape;\n /** Fraction of post-platform-fee that flows to the user (0–0.8 since\n * platform_fee is 20%). The remainder is a rebate to the site's OC\n * project balance. */\n user_share_pct: number;\n}\n\n/** A complete integrator pricing config. Posted to me.ochk.io once at\n * integration time, mutable via the configurator UI or this SDK any time\n * after. */\nexport interface IntegratorPriceConfig {\n project_key: string;\n display_name: string;\n domain: string;\n /** ISO-8601 timestamp the config was last updated. */\n updated_at: string;\n /** Per-subtype configs. Subtypes not listed are disabled by default. */\n events: Partial<Record<EventSubtype, IntegratorEventConfig>>;\n}\n\n/** A computed fee breakdown for a single event. site_rebate_sats is what\n * flows back to the integrator's OC balance after OC's platform fee and\n * the user's cashback. */\nexport interface ComputedFees {\n gross_fee_sats: number;\n platform_fee_sats: number;\n user_earned_sats: number;\n site_rebate_sats: number;\n}\n\n/** Compute the four-way fee split for an event given an integrator's\n * config and (for percent_of_amount events) the underlying payment\n * amount.\n *\n * Invariants (verified by tests in oc-me-web/src/lib/events/types.test.ts):\n * 1. gross_fee_sats >= MIN_INTEGRATOR_PRICE_SATS\n * 2. platform_fee_sats >= PLATFORM_FEE_POLICY.min_floor_sats\n * 3. user_share_pct is clamped to [0, 0.8]\n * 4. site_rebate_sats >= 0\n * 5. gross == platform + user + rebate (exact, modulo rounding into rebate)\n */\nexport function computeFees(\n cfg: IntegratorEventConfig,\n payment_amount_sats?: number\n): ComputedFees {\n let gross = 0;\n if (cfg.site_pays.kind === 'fixed_sats') {\n gross = Math.max(MIN_INTEGRATOR_PRICE_SATS, Math.round(cfg.site_pays.sats));\n } else {\n if (payment_amount_sats == null) {\n throw new Error('percent_of_amount config requires payment_amount_sats');\n }\n gross = Math.max(\n MIN_INTEGRATOR_PRICE_SATS,\n Math.round(payment_amount_sats * cfg.site_pays.pct)\n );\n }\n const platform_fee_sats = Math.max(\n PLATFORM_FEE_POLICY.min_floor_sats,\n Math.round(gross * PLATFORM_FEE_POLICY.pct)\n );\n const user_share = Math.min(0.8, Math.max(0, cfg.user_share_pct));\n const user_earned_sats = Math.round(gross * user_share);\n const site_rebate_sats = Math.max(0, gross - platform_fee_sats - user_earned_sats);\n return { gross_fee_sats: gross, platform_fee_sats, user_earned_sats, site_rebate_sats };\n}\n\n/** Result of validating an IntegratorPriceConfig. */\nexport interface ValidationResult {\n ok: boolean;\n errors: { subtype?: EventSubtype; message: string }[];\n}\n\n/**\n * Validate an integrator's pricing config against the platform's\n * non-negotiable rules. Run client-side before posting; the server runs\n * the same checks and rejects anything that fails.\n */\nexport function validateIntegratorConfig(cfg: IntegratorPriceConfig): ValidationResult {\n const errors: ValidationResult['errors'] = [];\n\n if (!cfg.project_key) errors.push({ message: 'project_key is required' });\n if (!cfg.display_name) errors.push({ message: 'display_name is required' });\n if (!cfg.domain) errors.push({ message: 'domain is required' });\n\n for (const [key, eventCfg] of Object.entries(cfg.events)) {\n if (!eventCfg) continue;\n const subtype = key as EventSubtype;\n if (!eventCfg.enabled) continue;\n\n if (eventCfg.site_pays.kind === 'fixed_sats') {\n if (eventCfg.site_pays.sats < MIN_INTEGRATOR_PRICE_SATS) {\n errors.push({\n subtype,\n message: `site_pays.sats (${eventCfg.site_pays.sats}) is below MIN_INTEGRATOR_PRICE_SATS (${MIN_INTEGRATOR_PRICE_SATS})`,\n });\n }\n } else {\n const pct = eventCfg.site_pays.pct;\n if (!(pct > 0 && pct <= 1)) {\n errors.push({\n subtype,\n message: `site_pays.pct (${pct}) must be in (0, 1]`,\n });\n }\n }\n\n const u = eventCfg.user_share_pct;\n if (u < 0 || u > 0.8) {\n errors.push({\n subtype,\n message: `user_share_pct (${u}) must be in [0, 0.8]; max is 0.8 because platform_fee is ${PLATFORM_FEE_POLICY.pct}`,\n });\n }\n }\n\n return { ok: errors.length === 0, errors };\n}\n\n// ── canonical envelope ────────────────────────────────────────────────────\n\nexport interface BillableEvent {\n id: string;\n occurred_at: string;\n class: EventClass;\n subtype: EventSubtype;\n site: { domain: string; display_name: string };\n gross_fee_sats: number;\n platform_fee_sats: number;\n user_earned_sats: number;\n site_rebate_sats: number;\n verify_url: string;\n}\n\n// ── session lifecycle ────────────────────────────────────────────────────\n\nexport interface SessionPolicy {\n duration_seconds: number;\n refresh: 'sliding' | 'rolling' | 'none';\n sensitive_actions?: 're-auth' | 'none';\n}\n\nexport interface Session {\n id: string;\n identity: string;\n opens_at: string;\n expires_at: string;\n policy: SessionPolicy;\n scope: string[];\n}\n\nexport interface SignInOptions {\n scope: string[];\n sessionPolicy?: Partial<SessionPolicy>;\n returnTo?: string;\n}\n\nexport interface PaymentAuthorizeOptions {\n identity: string;\n amount_sats?: number;\n usd_cents?: number;\n description: string;\n external_ref?: string;\n}\n\nexport interface PaymentResult {\n id: string;\n status: 'authorized' | 'failed' | 'cancelled';\n sats_charged?: number;\n user_envelope_id?: string;\n verify_url?: string;\n}\n\nexport interface TelemetryEvent {\n code:\n | 'session.intra_signin'\n | 'session.token_refresh'\n | 'session.navigation'\n | 'auth.signin_failed'\n | 'auth.signin_cancelled'\n | 'auth.signin_rejected'\n | 'verify.passive_check';\n timestamp: string;\n session_id?: string;\n}\n","/**\n * `oc.config.validate` — local IntegratorPriceConfig validator, no\n * network call. Mirrors the server-side validation rules the\n * configurator at me.ochk.io/integrate enforces.\n *\n * import { oc } from '@orangecheck/me-client';\n * import type { IntegratorPriceConfig } from '@orangecheck/me-client';\n *\n * const cfg: IntegratorPriceConfig = { … };\n * const result = oc.config.validate(cfg);\n * if (!result.ok) console.error(result.errors);\n *\n * Per-project read/write of the config is owner-gated and lives at\n * /api/me/projects/[id] (POST to update). See me.ochk.io/me/projects/\n * for the operator UI.\n */\n\nimport { validateIntegratorConfig } from './types';\nimport type { IntegratorPriceConfig, ValidationResult } from './types';\n\nfunction validate(cfg: IntegratorPriceConfig): ValidationResult {\n return validateIntegratorConfig(cfg);\n}\n\nexport const config = { validate };\n","export const encoder = new TextEncoder();\nexport const decoder = new TextDecoder();\nconst MAX_INT32 = 2 ** 32;\nexport function concat(...buffers) {\n const size = buffers.reduce((acc, { length }) => acc + length, 0);\n const buf = new Uint8Array(size);\n let i = 0;\n for (const buffer of buffers) {\n buf.set(buffer, i);\n i += buffer.length;\n }\n return buf;\n}\nfunction writeUInt32BE(buf, value, offset) {\n if (value < 0 || value >= MAX_INT32) {\n throw new RangeError(`value must be >= 0 and <= ${MAX_INT32 - 1}. Received ${value}`);\n }\n buf.set([value >>> 24, value >>> 16, value >>> 8, value & 0xff], offset);\n}\nexport function uint64be(value) {\n const high = Math.floor(value / MAX_INT32);\n const low = value % MAX_INT32;\n const buf = new Uint8Array(8);\n writeUInt32BE(buf, high, 0);\n writeUInt32BE(buf, low, 4);\n return buf;\n}\nexport function uint32be(value) {\n const buf = new Uint8Array(4);\n writeUInt32BE(buf, value);\n return buf;\n}\nexport function encode(string) {\n const bytes = new Uint8Array(string.length);\n for (let i = 0; i < string.length; i++) {\n const code = string.charCodeAt(i);\n if (code > 127) {\n throw new TypeError('non-ASCII string encountered in encode()');\n }\n bytes[i] = code;\n }\n return bytes;\n}\n","export function encodeBase64(input) {\n if (Uint8Array.prototype.toBase64) {\n return input.toBase64();\n }\n const CHUNK_SIZE = 0x8000;\n const arr = [];\n for (let i = 0; i < input.length; i += CHUNK_SIZE) {\n arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));\n }\n return btoa(arr.join(''));\n}\nexport function decodeBase64(encoded) {\n if (Uint8Array.fromBase64) {\n return Uint8Array.fromBase64(encoded);\n }\n const binary = atob(encoded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n","import { encoder, decoder } from '../lib/buffer_utils.js';\nimport { encodeBase64, decodeBase64 } from '../lib/base64.js';\nexport function decode(input) {\n if (Uint8Array.fromBase64) {\n return Uint8Array.fromBase64(typeof input === 'string' ? input : decoder.decode(input), {\n alphabet: 'base64url',\n });\n }\n let encoded = input;\n if (encoded instanceof Uint8Array) {\n encoded = decoder.decode(encoded);\n }\n encoded = encoded.replace(/-/g, '+').replace(/_/g, '/');\n try {\n return decodeBase64(encoded);\n }\n catch {\n throw new TypeError('The input to be decoded is not correctly encoded.');\n }\n}\nexport function encode(input) {\n let unencoded = input;\n if (typeof unencoded === 'string') {\n unencoded = encoder.encode(unencoded);\n }\n if (Uint8Array.prototype.toBase64) {\n return unencoded.toBase64({ alphabet: 'base64url', omitPadding: true });\n }\n return encodeBase64(unencoded).replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n","export class JOSEError extends Error {\n static code = 'ERR_JOSE_GENERIC';\n code = 'ERR_JOSE_GENERIC';\n constructor(message, options) {\n super(message, options);\n this.name = this.constructor.name;\n Error.captureStackTrace?.(this, this.constructor);\n }\n}\nexport class JWTClaimValidationFailed extends JOSEError {\n static code = 'ERR_JWT_CLAIM_VALIDATION_FAILED';\n code = 'ERR_JWT_CLAIM_VALIDATION_FAILED';\n claim;\n reason;\n payload;\n constructor(message, payload, claim = 'unspecified', reason = 'unspecified') {\n super(message, { cause: { claim, reason, payload } });\n this.claim = claim;\n this.reason = reason;\n this.payload = payload;\n }\n}\nexport class JWTExpired extends JOSEError {\n static code = 'ERR_JWT_EXPIRED';\n code = 'ERR_JWT_EXPIRED';\n claim;\n reason;\n payload;\n constructor(message, payload, claim = 'unspecified', reason = 'unspecified') {\n super(message, { cause: { claim, reason, payload } });\n this.claim = claim;\n this.reason = reason;\n this.payload = payload;\n }\n}\nexport class JOSEAlgNotAllowed extends JOSEError {\n static code = 'ERR_JOSE_ALG_NOT_ALLOWED';\n code = 'ERR_JOSE_ALG_NOT_ALLOWED';\n}\nexport class JOSENotSupported extends JOSEError {\n static code = 'ERR_JOSE_NOT_SUPPORTED';\n code = 'ERR_JOSE_NOT_SUPPORTED';\n}\nexport class JWEDecryptionFailed extends JOSEError {\n static code = 'ERR_JWE_DECRYPTION_FAILED';\n code = 'ERR_JWE_DECRYPTION_FAILED';\n constructor(message = 'decryption operation failed', options) {\n super(message, options);\n }\n}\nexport class JWEInvalid extends JOSEError {\n static code = 'ERR_JWE_INVALID';\n code = 'ERR_JWE_INVALID';\n}\nexport class JWSInvalid extends JOSEError {\n static code = 'ERR_JWS_INVALID';\n code = 'ERR_JWS_INVALID';\n}\nexport class JWTInvalid extends JOSEError {\n static code = 'ERR_JWT_INVALID';\n code = 'ERR_JWT_INVALID';\n}\nexport class JWKInvalid extends JOSEError {\n static code = 'ERR_JWK_INVALID';\n code = 'ERR_JWK_INVALID';\n}\nexport class JWKSInvalid extends JOSEError {\n static code = 'ERR_JWKS_INVALID';\n code = 'ERR_JWKS_INVALID';\n}\nexport class JWKSNoMatchingKey extends JOSEError {\n static code = 'ERR_JWKS_NO_MATCHING_KEY';\n code = 'ERR_JWKS_NO_MATCHING_KEY';\n constructor(message = 'no applicable key found in the JSON Web Key Set', options) {\n super(message, options);\n }\n}\nexport class JWKSMultipleMatchingKeys extends JOSEError {\n [Symbol.asyncIterator];\n static code = 'ERR_JWKS_MULTIPLE_MATCHING_KEYS';\n code = 'ERR_JWKS_MULTIPLE_MATCHING_KEYS';\n constructor(message = 'multiple matching keys found in the JSON Web Key Set', options) {\n super(message, options);\n }\n}\nexport class JWKSTimeout extends JOSEError {\n static code = 'ERR_JWKS_TIMEOUT';\n code = 'ERR_JWKS_TIMEOUT';\n constructor(message = 'request timed out', options) {\n super(message, options);\n }\n}\nexport class JWSSignatureVerificationFailed extends JOSEError {\n static code = 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED';\n code = 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED';\n constructor(message = 'signature verification failed', options) {\n super(message, options);\n }\n}\n","const isObjectLike = (value) => typeof value === 'object' && value !== null;\nexport function isObject(input) {\n if (!isObjectLike(input) || Object.prototype.toString.call(input) !== '[object Object]') {\n return false;\n }\n if (Object.getPrototypeOf(input) === null) {\n return true;\n }\n let proto = input;\n while (Object.getPrototypeOf(proto) !== null) {\n proto = Object.getPrototypeOf(proto);\n }\n return Object.getPrototypeOf(input) === proto;\n}\nexport function isDisjoint(...headers) {\n const sources = headers.filter(Boolean);\n if (sources.length === 0 || sources.length === 1) {\n return true;\n }\n let acc;\n for (const header of sources) {\n const parameters = Object.keys(header);\n if (!acc || acc.size === 0) {\n acc = new Set(parameters);\n continue;\n }\n for (const parameter of parameters) {\n if (acc.has(parameter)) {\n return false;\n }\n acc.add(parameter);\n }\n }\n return true;\n}\nexport const isJWK = (key) => isObject(key) && typeof key.kty === 'string';\nexport const isPrivateJWK = (key) => key.kty !== 'oct' &&\n ((key.kty === 'AKP' && typeof key.priv === 'string') || typeof key.d === 'string');\nexport const isPublicJWK = (key) => key.kty !== 'oct' && key.d === undefined && key.priv === undefined;\nexport const isSecretJWK = (key) => key.kty === 'oct' && typeof key.k === 'string';\n","import { JOSENotSupported } from '../util/errors.js';\nconst unsupportedAlg = 'Invalid or unsupported JWK \"alg\" (Algorithm) Parameter value';\nfunction subtleMapping(jwk) {\n let algorithm;\n let keyUsages;\n switch (jwk.kty) {\n case 'AKP': {\n switch (jwk.alg) {\n case 'ML-DSA-44':\n case 'ML-DSA-65':\n case 'ML-DSA-87':\n algorithm = { name: jwk.alg };\n keyUsages = jwk.priv ? ['sign'] : ['verify'];\n break;\n default:\n throw new JOSENotSupported(unsupportedAlg);\n }\n break;\n }\n case 'RSA': {\n switch (jwk.alg) {\n case 'PS256':\n case 'PS384':\n case 'PS512':\n algorithm = { name: 'RSA-PSS', hash: `SHA-${jwk.alg.slice(-3)}` };\n keyUsages = jwk.d ? ['sign'] : ['verify'];\n break;\n case 'RS256':\n case 'RS384':\n case 'RS512':\n algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${jwk.alg.slice(-3)}` };\n keyUsages = jwk.d ? ['sign'] : ['verify'];\n break;\n case 'RSA-OAEP':\n case 'RSA-OAEP-256':\n case 'RSA-OAEP-384':\n case 'RSA-OAEP-512':\n algorithm = {\n name: 'RSA-OAEP',\n hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}`,\n };\n keyUsages = jwk.d ? ['decrypt', 'unwrapKey'] : ['encrypt', 'wrapKey'];\n break;\n default:\n throw new JOSENotSupported(unsupportedAlg);\n }\n break;\n }\n case 'EC': {\n switch (jwk.alg) {\n case 'ES256':\n case 'ES384':\n case 'ES512':\n algorithm = {\n name: 'ECDSA',\n namedCurve: { ES256: 'P-256', ES384: 'P-384', ES512: 'P-521' }[jwk.alg],\n };\n keyUsages = jwk.d ? ['sign'] : ['verify'];\n break;\n case 'ECDH-ES':\n case 'ECDH-ES+A128KW':\n case 'ECDH-ES+A192KW':\n case 'ECDH-ES+A256KW':\n algorithm = { name: 'ECDH', namedCurve: jwk.crv };\n keyUsages = jwk.d ? ['deriveBits'] : [];\n break;\n default:\n throw new JOSENotSupported(unsupportedAlg);\n }\n break;\n }\n case 'OKP': {\n switch (jwk.alg) {\n case 'Ed25519':\n case 'EdDSA':\n algorithm = { name: 'Ed25519' };\n keyUsages = jwk.d ? ['sign'] : ['verify'];\n break;\n case 'ECDH-ES':\n case 'ECDH-ES+A128KW':\n case 'ECDH-ES+A192KW':\n case 'ECDH-ES+A256KW':\n algorithm = { name: jwk.crv };\n keyUsages = jwk.d ? ['deriveBits'] : [];\n break;\n default:\n throw new JOSENotSupported(unsupportedAlg);\n }\n break;\n }\n default:\n throw new JOSENotSupported('Invalid or unsupported JWK \"kty\" (Key Type) Parameter value');\n }\n return { algorithm, keyUsages };\n}\nexport async function jwkToKey(jwk) {\n if (!jwk.alg) {\n throw new TypeError('\"alg\" argument is required when \"jwk.alg\" is not present');\n }\n const { algorithm, keyUsages } = subtleMapping(jwk);\n const keyData = { ...jwk };\n if (keyData.kty !== 'AKP') {\n delete keyData.alg;\n }\n delete keyData.use;\n return crypto.subtle.importKey('jwk', keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);\n}\n","import { decode as decodeBase64URL } from '../util/base64url.js';\nimport { fromSPKI, fromPKCS8, fromX509 } from '../lib/asn1.js';\nimport { jwkToKey } from '../lib/jwk_to_key.js';\nimport { JOSENotSupported } from '../util/errors.js';\nimport { isObject } from '../lib/type_checks.js';\nexport async function importSPKI(spki, alg, options) {\n if (typeof spki !== 'string' || spki.indexOf('-----BEGIN PUBLIC KEY-----') !== 0) {\n throw new TypeError('\"spki\" must be SPKI formatted string');\n }\n return fromSPKI(spki, alg, options);\n}\nexport async function importX509(x509, alg, options) {\n if (typeof x509 !== 'string' || x509.indexOf('-----BEGIN CERTIFICATE-----') !== 0) {\n throw new TypeError('\"x509\" must be X.509 formatted string');\n }\n return fromX509(x509, alg, options);\n}\nexport async function importPKCS8(pkcs8, alg, options) {\n if (typeof pkcs8 !== 'string' || pkcs8.indexOf('-----BEGIN PRIVATE KEY-----') !== 0) {\n throw new TypeError('\"pkcs8\" must be PKCS#8 formatted string');\n }\n return fromPKCS8(pkcs8, alg, options);\n}\nexport async function importJWK(jwk, alg, options) {\n if (!isObject(jwk)) {\n throw new TypeError('JWK must be an object');\n }\n let ext;\n alg ??= jwk.alg;\n ext ??= options?.extractable ?? jwk.ext;\n switch (jwk.kty) {\n case 'oct':\n if (typeof jwk.k !== 'string' || !jwk.k) {\n throw new TypeError('missing \"k\" (Key Value) Parameter value');\n }\n return decodeBase64URL(jwk.k);\n case 'RSA':\n if ('oth' in jwk && jwk.oth !== undefined) {\n throw new JOSENotSupported('RSA JWK \"oth\" (Other Primes Info) Parameter value is not supported');\n }\n return jwkToKey({ ...jwk, alg, ext });\n case 'AKP': {\n if (typeof jwk.alg !== 'string' || !jwk.alg) {\n throw new TypeError('missing \"alg\" (Algorithm) Parameter value');\n }\n if (alg !== undefined && alg !== jwk.alg) {\n throw new TypeError('JWK alg and alg option value mismatch');\n }\n return jwkToKey({ ...jwk, ext });\n }\n case 'EC':\n case 'OKP':\n return jwkToKey({ ...jwk, alg, ext });\n default:\n throw new JOSENotSupported('Unsupported \"kty\" (Key Type) Parameter value');\n }\n}\n","/**\n * `oc.webhook.verify` — Ed25519 signature verification for me.ochk.io\n * webhook deliveries.\n *\n * Webhook envelopes are signed with the auth host's Ed25519 key. The\n * signature is sent as a hex string in the `OC-Signature` header, and\n * the kid is in the `OC-Key-Id` header.\n *\n * import { oc } from '@orangecheck/me-client';\n *\n * // In your webhook handler — pass RAW BODY BYTES, not the parsed\n * // JSON. Frameworks that re-serialize before your handler will\n * // produce a different byte sequence and the signature will not\n * // validate.\n * const result = await oc.webhook.verify(\n * rawBody, // string | Uint8Array\n * req.headers['oc-signature'], // hex\n * req.headers['oc-key-id'] // kid\n * );\n * if (!result.ok) return res.status(401).send(result.reason);\n *\n * The verifier auto-fetches and caches the JWKS at\n * `https://ochk.io/.well-known/jwks.json` for 1h. Pass `{ jwk }` to\n * skip the network round-trip if you've embedded the key.\n */\n\nimport { importJWK, type CryptoKey, type KeyObject } from 'jose';\n\nconst DEFAULT_ISSUER = 'https://ochk.io';\nconst DEFAULT_TTL_MS = 60 * 60 * 1000;\n\nexport interface VerifyResult {\n ok: boolean;\n reason?: string;\n}\n\nexport interface OcPublicJwk {\n kty: 'OKP';\n crv: 'Ed25519';\n x: string;\n kid: string;\n alg?: 'EdDSA';\n use?: 'sig';\n}\n\nexport interface VerifyOptions {\n /** Override the auth host issuer. Defaults to https://ochk.io. */\n issuer?: string;\n /** Pass a JWK directly to skip the network fetch entirely. Useful\n * for tests, edge runtimes that can't fetch, or integrators that\n * ship the public key alongside their webhook handler. */\n jwk?: OcPublicJwk;\n /** JWKS cache TTL in ms. Defaults to 1 hour. Stale-on-error: a\n * transient JWKS outage falls back to the previous cached value\n * rather than rejecting every webhook. */\n jwksCacheTtlMs?: number;\n}\n\ntype AuthKey = CryptoKey | KeyObject;\n\ninterface JwksCacheEntry {\n keys: Record<string, AuthKey>;\n fetchedAt: number;\n}\n\nconst jwksCache = new Map<string, JwksCacheEntry>();\nconst inflight = new Map<string, Promise<JwksCacheEntry>>();\n\nasync function fetchJwks(issuer: string, ttlMs: number): Promise<JwksCacheEntry> {\n const cached = jwksCache.get(issuer);\n if (cached && Date.now() - cached.fetchedAt < ttlMs) return cached;\n const existing = inflight.get(issuer);\n if (existing) return existing;\n const p = (async (): Promise<JwksCacheEntry> => {\n try {\n const url = `${issuer.replace(/\\/$/, '')}/.well-known/jwks.json`;\n const res = await fetch(url, { headers: { Accept: 'application/json' } });\n if (!res.ok) throw new Error(`JWKS fetch ${url} returned ${res.status}`);\n const json = (await res.json()) as { keys: OcPublicJwk[] };\n if (!json || !Array.isArray(json.keys)) {\n throw new Error(`JWKS at ${url} did not return {keys:[…]}`);\n }\n const keys: Record<string, AuthKey> = {};\n for (const k of json.keys) {\n if (typeof k.kid !== 'string') continue;\n try {\n keys[k.kid] = (await importJWK(k, 'EdDSA')) as AuthKey;\n } catch {\n /* skip keys that won't import */\n }\n }\n const entry: JwksCacheEntry = { keys, fetchedAt: Date.now() };\n jwksCache.set(issuer, entry);\n return entry;\n } catch (err) {\n const stale = jwksCache.get(issuer);\n if (stale) return stale;\n throw err;\n }\n })().finally(() => {\n inflight.delete(issuer);\n });\n inflight.set(issuer, p);\n return p;\n}\n\nfunction hexToBytes(hex: string): Uint8Array | null {\n if (typeof hex !== 'string') return null;\n const s = hex.trim();\n if (s.length === 0 || s.length % 2 !== 0) return null;\n const out = new Uint8Array(s.length / 2);\n for (let i = 0; i < out.length; i++) {\n const b = parseInt(s.slice(i * 2, i * 2 + 2), 16);\n if (Number.isNaN(b)) return null;\n out[i] = b;\n }\n return out;\n}\n\nfunction toBytes(input: string | Uint8Array): Uint8Array {\n if (typeof input === 'string') return new TextEncoder().encode(input);\n return input;\n}\n\nfunction toArrayBuffer(view: Uint8Array): ArrayBuffer {\n // SubtleCrypto's BufferSource type requires Uint8Array<ArrayBuffer>\n // (not ArrayBufferLike). Copy into a fresh ArrayBuffer so the\n // resulting buffer is statically typed as ArrayBuffer (slicing a\n // SharedArrayBuffer would yield SharedArrayBuffer which the type\n // system rejects).\n const buf = new ArrayBuffer(view.byteLength);\n new Uint8Array(buf).set(view);\n return buf;\n}\n\nasync function verifyEd25519(\n key: AuthKey,\n sig: Uint8Array,\n msg: Uint8Array\n): Promise<boolean> {\n // jose normalizes the key into a CryptoKey under WebCrypto-capable\n // runtimes (Node 20+, Vercel Edge, modern browsers); fall through\n // to subtle.verify for the actual signature check.\n const subtle =\n typeof globalThis.crypto !== 'undefined' && globalThis.crypto.subtle\n ? globalThis.crypto.subtle\n : null;\n if (!subtle) return false;\n try {\n return await subtle.verify(\n 'Ed25519',\n key as CryptoKey,\n toArrayBuffer(sig),\n toArrayBuffer(msg)\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Verify a webhook signature. Pass the raw body bytes (not parsed\n * JSON), the hex-encoded signature from the `OC-Signature` header, and\n * the kid from the `OC-Key-Id` header.\n *\n * Returns `{ ok: true }` on success, `{ ok: false, reason }` on any\n * failure (bad signature, kid not in JWKS, malformed signature,\n * network-only JWKS fetch failed without prior cache, etc.). Never\n * throws.\n */\nexport async function verify(\n rawBody: string | Uint8Array,\n sigHex: string,\n kid: string,\n options: VerifyOptions = {}\n): Promise<VerifyResult> {\n if (!sigHex) return { ok: false, reason: 'missing signature' };\n if (!kid) return { ok: false, reason: 'missing kid' };\n const sig = hexToBytes(sigHex);\n if (!sig) return { ok: false, reason: 'malformed signature (expected hex)' };\n const msg = toBytes(rawBody);\n\n let key: AuthKey | undefined;\n if (options.jwk) {\n if (options.jwk.kid !== kid) {\n return { ok: false, reason: `kid mismatch (header=${kid}, jwk=${options.jwk.kid})` };\n }\n try {\n key = (await importJWK(options.jwk, 'EdDSA')) as AuthKey;\n } catch {\n return { ok: false, reason: 'could not import provided jwk' };\n }\n } else {\n const issuer = options.issuer ?? DEFAULT_ISSUER;\n const ttl = options.jwksCacheTtlMs ?? DEFAULT_TTL_MS;\n try {\n let entry = await fetchJwks(issuer, ttl);\n key = entry.keys[kid];\n if (!key) {\n jwksCache.delete(issuer);\n entry = await fetchJwks(issuer, ttl);\n key = entry.keys[kid];\n }\n } catch (err) {\n return { ok: false, reason: `jwks unavailable: ${(err as Error).message}` };\n }\n if (!key) return { ok: false, reason: `kid ${kid} not in JWKS` };\n }\n\n const ok = await verifyEd25519(key, sig, msg);\n return ok ? { ok: true } : { ok: false, reason: 'signature does not match' };\n}\n\n/** Force-refresh the JWKS cache. Useful after a key rotation event\n * if you don't want to wait for the TTL to expire. */\nexport async function fetchJwksForce(issuer = DEFAULT_ISSUER): Promise<void> {\n jwksCache.delete(issuer);\n await fetchJwks(issuer, DEFAULT_TTL_MS);\n}\n\nexport const webhook = { verify, fetchJwks: fetchJwksForce };\n","/**\n * @orangecheck/me-client\n *\n * Drop-in client for me.ochk.io. Sign-in-with-OC. You pay for sessions\n * and actions, not for clicks.\n *\n * Three entry points for three audiences:\n *\n * import { ... } from '@orangecheck/me-client' // React surface\n * import { ... } from '@orangecheck/me-client/server' // server-side\n * verification\n * (Next.js, Express,\n * Hono — all without\n * env vars or JWK\n * handling)\n * import { signInWithOc } from '@orangecheck/me-client/popup'\n * // browser-only popup\n * orchestrator\n *\n * Server-side verification example:\n *\n * // pages/api/me.ts\n * import { withOcAuth } from '@orangecheck/me-client/server';\n *\n * export default withOcAuth(async (req, res) => {\n * if (!req.ocSession) return res.status(401).json({ ok: false });\n * res.status(200).json({ address: req.ocSession.addr });\n * });\n *\n * Popup signin example:\n *\n * import { signInWithOc } from '@orangecheck/me-client/popup';\n *\n * button.addEventListener('click', async () => {\n * const result = await signInWithOc();\n * if (!result) return; // user cancelled\n * localStorage.setItem('oc-token', result.token);\n * location.assign('/dashboard');\n * });\n */\n\nexport { OcSignInButton } from './SignInButton';\nexport type { OcSignInButtonProps } from './SignInButton';\n\nexport { session, onTelemetry } from './session';\nexport { payment } from './payment';\nexport { event } from './event';\nexport type { FireEventOptions } from './event';\nexport { config } from './config';\nexport { webhook } from './webhook';\nexport type { OcPublicJwk, VerifyOptions, VerifyResult } from './webhook';\nexport {\n setOrigin,\n getOrigin,\n setBearerToken,\n getBearerToken,\n clearBearerToken,\n MeClientError,\n} from './transport';\n\nexport {\n PLATFORM_FEE_POLICY,\n MIN_INTEGRATOR_PRICE_SATS,\n computeFees,\n validateIntegratorConfig,\n} from './types';\n\nexport type {\n EventClass,\n EventSubtype,\n ClassASubtype,\n ClassBSubtype,\n ClassCSubtype,\n AttestTier,\n SiteFeeShape,\n IntegratorEventConfig,\n IntegratorPriceConfig,\n ComputedFees,\n ValidationResult,\n BillableEvent,\n Session,\n SessionPolicy,\n SignInOptions,\n PaymentAuthorizeOptions,\n PaymentResult,\n TelemetryEvent,\n} from './types';\n\nimport { session } from './session';\nimport { payment } from './payment';\nimport { event } from './event';\nimport { config } from './config';\nimport { webhook } from './webhook';\n\n/** Convenience namespace mirroring the public API surface in /integrate\n * code samples — `oc.session.create()`, `oc.payment.authorize()`,\n * `oc.event.fire()`, `oc.config.validate()`, `oc.webhook.verify()`. */\nexport const oc = { session, payment, event, config, webhook };\n"]}
|
package/dist/popup.d.mts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface OcPopupAccount {
|
|
2
|
+
id?: string;
|
|
3
|
+
address?: string;
|
|
4
|
+
btc_address?: string;
|
|
5
|
+
display_name?: string | null;
|
|
6
|
+
nostr_npub?: string | null;
|
|
7
|
+
wallet_provisioned?: boolean;
|
|
8
|
+
email?: string;
|
|
9
|
+
}
|
|
10
|
+
interface OcPopupResult {
|
|
11
|
+
account: OcPopupAccount;
|
|
12
|
+
token: string;
|
|
13
|
+
}
|
|
14
|
+
interface SignInWithOcOptions {
|
|
15
|
+
popupOrigin?: string;
|
|
16
|
+
popupPath?: string;
|
|
17
|
+
features?: string;
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
}
|
|
20
|
+
declare function signInWithOc(options?: SignInWithOcOptions): Promise<OcPopupResult | null>;
|
|
21
|
+
|
|
22
|
+
export { type OcPopupAccount, type OcPopupResult, type SignInWithOcOptions, signInWithOc };
|
package/dist/popup.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface OcPopupAccount {
|
|
2
|
+
id?: string;
|
|
3
|
+
address?: string;
|
|
4
|
+
btc_address?: string;
|
|
5
|
+
display_name?: string | null;
|
|
6
|
+
nostr_npub?: string | null;
|
|
7
|
+
wallet_provisioned?: boolean;
|
|
8
|
+
email?: string;
|
|
9
|
+
}
|
|
10
|
+
interface OcPopupResult {
|
|
11
|
+
account: OcPopupAccount;
|
|
12
|
+
token: string;
|
|
13
|
+
}
|
|
14
|
+
interface SignInWithOcOptions {
|
|
15
|
+
popupOrigin?: string;
|
|
16
|
+
popupPath?: string;
|
|
17
|
+
features?: string;
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
}
|
|
20
|
+
declare function signInWithOc(options?: SignInWithOcOptions): Promise<OcPopupResult | null>;
|
|
21
|
+
|
|
22
|
+
export { type OcPopupAccount, type OcPopupResult, type SignInWithOcOptions, signInWithOc };
|
package/dist/popup.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/popup.ts
|
|
4
|
+
var DEFAULT_POPUP_ORIGIN = "https://me.ochk.io";
|
|
5
|
+
var DEFAULT_POPUP_PATH = "/popup/signin";
|
|
6
|
+
var DEFAULT_FEATURES = "width=480,height=720,resizable=yes,scrollbars=yes";
|
|
7
|
+
function signInWithOc(options = {}) {
|
|
8
|
+
const popupOrigin = options.popupOrigin ?? DEFAULT_POPUP_ORIGIN;
|
|
9
|
+
const popupPath = options.popupPath ?? DEFAULT_POPUP_PATH;
|
|
10
|
+
const features = options.features ?? DEFAULT_FEATURES;
|
|
11
|
+
return new Promise((resolve) => {
|
|
12
|
+
if (typeof window === "undefined") {
|
|
13
|
+
resolve(null);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const url = new URL(popupPath, popupOrigin);
|
|
17
|
+
url.searchParams.set("opener_origin", window.location.origin);
|
|
18
|
+
const popup = window.open(url.toString(), "oc-signin", features);
|
|
19
|
+
if (!popup) {
|
|
20
|
+
resolve(null);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
popup.focus();
|
|
24
|
+
let settled = false;
|
|
25
|
+
const cleanup = () => {
|
|
26
|
+
window.removeEventListener("message", onMessage);
|
|
27
|
+
clearInterval(closedTimer);
|
|
28
|
+
if (options.signal) options.signal.removeEventListener("abort", onAbort);
|
|
29
|
+
};
|
|
30
|
+
function settle(value) {
|
|
31
|
+
if (settled) return;
|
|
32
|
+
settled = true;
|
|
33
|
+
cleanup();
|
|
34
|
+
try {
|
|
35
|
+
if (popup && !popup.closed) popup.close();
|
|
36
|
+
} catch {
|
|
37
|
+
}
|
|
38
|
+
resolve(value);
|
|
39
|
+
}
|
|
40
|
+
function onMessage(event) {
|
|
41
|
+
if (event.origin !== popupOrigin) return;
|
|
42
|
+
if (event.source !== popup) return;
|
|
43
|
+
const data = event.data;
|
|
44
|
+
if (!data || data.type !== "oc-signin-success") return;
|
|
45
|
+
if (!data.account || !data.token) {
|
|
46
|
+
settle(null);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
settle({ account: data.account, token: data.token });
|
|
50
|
+
}
|
|
51
|
+
function onAbort() {
|
|
52
|
+
settle(null);
|
|
53
|
+
}
|
|
54
|
+
window.addEventListener("message", onMessage);
|
|
55
|
+
if (options.signal) {
|
|
56
|
+
if (options.signal.aborted) {
|
|
57
|
+
settle(null);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
options.signal.addEventListener("abort", onAbort);
|
|
61
|
+
}
|
|
62
|
+
const closedTimer = setInterval(() => {
|
|
63
|
+
if (popup && popup.closed) settle(null);
|
|
64
|
+
}, 500);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
exports.signInWithOc = signInWithOc;
|
|
69
|
+
//# sourceMappingURL=popup.js.map
|
|
70
|
+
//# sourceMappingURL=popup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/popup.ts"],"names":[],"mappings":"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","file":"popup.js","sourcesContent":["/**\n * @orangecheck/me-client/popup\n *\n * Browser-side helper that opens the OC sign-in popup, listens for the\n * postMessage from me.ochk.io, and resolves with the verified session.\n *\n * import { signInWithOc } from '@orangecheck/me-client/popup';\n *\n * document.querySelector('#oc-signin')!.addEventListener('click', async () => {\n * const result = await signInWithOc();\n * if (result) {\n * localStorage.setItem('oc-session-token', result.token);\n * location.assign('/app');\n * }\n * });\n *\n * Why this lives in a separate entry point: it's browser-only (uses\n * window.open / addEventListener) and integrators that only need the\n * server-side verifier shouldn't pull popup orchestration into their\n * server bundle.\n */\n\nconst DEFAULT_POPUP_ORIGIN = 'https://me.ochk.io';\nconst DEFAULT_POPUP_PATH = '/popup/signin';\nconst DEFAULT_FEATURES = 'width=480,height=720,resizable=yes,scrollbars=yes';\n\nexport interface OcPopupAccount {\n id?: string;\n address?: string;\n btc_address?: string;\n display_name?: string | null;\n nostr_npub?: string | null;\n wallet_provisioned?: boolean;\n email?: string;\n}\n\nexport interface OcPopupResult {\n /** Account payload from the auth host. `address` is the canonical\n * identifier (Bitcoin address for BIP-322 users, did:email:<hash>\n * for email-OTP users). */\n account: OcPopupAccount;\n /** The session JWT. Cross-domain integrators store this and send\n * it as `Authorization: Bearer <token>` on subsequent calls.\n * Family integrators (*.ochk.io) can ignore it — the cookie set\n * Domain=.ochk.io rides home automatically. */\n token: string;\n}\n\nexport interface SignInWithOcOptions {\n /** Origin of the OC popup page. Defaults to https://me.ochk.io.\n * Override only for staging / preview environments. */\n popupOrigin?: string;\n /** Path on the popup origin. Defaults to /popup/signin. */\n popupPath?: string;\n /** window.open features string. Defaults to a 480x720 resizable\n * popup with scrollbars. */\n features?: string;\n /** AbortSignal that cancels the wait and closes the popup. */\n signal?: AbortSignal;\n}\n\n/**\n * Open the OC signin popup and resolve with the session result. Returns\n * `null` if the user closed the popup without completing signin, or if\n * the AbortSignal fired.\n *\n * MUST be called inside a user-gesture handler (e.g. a button onClick).\n * Browsers block `window.open` outside of user gestures.\n */\nexport function signInWithOc(options: SignInWithOcOptions = {}): Promise<OcPopupResult | null> {\n const popupOrigin = options.popupOrigin ?? DEFAULT_POPUP_ORIGIN;\n const popupPath = options.popupPath ?? DEFAULT_POPUP_PATH;\n const features = options.features ?? DEFAULT_FEATURES;\n\n return new Promise((resolve) => {\n if (typeof window === 'undefined') {\n resolve(null);\n return;\n }\n\n const url = new URL(popupPath, popupOrigin);\n url.searchParams.set('opener_origin', window.location.origin);\n const popup = window.open(url.toString(), 'oc-signin', features);\n if (!popup) {\n // Popup blocked. Caller can detect a null result and fall\n // back to a full-page redirect if desired.\n resolve(null);\n return;\n }\n popup.focus();\n\n let settled = false;\n const cleanup = () => {\n window.removeEventListener('message', onMessage);\n clearInterval(closedTimer);\n if (options.signal) options.signal.removeEventListener('abort', onAbort);\n };\n\n function settle(value: OcPopupResult | null) {\n if (settled) return;\n settled = true;\n cleanup();\n try {\n if (popup && !popup.closed) popup.close();\n } catch {\n /* popup may have closed itself first */\n }\n resolve(value);\n }\n\n function onMessage(event: MessageEvent) {\n // Origin pinning is necessary but not sufficient — same-origin\n // pages other than our popup can post the same shape. Pin both\n // origin AND source window so only the popup we opened can\n // settle this promise.\n if (event.origin !== popupOrigin) return;\n if (event.source !== popup) return;\n const data = event.data as\n | { type?: string; account?: OcPopupAccount; token?: string }\n | null;\n if (!data || data.type !== 'oc-signin-success') return;\n if (!data.account || !data.token) {\n // Malformed payload — treat as not-signed-in.\n settle(null);\n return;\n }\n settle({ account: data.account, token: data.token });\n }\n\n function onAbort() {\n settle(null);\n }\n\n window.addEventListener('message', onMessage);\n if (options.signal) {\n if (options.signal.aborted) {\n settle(null);\n return;\n }\n options.signal.addEventListener('abort', onAbort);\n }\n\n // Detect the user closing the popup without completing signin.\n const closedTimer = setInterval(() => {\n if (popup && popup.closed) settle(null);\n }, 500);\n });\n}\n"]}
|
package/dist/popup.mjs
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// src/popup.ts
|
|
2
|
+
var DEFAULT_POPUP_ORIGIN = "https://me.ochk.io";
|
|
3
|
+
var DEFAULT_POPUP_PATH = "/popup/signin";
|
|
4
|
+
var DEFAULT_FEATURES = "width=480,height=720,resizable=yes,scrollbars=yes";
|
|
5
|
+
function signInWithOc(options = {}) {
|
|
6
|
+
const popupOrigin = options.popupOrigin ?? DEFAULT_POPUP_ORIGIN;
|
|
7
|
+
const popupPath = options.popupPath ?? DEFAULT_POPUP_PATH;
|
|
8
|
+
const features = options.features ?? DEFAULT_FEATURES;
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
if (typeof window === "undefined") {
|
|
11
|
+
resolve(null);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const url = new URL(popupPath, popupOrigin);
|
|
15
|
+
url.searchParams.set("opener_origin", window.location.origin);
|
|
16
|
+
const popup = window.open(url.toString(), "oc-signin", features);
|
|
17
|
+
if (!popup) {
|
|
18
|
+
resolve(null);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
popup.focus();
|
|
22
|
+
let settled = false;
|
|
23
|
+
const cleanup = () => {
|
|
24
|
+
window.removeEventListener("message", onMessage);
|
|
25
|
+
clearInterval(closedTimer);
|
|
26
|
+
if (options.signal) options.signal.removeEventListener("abort", onAbort);
|
|
27
|
+
};
|
|
28
|
+
function settle(value) {
|
|
29
|
+
if (settled) return;
|
|
30
|
+
settled = true;
|
|
31
|
+
cleanup();
|
|
32
|
+
try {
|
|
33
|
+
if (popup && !popup.closed) popup.close();
|
|
34
|
+
} catch {
|
|
35
|
+
}
|
|
36
|
+
resolve(value);
|
|
37
|
+
}
|
|
38
|
+
function onMessage(event) {
|
|
39
|
+
if (event.origin !== popupOrigin) return;
|
|
40
|
+
if (event.source !== popup) return;
|
|
41
|
+
const data = event.data;
|
|
42
|
+
if (!data || data.type !== "oc-signin-success") return;
|
|
43
|
+
if (!data.account || !data.token) {
|
|
44
|
+
settle(null);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
settle({ account: data.account, token: data.token });
|
|
48
|
+
}
|
|
49
|
+
function onAbort() {
|
|
50
|
+
settle(null);
|
|
51
|
+
}
|
|
52
|
+
window.addEventListener("message", onMessage);
|
|
53
|
+
if (options.signal) {
|
|
54
|
+
if (options.signal.aborted) {
|
|
55
|
+
settle(null);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
options.signal.addEventListener("abort", onAbort);
|
|
59
|
+
}
|
|
60
|
+
const closedTimer = setInterval(() => {
|
|
61
|
+
if (popup && popup.closed) settle(null);
|
|
62
|
+
}, 500);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { signInWithOc };
|
|
67
|
+
//# sourceMappingURL=popup.mjs.map
|
|
68
|
+
//# sourceMappingURL=popup.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/popup.ts"],"names":[],"mappings":"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","file":"popup.mjs","sourcesContent":["/**\n * @orangecheck/me-client/popup\n *\n * Browser-side helper that opens the OC sign-in popup, listens for the\n * postMessage from me.ochk.io, and resolves with the verified session.\n *\n * import { signInWithOc } from '@orangecheck/me-client/popup';\n *\n * document.querySelector('#oc-signin')!.addEventListener('click', async () => {\n * const result = await signInWithOc();\n * if (result) {\n * localStorage.setItem('oc-session-token', result.token);\n * location.assign('/app');\n * }\n * });\n *\n * Why this lives in a separate entry point: it's browser-only (uses\n * window.open / addEventListener) and integrators that only need the\n * server-side verifier shouldn't pull popup orchestration into their\n * server bundle.\n */\n\nconst DEFAULT_POPUP_ORIGIN = 'https://me.ochk.io';\nconst DEFAULT_POPUP_PATH = '/popup/signin';\nconst DEFAULT_FEATURES = 'width=480,height=720,resizable=yes,scrollbars=yes';\n\nexport interface OcPopupAccount {\n id?: string;\n address?: string;\n btc_address?: string;\n display_name?: string | null;\n nostr_npub?: string | null;\n wallet_provisioned?: boolean;\n email?: string;\n}\n\nexport interface OcPopupResult {\n /** Account payload from the auth host. `address` is the canonical\n * identifier (Bitcoin address for BIP-322 users, did:email:<hash>\n * for email-OTP users). */\n account: OcPopupAccount;\n /** The session JWT. Cross-domain integrators store this and send\n * it as `Authorization: Bearer <token>` on subsequent calls.\n * Family integrators (*.ochk.io) can ignore it — the cookie set\n * Domain=.ochk.io rides home automatically. */\n token: string;\n}\n\nexport interface SignInWithOcOptions {\n /** Origin of the OC popup page. Defaults to https://me.ochk.io.\n * Override only for staging / preview environments. */\n popupOrigin?: string;\n /** Path on the popup origin. Defaults to /popup/signin. */\n popupPath?: string;\n /** window.open features string. Defaults to a 480x720 resizable\n * popup with scrollbars. */\n features?: string;\n /** AbortSignal that cancels the wait and closes the popup. */\n signal?: AbortSignal;\n}\n\n/**\n * Open the OC signin popup and resolve with the session result. Returns\n * `null` if the user closed the popup without completing signin, or if\n * the AbortSignal fired.\n *\n * MUST be called inside a user-gesture handler (e.g. a button onClick).\n * Browsers block `window.open` outside of user gestures.\n */\nexport function signInWithOc(options: SignInWithOcOptions = {}): Promise<OcPopupResult | null> {\n const popupOrigin = options.popupOrigin ?? DEFAULT_POPUP_ORIGIN;\n const popupPath = options.popupPath ?? DEFAULT_POPUP_PATH;\n const features = options.features ?? DEFAULT_FEATURES;\n\n return new Promise((resolve) => {\n if (typeof window === 'undefined') {\n resolve(null);\n return;\n }\n\n const url = new URL(popupPath, popupOrigin);\n url.searchParams.set('opener_origin', window.location.origin);\n const popup = window.open(url.toString(), 'oc-signin', features);\n if (!popup) {\n // Popup blocked. Caller can detect a null result and fall\n // back to a full-page redirect if desired.\n resolve(null);\n return;\n }\n popup.focus();\n\n let settled = false;\n const cleanup = () => {\n window.removeEventListener('message', onMessage);\n clearInterval(closedTimer);\n if (options.signal) options.signal.removeEventListener('abort', onAbort);\n };\n\n function settle(value: OcPopupResult | null) {\n if (settled) return;\n settled = true;\n cleanup();\n try {\n if (popup && !popup.closed) popup.close();\n } catch {\n /* popup may have closed itself first */\n }\n resolve(value);\n }\n\n function onMessage(event: MessageEvent) {\n // Origin pinning is necessary but not sufficient — same-origin\n // pages other than our popup can post the same shape. Pin both\n // origin AND source window so only the popup we opened can\n // settle this promise.\n if (event.origin !== popupOrigin) return;\n if (event.source !== popup) return;\n const data = event.data as\n | { type?: string; account?: OcPopupAccount; token?: string }\n | null;\n if (!data || data.type !== 'oc-signin-success') return;\n if (!data.account || !data.token) {\n // Malformed payload — treat as not-signed-in.\n settle(null);\n return;\n }\n settle({ account: data.account, token: data.token });\n }\n\n function onAbort() {\n settle(null);\n }\n\n window.addEventListener('message', onMessage);\n if (options.signal) {\n if (options.signal.aborted) {\n settle(null);\n return;\n }\n options.signal.addEventListener('abort', onAbort);\n }\n\n // Detect the user closing the popup without completing signin.\n const closedTimer = setInterval(() => {\n if (popup && popup.closed) settle(null);\n }, 500);\n });\n}\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { VerifyOcOptions, SessionRequestHeaders, SessionPayload } from '@orangecheck/auth-core';
|
|
2
|
+
export { SessionPayload, VerifyOcOptions, verifyOcToken } from '@orangecheck/auth-core';
|
|
3
|
+
|
|
4
|
+
declare function getOcSession(headers: SessionRequestHeaders | Headers, options?: VerifyOcOptions): Promise<SessionPayload | null>;
|
|
5
|
+
interface NextApiRequestLike {
|
|
6
|
+
headers: {
|
|
7
|
+
cookie?: string;
|
|
8
|
+
authorization?: string;
|
|
9
|
+
[k: string]: unknown;
|
|
10
|
+
};
|
|
11
|
+
ocSession?: SessionPayload | null;
|
|
12
|
+
}
|
|
13
|
+
interface NextApiResponseLike {
|
|
14
|
+
status(code: number): NextApiResponseLike;
|
|
15
|
+
json(body: unknown): unknown;
|
|
16
|
+
setHeader(name: string, value: string | number | readonly string[]): unknown;
|
|
17
|
+
}
|
|
18
|
+
type NextApiHandlerLike = (req: NextApiRequestLike, res: NextApiResponseLike) => unknown | Promise<unknown>;
|
|
19
|
+
interface WithOcAuthOptions extends VerifyOcOptions {
|
|
20
|
+
required?: boolean;
|
|
21
|
+
}
|
|
22
|
+
declare function withOcAuth<T extends NextApiHandlerLike>(handler: T, options?: WithOcAuthOptions): T;
|
|
23
|
+
interface ExpressRequestLike {
|
|
24
|
+
headers: {
|
|
25
|
+
cookie?: string;
|
|
26
|
+
authorization?: string;
|
|
27
|
+
[k: string]: unknown;
|
|
28
|
+
};
|
|
29
|
+
ocSession?: SessionPayload | null;
|
|
30
|
+
}
|
|
31
|
+
interface ExpressResponseLike {
|
|
32
|
+
status(code: number): ExpressResponseLike;
|
|
33
|
+
json(body: unknown): unknown;
|
|
34
|
+
setHeader(name: string, value: string | number | readonly string[]): unknown;
|
|
35
|
+
}
|
|
36
|
+
type ExpressNextLike = (err?: unknown) => void;
|
|
37
|
+
declare function ocAuthExpress(options?: WithOcAuthOptions): (req: ExpressRequestLike, res: ExpressResponseLike, next: ExpressNextLike) => Promise<void>;
|
|
38
|
+
interface HonoContextLike {
|
|
39
|
+
req: {
|
|
40
|
+
raw: {
|
|
41
|
+
headers: Headers;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
set(key: string, value: unknown): void;
|
|
45
|
+
json(body: unknown, status?: number): unknown;
|
|
46
|
+
header(name: string, value: string): void;
|
|
47
|
+
}
|
|
48
|
+
type HonoNextLike = () => Promise<void>;
|
|
49
|
+
declare function ocAuthHono(options?: WithOcAuthOptions): (c: HonoContextLike, next: HonoNextLike) => Promise<unknown>;
|
|
50
|
+
|
|
51
|
+
export { type WithOcAuthOptions, getOcSession, ocAuthExpress, ocAuthHono, withOcAuth };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { VerifyOcOptions, SessionRequestHeaders, SessionPayload } from '@orangecheck/auth-core';
|
|
2
|
+
export { SessionPayload, VerifyOcOptions, verifyOcToken } from '@orangecheck/auth-core';
|
|
3
|
+
|
|
4
|
+
declare function getOcSession(headers: SessionRequestHeaders | Headers, options?: VerifyOcOptions): Promise<SessionPayload | null>;
|
|
5
|
+
interface NextApiRequestLike {
|
|
6
|
+
headers: {
|
|
7
|
+
cookie?: string;
|
|
8
|
+
authorization?: string;
|
|
9
|
+
[k: string]: unknown;
|
|
10
|
+
};
|
|
11
|
+
ocSession?: SessionPayload | null;
|
|
12
|
+
}
|
|
13
|
+
interface NextApiResponseLike {
|
|
14
|
+
status(code: number): NextApiResponseLike;
|
|
15
|
+
json(body: unknown): unknown;
|
|
16
|
+
setHeader(name: string, value: string | number | readonly string[]): unknown;
|
|
17
|
+
}
|
|
18
|
+
type NextApiHandlerLike = (req: NextApiRequestLike, res: NextApiResponseLike) => unknown | Promise<unknown>;
|
|
19
|
+
interface WithOcAuthOptions extends VerifyOcOptions {
|
|
20
|
+
required?: boolean;
|
|
21
|
+
}
|
|
22
|
+
declare function withOcAuth<T extends NextApiHandlerLike>(handler: T, options?: WithOcAuthOptions): T;
|
|
23
|
+
interface ExpressRequestLike {
|
|
24
|
+
headers: {
|
|
25
|
+
cookie?: string;
|
|
26
|
+
authorization?: string;
|
|
27
|
+
[k: string]: unknown;
|
|
28
|
+
};
|
|
29
|
+
ocSession?: SessionPayload | null;
|
|
30
|
+
}
|
|
31
|
+
interface ExpressResponseLike {
|
|
32
|
+
status(code: number): ExpressResponseLike;
|
|
33
|
+
json(body: unknown): unknown;
|
|
34
|
+
setHeader(name: string, value: string | number | readonly string[]): unknown;
|
|
35
|
+
}
|
|
36
|
+
type ExpressNextLike = (err?: unknown) => void;
|
|
37
|
+
declare function ocAuthExpress(options?: WithOcAuthOptions): (req: ExpressRequestLike, res: ExpressResponseLike, next: ExpressNextLike) => Promise<void>;
|
|
38
|
+
interface HonoContextLike {
|
|
39
|
+
req: {
|
|
40
|
+
raw: {
|
|
41
|
+
headers: Headers;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
set(key: string, value: unknown): void;
|
|
45
|
+
json(body: unknown, status?: number): unknown;
|
|
46
|
+
header(name: string, value: string): void;
|
|
47
|
+
}
|
|
48
|
+
type HonoNextLike = () => Promise<void>;
|
|
49
|
+
declare function ocAuthHono(options?: WithOcAuthOptions): (c: HonoContextLike, next: HonoNextLike) => Promise<unknown>;
|
|
50
|
+
|
|
51
|
+
export { type WithOcAuthOptions, getOcSession, ocAuthExpress, ocAuthHono, withOcAuth };
|