UNPKG

@web5/agent

Version:
247 lines 12.6 kB
import { RequireOnly } from '@web5/common'; import type { ConnectPermissionRequest } from './connect.js'; import { DidDocument, PortableDid, type BearerDid } from '@web5/dids'; import { DwnDataEncodedRecordsWriteMessage, DwnPermissionScope } from './types/dwn.js'; import type { Web5Agent } from './types/agent.js'; /** * Sent to an OIDC server to authorize a client. Allows clients * to securely send authorization request parameters directly to * the server via POST. This avoids exposing sensitive data in URLs * and ensures the server validates the request before user interaction. * * @see {@link https://www.rfc-editor.org/rfc/rfc9126.html | OAuth 2.0 Pushed Authorization Requests} */ export type PushedAuthRequest = { /** The JWT which contains the {@link Web5ConnectAuthRequest} */ request: string; }; /** * Sent back by OIDC server in response to {@link PushedAuthRequest} * The server generates a TTL and a unique request_uri. The request_uri can be shared * with the Provider using a link or a QR code along with additional params * to access the url and decrypt the payload. */ export type PushedAuthResponse = { request_uri: string; expires_in: number; }; /** * Used in decentralized apps. The SIOPv2 Auth Request is created by a client relying party (RP) * often a web service or an app who wants to obtain information from a provider * The contents of this are inserted into a JWT inside of the {@link PushedAuthRequest}. * @see {@link https://github.com/TBD54566975/known-customer-credential | TBD OIDC Documentation for SIOPv2 } */ export type SIOPv2AuthRequest = { /** The DID of the client (RP) */ client_id: string; /** The scope of the access request (e.g., `openid profile`). */ scope: string; /** The type of response desired (e.g. `id_token`) */ response_type: string; /** the URL to which the Identity Provider will post the Authorization Response */ redirect_uri: string; /** The URI to which the SIOPv2 Authorization Response will be sent (Tim's note: not used with encrypted request JWT)*/ response_uri?: string; /** * An opaque value used to maintain state between the request and the callback. * Recommended for security to prevent CSRF attacks. */ state: string; /** * A string value used to associate a client session with an ID token to mitigate replay attacks. * Recommended when requesting ID tokens. */ nonce: string; /** * The PKCE code challenge. * Required if `code_challenge_method` is used. Enhances security for public clients (e.g., single-page apps, * mobile apps) by requiring an additional verification step during token exchange. */ code_challenge?: string; /** The method used for the PKCE challenge (typically `S256`). Must be present if `code_challenge` is included. */ code_challenge_method?: 'S256'; /** * An ID token previously issued to the client, passed as a hint about the end-user’s current or past authenticated * session with the client. Can streamline user experience if already logged in. */ id_token_hint?: string; /** A hint to the authorization server about the login identifier the user might use. Useful for pre-filling login information. */ login_hint?: string; /** Requested Authentication Context Class Reference values. Specifies the authentication context requirements. */ acr_values?: string; /** When using a PAR for secure cross device flows we use a "form_post" rather than a "direct_post" */ response_mode: 'direct_post'; /** Used by PFI to request VCs as input to IDV process. If present, `response_type: "vp_token""` MUST also be present */ presentation_definition?: any; /** A JSON object containing the Verifier metadata values (Tim's note: from TBD KCC Repo) */ client_metadata?: { /** Array of strings, each a DID method supported for the subject of ID Token */ subject_syntax_types_supported: string[]; /** Human-readable string name of the client to be presented to the end-user during authorization */ client_name?: string; /** URI of a web page providing information about the client */ client_uri?: string; /** URI of an image logo for the client */ logo_uri?: string; /** Array of strings representing ways to contact people responsible for this client, typically email addresses */ contacts?: string[]; /** URI that points to a terms of service document for the client */ tos_uri?: string; /** URI that points to a privacy policy document */ policy_uri?: string; }; }; /** * An auth request that is compatible with both Web5 Connect and (hopefully, WIP) OIDC SIOPv2 * The contents of this are inserted into a JWT inside of the {@link PushedAuthRequest}. */ export type Web5ConnectAuthRequest = { /** The user friendly name of the client/app to be displayed when prompting end-user with permission requests. */ displayName: string; /** PermissionGrants that are to be sent to the provider */ permissionRequests: ConnectPermissionRequest[]; } & SIOPv2AuthRequest; /** The fields for an OIDC SIOPv2 Auth Repsonse */ export type SIOPv2AuthResponse = { /** Issuer MUST match the value of sub (Applicant's DID) */ iss: string; /** Subject Identifier. A locally unique and never reassigned identifier * within the Issuer for the End-User, which is intended to be consumed * by the Client. */ sub: string; /** Audience(s) that this ID Token is intended for. It MUST contain the * OAuth 2.0 client_id of the Relying Party as an audience value. */ aud: string; /** Time at which the JWT was issued. */ iat: number; /** Expiration time on or after which the ID Token MUST NOT be accepted * for processing. */ exp: number; /** Time when the End-User authentication occurred. */ auth_time?: number; /** b64url encoded nonce used to associate a Client session with an ID Token, and to * mitigate replay attacks. */ nonce?: string; /** Custom claims. */ [key: string]: any; }; /** An auth response that is compatible with both Web5 Connect and (hopefully, WIP) OIDC SIOPv2 */ export type Web5ConnectAuthResponse = { delegateGrants: DwnDataEncodedRecordsWriteMessage[]; delegatePortableDid: PortableDid; } & SIOPv2AuthResponse; /** Represents the different OIDC endpoint types. * 1. `pushedAuthorizationRequest`: client sends {@link PushedAuthRequest} receives {@link PushedAuthResponse} * 2. `authorize`: provider gets the {@link Web5ConnectAuthRequest} JWT that was stored by the PAR * 3. `callback`: provider sends {@link Web5ConnectAuthResponse} to this endpoint * 4. `token`: client gets {@link Web5ConnectAuthResponse} from this endpoint */ type OidcEndpoint = 'pushedAuthorizationRequest' | 'authorize' | 'callback' | 'token'; /** * Gets the correct OIDC endpoint out of the {@link OidcEndpoint} options provided. * Handles a trailing slash on baseURL * * @param {Object} options the options object * @param {string} options.baseURL for example `http://foo.com/connect/ * @param {OidcEndpoint} options.endpoint the OIDC endpoint desired * @param {string} options.authParam this is the unique id which must be provided when getting the `authorize` endpoint * @param {string} options.tokenParam this is the random state as b64url which must be provided with the `token` endpoint */ declare function buildOidcUrl({ baseURL, endpoint, authParam, tokenParam, }: { baseURL: string; endpoint: OidcEndpoint; authParam?: string; tokenParam?: string; }): string; /** * Generates a cryptographically random "code challenge" in * accordance with the RFC 7636 PKCE specification. * * @see {@link https://datatracker.ietf.org/doc/html/rfc7636#section-4.2 | RFC 7636 } */ declare function generateCodeChallenge(): Promise<{ codeChallengeBytes: Uint8Array; codeChallengeBase64Url: string; }>; /** Client creates the {@link Web5ConnectAuthRequest} */ declare function createAuthRequest(options: RequireOnly<Web5ConnectAuthRequest, 'client_id' | 'scope' | 'redirect_uri' | 'permissionRequests' | 'displayName'>): Promise<Web5ConnectAuthRequest>; /** Encrypts the auth request with the key which will be passed through QR code */ declare function encryptAuthRequest({ jwt, encryptionKey, }: { jwt: string; encryptionKey: Uint8Array; }): Promise<string>; /** Create a response object compatible with Web5 Connect and OIDC SIOPv2 */ declare function createResponseObject(options: RequireOnly<Web5ConnectAuthResponse, 'iss' | 'sub' | 'aud' | 'delegateGrants' | 'delegatePortableDid'>): Promise<Web5ConnectAuthResponse>; /** sign an object and transform it into a jwt using a did */ declare function signJwt({ did, data, }: { did: BearerDid; data: Record<string, unknown>; }): Promise<string>; /** Take the decrypted JWT and verify it was signed by its public DID. Return parsed object. */ declare function verifyJwt({ jwt }: { jwt: string; }): Promise<object>; /** Take the encrypted JWE, decrypt using the code challenge and return a JWT string which will need to be verified */ declare function decryptAuthRequest({ jwe, encryption_key, }: { jwe: string; encryption_key: string; }): string; /** * The client uses to decrypt the jwe obtained from the auth server which contains * the {@link Web5ConnectAuthResponse} that was sent by the provider to the auth server. * * @async * @param {BearerDid} clientDid - The did that was initially used by the client for ECDH at connect init. * @param {string} jwe - The encrypted data as a jwe. * @param {string} pin - The pin that was obtained from the user. */ declare function decryptAuthResponse(clientDid: BearerDid, jwe: string, pin: string): Promise<string>; /** Derives a shared ECDH private key in order to encrypt the {@link Web5ConnectAuthResponse} */ declare function deriveSharedKey(privateKeyDid: BearerDid, publicKeyDid: DidDocument): Promise<Uint8Array>; /** * Encrypts the auth response jwt. Requires a randomPin is added to the AAD of the * encryption algorithm in order to prevent man in the middle and eavesdropping attacks. * The keyid of the delegate did is used to pass the public key to the client in order * for the client to derive the shared ECDH private key. */ declare function encryptAuthResponse({ jwt, encryptionKey, delegateDidKeyId, randomPin, }: { jwt: string; encryptionKey: Uint8Array; delegateDidKeyId: string; randomPin: string; }): string; /** * Creates the permission grants that assign to the selectedDid the level of * permissions that the web app requested in the {@link Web5ConnectAuthRequest} */ declare function createPermissionGrants(selectedDid: string, delegateBearerDid: BearerDid, agent: Web5Agent, scopes: DwnPermissionScope[]): Promise<(import("@tbd54566975/dwn-sdk-js").RecordsWriteMessage & { encodedData: string; })[]>; /** * Creates a delegate did which the web app will use as its future indentity. * Assigns to that DID the level of permissions that the web app requested in * the {@link Web5ConnectAuthRequest}. Encrypts via ECDH key that the web app * will have access to because the web app has the public key which it provided * in the {@link Web5ConnectAuthRequest}. Then sends the ciphertext of this * {@link Web5ConnectAuthResponse} to the callback endpoint. Which the * web app will need to retrieve from the token endpoint and decrypt with the pin to access. */ declare function submitAuthResponse(selectedDid: string, authRequest: Web5ConnectAuthRequest, randomPin: string, agent: Web5Agent): Promise<void>; export declare const Oidc: { createAuthRequest: typeof createAuthRequest; encryptAuthRequest: typeof encryptAuthRequest; getAuthRequest: (request_uri: string, encryption_key: string) => Promise<Web5ConnectAuthRequest>; decryptAuthRequest: typeof decryptAuthRequest; createPermissionGrants: typeof createPermissionGrants; createResponseObject: typeof createResponseObject; encryptAuthResponse: typeof encryptAuthResponse; decryptAuthResponse: typeof decryptAuthResponse; deriveSharedKey: typeof deriveSharedKey; signJwt: typeof signJwt; verifyJwt: typeof verifyJwt; buildOidcUrl: typeof buildOidcUrl; generateCodeChallenge: typeof generateCodeChallenge; submitAuthResponse: typeof submitAuthResponse; }; export {}; //# sourceMappingURL=oidc.d.ts.map