From 76f47f25ee811a82db1953fba128745cb8fd898e Mon Sep 17 00:00:00 2001 From: Chris Tran Date: Thu, 4 Apr 2024 15:50:43 -0500 Subject: [PATCH] feat: splits createTransaction into two functions for register and authenticate --- README.md | 23 ++++++++++-- src/classes/PassageFlex.ts | 37 +++++++++++++++---- src/index.ts | 3 +- src/types/AuthenticateTransactionArgs.ts | 6 +++ ...tionArgs.ts => RegisterTransactionArgs.ts} | 2 +- .../{Passage.test.ts => PassageFlex.test.ts} | 24 ++++++++++-- 6 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 src/types/AuthenticateTransactionArgs.ts rename src/types/{TransactionArgs.ts => RegisterTransactionArgs.ts} (85%) rename tests/{Passage.test.ts => PassageFlex.test.ts} (88%) diff --git a/README.md b/README.md index ec6e1b5..7b1ab71 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,9 @@ const passageApp = await passage.getApp(); console.log(passageApp.authOrigin); ``` -## Create a transaction +## Create a registration transaction -To create a transaction to kick off a user passkey registration or authentication, you should use the `passage.createTransaction()` function. +To create a transaction to kick off a user passkey registration, you should use the `passage.createRegisterTransaction()` function. ```javascript import { PassageFlex } from '@passageidentity/passage-flex-node'; @@ -59,12 +59,29 @@ const passage = new PassageFlex({ apiKey: process.env.PASSAGE_API_KEY, }); -const transaction = await passage.createTransaction({ +const transaction = await passage.createRegisterTransaction({ externalId: 'a unique immutable string that represents your user', passkeyDisplayName: "the label for the user's passkey that they will see when logging in", }); ``` +## Create an authentication transaction + +To create a transaction to kick off a user passkey authentication, you should use the `passage.createAuthenticateTransaction()` function. + +```javascript +import { PassageFlex } from '@passageidentity/passage-flex-node'; + +const passage = new PassageFlex({ + appId: process.env.PASSAGE_APP_ID, + apiKey: process.env.PASSAGE_API_KEY, +}); + +const transaction = await passage.createAuthenticateTransaction({ + externalId: 'a unique immutable string that represents your user', +}); +``` + ## Verify a nonce To verify a nonce that you received from the end of of passkey registration or authentication ceremony, you should use the `passage.verifyNonce()` function. diff --git a/src/classes/PassageFlex.ts b/src/classes/PassageFlex.ts index f45ae13..7c4a953 100644 --- a/src/classes/PassageFlex.ts +++ b/src/classes/PassageFlex.ts @@ -12,8 +12,9 @@ import { } from '../generated'; import apiConfiguration from '../utils/apiConfiguration'; import { AppInfo } from '../models/AppInfo'; -import { TransactionArgs } from '../types/TransactionArgs'; +import { AuthenticateTransactionArgs } from '../types/AuthenticateTransactionArgs'; import { UserInfo } from '../models/UserInfo'; +import { RegisterTransactionArgs } from '../types/RegisterTransactionArgs'; /** * PassageFlex class used to get app info, create transactions, and verify nonces @@ -77,17 +78,17 @@ export class PassageFlex { } /** - * Create a transaction to start a user's registration or authentication process + * Create a transaction to start a user's registration process * - * @param {TransactionArgs} args The required values to create a transaction + * @param {RegisterTransactionArgs} args The required values to create a transaction * @return {Promise} The transaction ID */ - public async createTransaction(args: TransactionArgs): Promise { + public async createRegisterTransaction(args: RegisterTransactionArgs): Promise { try { const { externalId, passkeyDisplayName } = args; - const response = await this.transactionClient.createTransaction({ + const response = await this.transactionClient.createRegisterTransaction({ appId: this.appId, - createTransactionRequest: { + createTransactionRegisterRequest: { externalId, passkeyDisplayName, }, @@ -95,7 +96,29 @@ export class PassageFlex { return response.transactionId; } catch (err) { - throw new PassageError('Could not create transaction', err as ResponseError); + throw new PassageError('Could not create register transaction', err as ResponseError); + } + } + + /** + * Create a transaction to start a user's authentication process + * + * @param {AuthenticateTransactionArgs} args The required values to create a transaction + * @return {Promise} The transaction ID + */ + public async createAuthenticateTransaction(args: AuthenticateTransactionArgs): Promise { + try { + const { externalId } = args; + const response = await this.transactionClient.createAuthenticateTransaction({ + appId: this.appId, + createTransactionAuthenticateRequest: { + externalId, + }, + }); + + return response.transactionId; + } catch (err) { + throw new PassageError('Could not create authenticate transaction', err as ResponseError); } } diff --git a/src/index.ts b/src/index.ts index 1bcd243..900459d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,5 +3,6 @@ export { PassageError } from './classes/PassageError'; export { AppInfo } from './models/AppInfo'; export { UserInfo } from './models/UserInfo'; export type { PassageConfig } from './types/PassageConfig'; -export type { TransactionArgs } from './types/TransactionArgs'; +export type { RegisterTransactionArgs } from './types/RegisterTransactionArgs'; +export type { AuthenticateTransactionArgs } from './types/AuthenticateTransactionArgs'; export { UserStatus, WebAuthnDevices, WebAuthnIcons, WebAuthnType } from './generated'; diff --git a/src/types/AuthenticateTransactionArgs.ts b/src/types/AuthenticateTransactionArgs.ts new file mode 100644 index 0000000..eac9bb8 --- /dev/null +++ b/src/types/AuthenticateTransactionArgs.ts @@ -0,0 +1,6 @@ +export type AuthenticateTransactionArgs = { + /** + * the user's unique identifier that will be associated with this transaction + */ + externalId: string; +}; diff --git a/src/types/TransactionArgs.ts b/src/types/RegisterTransactionArgs.ts similarity index 85% rename from src/types/TransactionArgs.ts rename to src/types/RegisterTransactionArgs.ts index 831063b..37aa8ab 100644 --- a/src/types/TransactionArgs.ts +++ b/src/types/RegisterTransactionArgs.ts @@ -1,4 +1,4 @@ -export type TransactionArgs = { +export type RegisterTransactionArgs = { /** * the user's unique identifier that will be associated with this transaction */ diff --git a/tests/Passage.test.ts b/tests/PassageFlex.test.ts similarity index 88% rename from tests/Passage.test.ts rename to tests/PassageFlex.test.ts index 4190110..b11527c 100644 --- a/tests/Passage.test.ts +++ b/tests/PassageFlex.test.ts @@ -5,7 +5,7 @@ import { WebAuthnDevices, WebAuthnType } from '../src/generated'; require('dotenv').config(); -describe('Passage', () => { +describe('PassageFlex', () => { const expectedAppId = process.env.TEST_APP_ID; const expectedApiKey = process.env.TEST_API_KEY; const userId = process.env.TEST_USER_ID; @@ -68,7 +68,7 @@ describe('Passage', () => { }); }); - describe('createTransaction', () => { + describe('createRegisterTransaction', () => { let passage: PassageFlex; beforeEach(() => { @@ -79,7 +79,7 @@ describe('Passage', () => { }); it('should return the transaction ID', async () => { - const transactionId = await passage.createTransaction({ + const transactionId = await passage.createRegisterTransaction({ externalId: 'test', passkeyDisplayName: 'test', }); @@ -87,6 +87,24 @@ describe('Passage', () => { }); }); + describe('createAuthenticateTransaction', () => { + let passage: PassageFlex; + + beforeEach(() => { + passage = new PassageFlex({ + appId: expectedAppId, + apiKey: expectedApiKey, + }); + }); + + it('should return the transaction ID', async () => { + const transactionId = await passage.createAuthenticateTransaction({ + externalId: 'test', + }); + expect(transactionId).toEqual(expect.any(String)); + }); + }); + describe('verifyNonce', () => { let passage: PassageFlex;