Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Admin 2660 - Write a script to count the number of candidates that have completed 2FA #1301

Merged
merged 3 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions functions/actions/internalReporting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { getDocuments } from '../shared/helpers.js';

export default (db, auth) => {

return {
getNumCandidatesCompleted2FASinceDate,
getCandidatesCompleted2FASinceDate,
};

/**
* Return the number of candidates who have completed 2FA since a specific date.
* If no date is supplied then its since records began
* @param {String} specifiedCutoffDate eg '2024-01-31'
* @returns
*/
async function getNumCandidatesCompleted2FASinceDate(specifiedCutoffDate = null) {
try {
let candidatesCompleted2FA = 0;
const personalDetailsRefs = [];
const candidates = await getDocuments(db.collection('candidates'));
for (const candidate of candidates) {
personalDetailsRefs.push(db.doc(`candidates/${candidate.id}/documents/personalDetails`));
}

// get personal details
const personalDetailsDocs = await db.getAll(...personalDetailsRefs, { fieldMask: ['twoFactorAuthVerifiedAt'] });
personalDetailsDocs.forEach((doc) => {
if (doc.exists) {
const personalDetails = doc.data();
if (personalDetails.twoFactorAuthVerifiedAt) {
if (!specifiedCutoffDate || (personalDetails.twoFactorAuthVerifiedAt.toDate() >= new Date(specifiedCutoffDate))) {
++candidatesCompleted2FA;
}
}
}
});

return candidatesCompleted2FA;
}
catch(e) {
console.log(e);
return false;
}
}

/**
* Return the candidates who have completed 2FA since a specific date.
* If no date is supplied then its since records began
* @param {String} specifiedCutoffDate eg '2024-01-31'
* @returns
*/
async function getCandidatesCompleted2FASinceDate(specifiedCutoffDate = null) {
try {
let candidatesCompleted2FA = [];
const personalDetailsRefs = [];
const candidates = await getDocuments(db.collection('candidates'));
for (const candidate of candidates) {
personalDetailsRefs.push(db.doc(`candidates/${candidate.id}/documents/personalDetails`));
}

// get personal details
const personalDetailsDocs = await db.getAll(...personalDetailsRefs, { fieldMask: ['fullName', 'email', 'twoFactorAuthVerifiedAt'] });
personalDetailsDocs.forEach((doc) => {
if (doc.exists) {
const personalDetails = doc.data();
if (personalDetails.twoFactorAuthVerifiedAt) {
if (!specifiedCutoffDate || (personalDetails.twoFactorAuthVerifiedAt.toDate() >= new Date(specifiedCutoffDate))) {
candidatesCompleted2FA.push([
personalDetails.fullName,
personalDetails.email,
personalDetails.twoFactorAuthVerifiedAt.toDate().toISOString().split('T')[0],
]);
}
}
}
});

return candidatesCompleted2FA;
}
catch(e) {
console.log(e);
return false;
}
}
};
54 changes: 54 additions & 0 deletions nodeScripts/internalReporting/getCandidatesCompleted2FA.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
'use strict';

/**
* Get list of candidates who have completed 2FA since a specific date
*/

import { app, db, auth } from '../shared/admin.js';
import initInternalReporting from '../../functions/actions/internalReporting.js';
import path from 'path';

import ExcelJS from 'exceljs';

const { getCandidatesCompleted2FASinceDate } = initInternalReporting(db, auth);

const exportToExcel = async (data, filePath) => {
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet('Candidates Who Completed 2FA');

// Add headers
worksheet.columns = [
{ header: 'Full Name', key: 'fullName', width: 30 },
{ header: 'Email', key: 'email', width: 50 },
{ header: '2FA Verified Date', key: 'twoFactorAuthVerifiedAt', width: 20 },
];

// Add rows from the data array
data.forEach(([ fullName, email, twoFactorAuthVerifiedAt ]) => {
worksheet.addRow({ fullName, email, twoFactorAuthVerifiedAt });
});

// Save the file
await workbook.xlsx.writeFile(filePath);
console.log(`Excel file saved at ${filePath}`);
};

const main = async () => {
const results = await getCandidatesCompleted2FASinceDate();
const fileName = 'candidates-2FA.xlsx';
const nestedDir = path.join(process.cwd(), 'nodeScripts', 'temp');
const filePath = path.join(nestedDir, fileName);
await exportToExcel(results, filePath);
return results.length;
};

main()
.then((result) => {
console.log(result);
app.delete();
return process.exit();
})
.catch((error) => {
console.error(error);
process.exit();
});
26 changes: 26 additions & 0 deletions nodeScripts/internalReporting/getNumCandidatesCompleted2FA.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

/**
* Get number of candidates who have completed 2FA since a specific date
*/

import { app, db, auth } from '../shared/admin.js';
import initInternalReporting from '../../functions/actions/internalReporting.js';

const { getNumCandidatesCompleted2FASinceDate } = initInternalReporting(db, auth);

const main = async () => {
const num = await getNumCandidatesCompleted2FASinceDate();
return num;
};

main()
.then((result) => {
console.log(result);
app.delete();
return process.exit();
})
.catch((error) => {
console.error(error);
process.exit();
});
Loading