diff --git a/passkeys-backend/functions/registration/start.js b/passkeys-backend/functions/registration/start.js index 5b8e7980..1d946b7f 100644 --- a/passkeys-backend/functions/registration/start.js +++ b/passkeys-backend/functions/registration/start.js @@ -35,9 +35,12 @@ exports.handler = async (context, event, callback) => { name: 'PasskeySample', origins: [ `https://${RELYING_PARTY}`, - ...(ANDROID_APP_KEYS.split(',') || []), + ...(ANDROID_APP_KEYS?.split(',') ?? []), ], }, + user: { + display_name: event.username, + }, authenticator_criteria: { authenticator_attachment: 'platform', discoverable_credentials: 'preferred', diff --git a/passkeys-backend/tests/registration-start.test.js b/passkeys-backend/tests/registration-start.test.js index 097df955..634a8ad6 100644 --- a/passkeys-backend/tests/registration-start.test.js +++ b/passkeys-backend/tests/registration-start.test.js @@ -1,9 +1,13 @@ +/* eslint-disable camelcase */ + const axios = require('axios'); const helpers = require('../../test/test-helper'); jest.mock('axios'); const mockContext = { + API_URL: 'https://api.com', + RELYING_PARTY: 'example.com', ANDROID_APP_KEYS: 'key1,key2,key3', getTwilioClient: () => ({ username: 'mockUsername', @@ -11,6 +15,28 @@ const mockContext = { }), }; +const mockRequestBody = { + friendly_name: 'Passkey Example', + to: { + user_identifier: 'user001', + }, + content: { + relying_party: { + id: 'example.com', + name: 'PasskeySample', + origins: [`https://example.com`], + }, + user: { + display_name: 'user001', + }, + authenticator_criteria: { + authenticator_attachment: 'platform', + discoverable_credentials: 'preferred', + user_verification: 'preferred', + }, + }, +}; + describe('registration/start', () => { beforeAll(() => { jest.clearAllMocks(); @@ -52,12 +78,48 @@ describe('registration/start', () => { done(); }; + handlerFunction(mockContext, { username: 'user001' }, callback); + }); + + it('works with empty ANDROID_APP_KEYS', (done) => { + const callback = (_, { _body }) => { + expect(axios.post).toHaveBeenCalledWith( + 'https://api.com/Factors', + mockRequestBody, + { auth: { password: 'mockPassword', username: 'mockUsername' } } + ); + done(); + }; + + const mockContextWithoutAndroidKeys = { + API_URL: 'https://api.com', + RELYING_PARTY: 'example.com', + getTwilioClient: () => ({ + username: 'mockUsername', + password: 'mockPassword', + }), + }; + handlerFunction( - mockContext, - { - username: 'test-username', - }, + mockContextWithoutAndroidKeys, + { username: 'user001' }, callback ); }); + + it('calls the API with the expected request body', (done) => { + const modifiedRequest = structuredClone(mockRequestBody); + modifiedRequest.content.relying_party.origins.push('key1', 'key2', 'key3'); + + const callback = (_, result) => { + expect(axios.post).toHaveBeenCalledWith( + 'https://api.com/Factors', + modifiedRequest, + { auth: { password: 'mockPassword', username: 'mockUsername' } } + ); + done(); + }; + + handlerFunction(mockContext, { username: 'user001' }, callback); + }); });