diff --git a/src/app/controllers/spcp.server.controller.js b/src/app/controllers/spcp.server.controller.js index d2bb108676..c82c35b89a 100644 --- a/src/app/controllers/spcp.server.controller.js +++ b/src/app/controllers/spcp.server.controller.js @@ -22,26 +22,6 @@ const jwtNames = { } const destinationRegex = /^\/([\w]+)\/?/ -const addLoginToDB = function (form) { - let login = new Login({ - form: form._id, - admin: form.admin._id, - agency: form.admin.agency._id, - authType: form.authType, - esrvcId: form.esrvcId, - }) - return login.save().catch((err) => { - logger.error({ - message: 'Error adding login to database', - meta: { - action: 'addLoginToDB', - formId: form._id, - }, - error: err, - }) - }) -} - const getForm = function (destination, cb) { let formId = destinationRegex.exec(destination)[1] Form.findById({ _id: formId }) @@ -176,7 +156,7 @@ const handleOOBAuthenticationWith = (ndiConfig, authType, extractUser) => { // NOTE: cookieDuration is interpreted as a seconds count if numeric. ) // Add login to DB - addLoginToDB(form).then(() => { + Login.addLoginFromForm(form).then(() => { const spcpSettings = spcpCookieDomain ? { domain: spcpCookieDomain, path: '/' } : {} diff --git a/src/app/models/login.server.model.ts b/src/app/models/login.server.model.ts index c98575e0a7..d8c6ade6cb 100644 --- a/src/app/models/login.server.model.ts +++ b/src/app/models/login.server.model.ts @@ -4,6 +4,7 @@ import { AuthType, ILoginModel, ILoginSchema, + IPopulatedForm, LoginStatistic, } from '../../types' @@ -52,6 +53,24 @@ const LoginSchema = new Schema( }, ) +LoginSchema.statics.addLoginFromForm = function ( + this: ILoginModel, + form: IPopulatedForm, +): Promise { + if (!form.authType || !form.esrvcId) { + return Promise.reject( + new Error('Form does not contain authType or e-service ID'), + ) + } + return this.create({ + form: form._id, + admin: form.admin._id, + agency: form.admin.agency._id, + authType: form.authType, + esrvcId: form.esrvcId, + }) +} + LoginSchema.statics.aggregateLoginStats = function ( this: ILoginModel, esrvcId: string, diff --git a/src/types/login.ts b/src/types/login.ts index 5d362c9dd5..43784350ea 100644 --- a/src/types/login.ts +++ b/src/types/login.ts @@ -1,7 +1,7 @@ import { Document, Model } from 'mongoose' import { IAgencySchema } from './agency' -import { AuthType, IFormSchema } from './form' +import { AuthType, IFormSchema, IPopulatedForm } from './form' import { IUserSchema } from './user' export interface ILogin { @@ -32,4 +32,5 @@ export interface ILoginModel extends Model { gte: Date, lte: Date, ) => Promise + addLoginFromForm: (form: IPopulatedForm) => Promise } diff --git a/tests/unit/backend/models/login.server.model.spec.ts b/tests/unit/backend/models/login.server.model.spec.ts index 0ed8c754b0..c7020fdb9c 100644 --- a/tests/unit/backend/models/login.server.model.spec.ts +++ b/tests/unit/backend/models/login.server.model.spec.ts @@ -5,7 +5,13 @@ import moment from 'moment-timezone' import mongoose from 'mongoose' import getLoginModel from 'src/app/models/login.server.model' -import { AuthType, IFormSchema, ILogin, IUserSchema } from 'src/types' +import { + AuthType, + IFormSchema, + ILogin, + IPopulatedForm, + IUserSchema, +} from 'src/types' import dbHandler from '../helpers/jest-db' @@ -114,6 +120,54 @@ describe('login.server.model', () => { }) describe('Statics', () => { + describe('addLoginFromForm', () => { + const adminId = new ObjectId() + const formId = new ObjectId() + const agencyId = new ObjectId() + const mockEsrvcId = 'esrvcid' + const mockAuthType = 'SP' + const fullForm = ({ + _id: formId, + admin: { + _id: adminId, + agency: { + _id: agencyId, + }, + }, + authType: mockAuthType, + esrvcId: mockEsrvcId, + } as unknown) as IPopulatedForm + + it('should save the correct form data', async () => { + const saved = await LoginModel.addLoginFromForm(fullForm) + const found = await LoginModel.findOne({ form: formId }) + // Returned document should match + expect(saved.form).toEqual(formId) + expect(saved.admin).toEqual(adminId) + expect(saved.agency).toEqual(agencyId) + expect(saved.authType).toBe(mockAuthType) + expect(saved.esrvcId).toBe(mockEsrvcId) + // Found document should match + expect(found!.form).toEqual(formId) + expect(found!.admin).toEqual(adminId) + expect(found!.agency).toEqual(agencyId) + expect(found!.authType).toBe(mockAuthType) + expect(found!.esrvcId).toBe(mockEsrvcId) + }) + + it('should reject when the form does not contain an e-service ID', async () => { + await expect( + LoginModel.addLoginFromForm(omit(fullForm, 'esrvcId')), + ).rejects.toThrow('Form does not contain authType or e-service ID') + }) + + it('should reject when the form does not contain an authType', async () => { + await expect( + LoginModel.addLoginFromForm(omit(fullForm, 'authType')), + ).rejects.toThrow('Form does not contain authType or e-service ID') + }) + }) + describe('aggregateLoginStats', () => { const VALID_ESRVC_ID = 'MOCK-ESRVC-ID' const CURR_MOMENT = moment()