import * as z from "zod/mini"; export const OAUTH_AUTHORIZATION_POPUP_TRANSPORT_SOURCE = "getuserfeedback.oauth"; export const OAUTH_AUTHORIZATION_POPUP_PROTOCOL_VERSION = 1; // A 32-byte value encodes to 43 unpadded base64url characters. Its final // sextet has two zero padding bits, so only indices divisible by four are // canonical. const OAUTH_AUTHORIZATION_ATTEMPT_ID_PATTERN = /^[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$/; const oauthAuthorizationAttemptIdSchema = z .string() .check(z.regex(OAUTH_AUTHORIZATION_ATTEMPT_ID_PATTERN)); export const oauthAuthorizationCompletionOutcomeSchema = z.enum([ "connected", "reconnected", "canceled", "failed", "confirmation_required", ]); export const oauthAuthorizationCompletionStatusRequestSchema = z.strictObject({ source: z.literal(OAUTH_AUTHORIZATION_POPUP_TRANSPORT_SOURCE), protocolVersion: z.literal(OAUTH_AUTHORIZATION_POPUP_PROTOCOL_VERSION), type: z.literal("oauth.authorization.completion-status.request"), attemptId: oauthAuthorizationAttemptIdSchema, }); /** * An untrusted popup wake signal, not authorization or settlement evidence. * The receiving page must fetch authoritative attempt status before sending an * acknowledgement or acting on the reported outcome. */ export const oauthAuthorizationCompletionStatusResultSchema = z.strictObject({ source: z.literal(OAUTH_AUTHORIZATION_POPUP_TRANSPORT_SOURCE), protocolVersion: z.literal(OAUTH_AUTHORIZATION_POPUP_PROTOCOL_VERSION), type: z.literal("oauth.authorization.completion-status.result"), attemptId: oauthAuthorizationAttemptIdSchema, outcome: oauthAuthorizationCompletionOutcomeSchema, }); /** A delivery acknowledgement for the correlated wake signal only. */ export const oauthAuthorizationCompletionStatusAckSchema = z.strictObject({ source: z.literal(OAUTH_AUTHORIZATION_POPUP_TRANSPORT_SOURCE), protocolVersion: z.literal(OAUTH_AUTHORIZATION_POPUP_PROTOCOL_VERSION), type: z.literal("oauth.authorization.completion-status.ack"), attemptId: oauthAuthorizationAttemptIdSchema, }); /** * An untrusted popup transport failure signal. It only reports that the * authorization handoff could not proceed; it is not OAuth settlement * evidence. */ export const oauthAuthorizationHandoffFailureSchema = z.strictObject({ source: z.literal(OAUTH_AUTHORIZATION_POPUP_TRANSPORT_SOURCE), protocolVersion: z.literal(OAUTH_AUTHORIZATION_POPUP_PROTOCOL_VERSION), type: z.literal("oauth.authorization.handoff-failure"), attemptId: oauthAuthorizationAttemptIdSchema, }); export const oauthAuthorizationPopupTransportMessageSchema = z.discriminatedUnion("type", [ oauthAuthorizationCompletionStatusRequestSchema, oauthAuthorizationCompletionStatusResultSchema, oauthAuthorizationCompletionStatusAckSchema, oauthAuthorizationHandoffFailureSchema, ]); export type OAuthAuthorizationCompletionOutcome = z.output< typeof oauthAuthorizationCompletionOutcomeSchema >; export type OAuthAuthorizationCompletionStatusRequest = z.output< typeof oauthAuthorizationCompletionStatusRequestSchema >; export type OAuthAuthorizationCompletionStatusResult = z.output< typeof oauthAuthorizationCompletionStatusResultSchema >; export type OAuthAuthorizationCompletionStatusAck = z.output< typeof oauthAuthorizationCompletionStatusAckSchema >; export type OAuthAuthorizationHandoffFailure = z.output< typeof oauthAuthorizationHandoffFailureSchema >; export type OAuthAuthorizationPopupTransportMessage = z.output< typeof oauthAuthorizationPopupTransportMessageSchema >;