From 2f3cf75e6093cf7ce20f4c9f373c7a7c9f384bf0 Mon Sep 17 00:00:00 2001 From: Andrew Min Date: Mon, 4 Dec 2023 17:23:25 -0500 Subject: [PATCH] release v2023.12.0 --- .../public/v1/public_api.client.ts | 28 ++++ .../public/v1/public_api.fetcher.ts | 46 ++++++ .../public/v1/public_api.swagger.json | 135 +++++++++++++++++- .../coordinator/public/v1/public_api.types.ts | 72 +++++++++- 4 files changed, 277 insertions(+), 4 deletions(-) diff --git a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.client.ts b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.client.ts index 2769be034..9935111f9 100644 --- a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.client.ts +++ b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.client.ts @@ -129,6 +129,7 @@ import type { TDeletePolicyBody, TDeletePolicyResponse, } from "./public_api.fetcher"; +import type { TEmailAuthBody, TEmailAuthResponse } from "./public_api.fetcher"; import type { TExportPrivateKeyBody, TExportPrivateKeyResponse, @@ -1270,6 +1271,33 @@ export class TurnkeyClient { }; }; + /** + * Authenticate a user via Email + * + * Sign the provided `TEmailAuthBody` with the client's `stamp` function, and submit the request (POST /public/v1/submit/email_auth). + * + * See also {@link stampEmailAuth}. + */ + emailAuth = async (input: TEmailAuthBody): Promise => { + return this.request("/public/v1/submit/email_auth", input); + }; + + /** + * Produce a `SignedRequest` from `TEmailAuthBody` by using the client's `stamp` function. + * + * See also {@link EmailAuth}. + */ + stampEmailAuth = async (input: TEmailAuthBody): Promise => { + const fullUrl = this.config.baseUrl + "/public/v1/submit/email_auth"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + }; + /** * Exports a Private Key * diff --git a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.fetcher.ts b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.fetcher.ts index 8b4031620..1295c529f 100644 --- a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.fetcher.ts +++ b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.fetcher.ts @@ -1649,6 +1649,52 @@ export const signDeletePolicy = ( options, }); +/** + * `POST /public/v1/submit/email_auth` + */ +export type TEmailAuthResponse = + operations["PublicApiService_EmailAuth"]["responses"]["200"]["schema"]; + +/** + * `POST /public/v1/submit/email_auth` + */ +export type TEmailAuthInput = { body: TEmailAuthBody }; + +/** + * `POST /public/v1/submit/email_auth` + */ +export type TEmailAuthBody = + operations["PublicApiService_EmailAuth"]["parameters"]["body"]["body"]; + +/** + * Email Auth + * + * Authenticate a user via Email + * + * `POST /public/v1/submit/email_auth` + */ +export const emailAuth = (input: TEmailAuthInput) => + request({ + uri: "/public/v1/submit/email_auth", + method: "POST", + body: input.body, + }); + +/** + * Request a WebAuthn assertion and return a signed `EmailAuth` request, ready to be POSTed to Turnkey. + * + * See {@link EmailAuth} + */ +export const signEmailAuth = ( + input: TEmailAuthInput, + options?: TurnkeyCredentialRequestOptions +) => + signedRequest({ + uri: "/public/v1/submit/email_auth", + body: input.body, + options, + }); + /** * `POST /public/v1/submit/export_private_key` */ diff --git a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.swagger.json b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.swagger.json index 3364c1dee..4e11b5c64 100644 --- a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.swagger.json +++ b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.swagger.json @@ -1156,6 +1156,38 @@ "tags": ["Policies"] } }, + "/public/v1/submit/email_auth": { + "post": { + "summary": "Email Auth", + "description": "Authenticate a user via Email", + "operationId": "PublicApiService_EmailAuth", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1EmailAuthRequest" + } + } + ], + "tags": ["Email Auth"] + } + }, "/public/v1/submit/export_private_key": { "post": { "summary": "Export Private Key", @@ -1961,7 +1993,8 @@ "ACTIVITY_TYPE_SIGN_TRANSACTION_V2", "ACTIVITY_TYPE_EXPORT_PRIVATE_KEY", "ACTIVITY_TYPE_EXPORT_WALLET", - "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V4" + "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V4", + "ACTIVITY_TYPE_EMAIL_AUTH" ] }, "v1AddressFormat": { @@ -1994,6 +2027,11 @@ }, "updatedAt": { "$ref": "#/definitions/externaldatav1Timestamp" + }, + "expirationSeconds": { + "type": "string", + "format": "uint64", + "description": "Optional window (in seconds) indicating how long the API Key should last." } }, "required": [ @@ -2014,6 +2052,10 @@ "publicKey": { "type": "string", "description": "The public component of a cryptographic key pair used to sign messages and transactions." + }, + "expirationSeconds": { + "type": "string", + "description": "Optional window (in seconds) indicating how long the API Key should last." } }, "required": ["apiKeyName", "publicKey"] @@ -2846,6 +2888,10 @@ "disableEmailRecovery": { "type": "boolean", "description": "Disable email recovery for the sub-organization" + }, + "disableEmailAuth": { + "type": "boolean", + "description": "Disable email auth for the sub-organization" } }, "required": ["subOrganizationName", "rootUsers", "rootQuorumThreshold"] @@ -3495,6 +3541,84 @@ "type": "string", "enum": ["EFFECT_ALLOW", "EFFECT_DENY"] }, + "v1EmailAuthIntent": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Email of the authenticating user." + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted." + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to Email Auth - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Optional window (in seconds) indicating how long the API Key should last. Default to 30 minutes." + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomization", + "description": "Optional parameters for customizing emails. If not provided, use defaults." + } + }, + "required": ["email", "targetPublicKey"] + }, + "v1EmailAuthRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_EMAIL_AUTH"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1EmailAuthIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1EmailAuthResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for the authenticating User." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for the created API key." + } + }, + "required": ["userId", "apiKeyId"] + }, + "v1EmailCustomization": { + "type": "object", + "properties": { + "subject": { + "type": "string" + }, + "body": { + "type": "string" + }, + "styling": { + "type": "string" + }, + "urlPrefix": { + "type": "string" + } + } + }, "v1ExportPrivateKeyIntent": { "type": "object", "properties": { @@ -3612,7 +3736,8 @@ "type": "string", "enum": [ "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY", - "FEATURE_NAME_WEBAUTHN_ORIGINS" + "FEATURE_NAME_WEBAUTHN_ORIGINS", + "FEATURE_NAME_EMAIL_AUTH" ] }, "v1GetActivitiesRequest": { @@ -4216,6 +4341,9 @@ }, "createSubOrganizationIntentV4": { "$ref": "#/definitions/v1CreateSubOrganizationIntentV4" + }, + "emailAuthIntent": { + "$ref": "#/definitions/v1EmailAuthIntent" } }, "required": ["createOrganizationIntent"] @@ -4923,6 +5051,9 @@ }, "createSubOrganizationResultV4": { "$ref": "#/definitions/v1CreateSubOrganizationResultV4" + }, + "emailAuthResult": { + "$ref": "#/definitions/v1EmailAuthResult" } } }, diff --git a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.types.ts b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.types.ts index ba21e9932..a4c1a8355 100644 --- a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.types.ts +++ b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.types.ts @@ -140,6 +140,10 @@ export type paths = { /** Delete an existing Policy */ post: operations["PublicApiService_DeletePolicy"]; }; + "/public/v1/submit/email_auth": { + /** Authenticate a user via Email */ + post: operations["PublicApiService_EmailAuth"]; + }; "/public/v1/submit/export_private_key": { /** Exports a Private Key */ post: operations["PublicApiService_ExportPrivateKey"]; @@ -368,7 +372,8 @@ export type definitions = { | "ACTIVITY_TYPE_SIGN_TRANSACTION_V2" | "ACTIVITY_TYPE_EXPORT_PRIVATE_KEY" | "ACTIVITY_TYPE_EXPORT_WALLET" - | "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V4"; + | "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V4" + | "ACTIVITY_TYPE_EMAIL_AUTH"; /** @enum {string} */ v1AddressFormat: | "ADDRESS_FORMAT_UNCOMPRESSED" @@ -385,12 +390,19 @@ export type definitions = { apiKeyName: string; createdAt: definitions["externaldatav1Timestamp"]; updatedAt: definitions["externaldatav1Timestamp"]; + /** + * Format: uint64 + * @description Optional window (in seconds) indicating how long the API Key should last. + */ + expirationSeconds?: string; }; v1ApiKeyParams: { /** @description Human-readable name for an API Key. */ apiKeyName: string; /** @description The public component of a cryptographic key pair used to sign messages and transactions. */ publicKey: string; + /** @description Optional window (in seconds) indicating how long the API Key should last. */ + expirationSeconds?: string; }; v1ApiOnlyUserParams: { /** @description The name of the new API-only User. */ @@ -709,6 +721,8 @@ export type definitions = { wallet?: definitions["v1WalletParams"]; /** @description Disable email recovery for the sub-organization */ disableEmailRecovery?: boolean; + /** @description Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; }; v1CreateSubOrganizationRequest: { /** @enum {string} */ @@ -949,6 +963,39 @@ export type definitions = { }; /** @enum {string} */ v1Effect: "EFFECT_ALLOW" | "EFFECT_DENY"; + v1EmailAuthIntent: { + /** @description Email of the authenticating user. */ + email: string; + /** @description Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Optional human-readable name for an API Key. If none provided, default to Email Auth - */ + apiKeyName?: string; + /** @description Optional window (in seconds) indicating how long the API Key should last. Default to 30 minutes. */ + expirationSeconds?: string; + /** @description Optional parameters for customizing emails. If not provided, use defaults. */ + emailCustomization?: definitions["v1EmailCustomization"]; + }; + v1EmailAuthRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_EMAIL_AUTH"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1EmailAuthIntent"]; + }; + v1EmailAuthResult: { + /** @description Unique identifier for the authenticating User. */ + userId: string; + /** @description Unique identifier for the created API key. */ + apiKeyId: string; + }; + v1EmailCustomization: { + subject?: string; + body?: string; + styling?: string; + urlPrefix?: string; + }; v1ExportPrivateKeyIntent: { /** @description Unique identifier for a given Private Key. */ privateKeyId: string; @@ -1000,7 +1047,8 @@ export type definitions = { /** @enum {string} */ v1FeatureName: | "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY" - | "FEATURE_NAME_WEBAUTHN_ORIGINS"; + | "FEATURE_NAME_WEBAUTHN_ORIGINS" + | "FEATURE_NAME_EMAIL_AUTH"; v1GetActivitiesRequest: { /** @description Unique identifier for a given Organization. */ organizationId: string; @@ -1226,6 +1274,7 @@ export type definitions = { exportPrivateKeyIntent?: definitions["v1ExportPrivateKeyIntent"]; exportWalletIntent?: definitions["v1ExportWalletIntent"]; createSubOrganizationIntentV4?: definitions["v1CreateSubOrganizationIntentV4"]; + emailAuthIntent?: definitions["v1EmailAuthIntent"]; }; v1Invitation: { /** @description Unique identifier for a given Invitation object. */ @@ -1482,6 +1531,7 @@ export type definitions = { exportPrivateKeyResult?: definitions["v1ExportPrivateKeyResult"]; exportWalletResult?: definitions["v1ExportWalletResult"]; createSubOrganizationResultV4?: definitions["v1CreateSubOrganizationResultV4"]; + emailAuthResult?: definitions["v1EmailAuthResult"]; }; v1RootUserParams: { /** @description Human-readable name for a User. */ @@ -2481,6 +2531,24 @@ export type operations = { }; }; }; + /** Authenticate a user via Email */ + PublicApiService_EmailAuth: { + parameters: { + body: { + body: definitions["v1EmailAuthRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; /** Exports a Private Key */ PublicApiService_ExportPrivateKey: { parameters: {