diff --git a/packages/fxa-shared/connected-services/factories.ts b/packages/fxa-shared/connected-services/factories.ts index 685de66723f..fc5ae2d051b 100644 --- a/packages/fxa-shared/connected-services/factories.ts +++ b/packages/fxa-shared/connected-services/factories.ts @@ -257,7 +257,7 @@ export class ConnectedServicesFactory { // We fill in a default device name from the OAuth client name, // but individual clients can override this in their device record registration. if (!client.name) { - client.name = oauthClient.client_name; + client.name = oauthClient.client_name ?? null; } // For now we assume that all oauth clients that register a device record are mobile apps. // Ref https://github.com/mozilla/fxa/issues/449 @@ -277,7 +277,7 @@ export class ConnectedServicesFactory { refreshTokenId: null, deviceId: device.id, deviceType: device.type, - name: device.name, + name: device.name ?? null, createdTime: device.createdAt, lastAccessTime: device.lastAccessTime, }; @@ -292,6 +292,6 @@ export class ConnectedServicesFactory { } protected getDefaultClientFields(): AttachedClient { - return attachedClientsDefaults; + return { ...attachedClientsDefaults }; } } diff --git a/packages/fxa-shared/test/connected-services/factories.ts b/packages/fxa-shared/test/connected-services/factories.ts index 69c460bb640..a88c2f3e9ae 100644 --- a/packages/fxa-shared/test/connected-services/factories.ts +++ b/packages/fxa-shared/test/connected-services/factories.ts @@ -193,5 +193,44 @@ describe('connected-services/factories', () => { Sinon.assert.calledOnce(bStubbed.oauthClients); Sinon.assert.calledOnce(bStubbed.sessions); }); + + it('coerces undefined device name to null', async () => { + deviceList = [ + { + id: 'test-device', + sessionTokenId: 'test', + name: undefined as any, // Simulate undefined from database + pushEndpointExpired: false, + availableCommands: {}, + location: {}, + } as AttachedDevice, + ]; + oauthClients = []; + sessions = []; + + const results = await factory.build('1234', 'en'); + + assert.strictEqual(results[0].name, null); + }); + + it('coerces undefined client_name to null', async () => { + oauthClients = [ + { + refresh_token_id: 'test-oauth', + created_time: Date.now(), + last_access_time: Date.now(), + client_name: undefined as any, // Simulate undefined from database + client_id: null as any, + scope: null as any, + } as AttachedOAuthClient, + ]; + deviceList = []; + sessions = []; + + const results = await factory.build('1234', 'en'); + + // Verify name is null, not undefined (required for validation) + assert.strictEqual(results[0].name, null); + }); }); });