diff --git a/package-lock.json b/package-lock.json
index 524c7c2..e7cf2f8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -43,6 +43,7 @@
"mongodb-snapshot": "^1.4.1",
"mongoose": "^7.7.0",
"nodemailer": "^6.9.14",
+ "sendgrid": "^5.2.3",
"tsc-alias": "^1.8.10",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.5.3",
@@ -3987,6 +3988,12 @@
"node": ">=0.4.0"
}
},
+ "node_modules/addressparser": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz",
+ "integrity": "sha512-aQX7AISOMM7HFE0iZ3+YnD07oIeJqWGVnJ+ZIKaBZAk03ftmVYVqsGas/rbXKR21n4D/hKCSHypvcyOkds/xzg==",
+ "license": "MIT"
+ },
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@@ -4421,6 +4428,90 @@
"integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==",
"license": "MIT"
},
+ "node_modules/async.ensureasync": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.ensureasync/-/async.ensureasync-0.5.2.tgz",
+ "integrity": "sha512-eez/kJFHbnnHUBWpYlmWcjZpho/Oh7SHwnnnuscM8nOZcIJ41t+ACMSYTfNtdrES+XfbGVQtyw+6YK2evQgV5w==",
+ "license": "MIT",
+ "dependencies": {
+ "async.util.ensureasync": "0.5.2"
+ }
+ },
+ "node_modules/async.queue": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.queue/-/async.queue-0.5.2.tgz",
+ "integrity": "sha512-SX5gCWh47bIRLqHAt/zfJmRl2xpCF4OM4kkT3HehVJLmgQfLzYjL6QhLHe+SS4e7FOYU6NgMy2kXPB2wVchncg==",
+ "license": "MIT",
+ "dependencies": {
+ "async.util.queue": "0.5.2"
+ }
+ },
+ "node_modules/async.util.arrayeach": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.arrayeach/-/async.util.arrayeach-0.5.2.tgz",
+ "integrity": "sha512-PIb4rVYjwzLqb93XX2wj0+mA9YTgSWtxQRKxtuLqxXvGj1xZMB6qJUfr1NhS+FSaMPJIE1tF40Gl/o/vlfIz/A==",
+ "license": "MIT"
+ },
+ "node_modules/async.util.ensureasync": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.ensureasync/-/async.util.ensureasync-0.5.2.tgz",
+ "integrity": "sha512-sQufNz4JYLHO/7ZUklaTGJtiX36gCp28McNNcMZfVYPm/wqi1pKk4xRCPr2DOZDM6KfA54zjG36jQjBU2mLzXg==",
+ "license": "MIT",
+ "dependencies": {
+ "async.util.restparam": "0.5.2",
+ "async.util.setimmediate": "0.5.2"
+ }
+ },
+ "node_modules/async.util.isarray": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.isarray/-/async.util.isarray-0.5.2.tgz",
+ "integrity": "sha512-wbUzlrwON8RUgi+v/rhF0U99Ce8Osjcn+JP/mFNg6ymvShcobAOvE6cvLajSY5dPqKCOE1xfdhefgBif11zZgw==",
+ "license": "MIT"
+ },
+ "node_modules/async.util.map": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.map/-/async.util.map-0.5.2.tgz",
+ "integrity": "sha512-uXZhyNIH9Jo25jn35lUoEwFLAdZWC2ZQKjLO5PLq8VAisfW6qvSfgDLH4H57/WQSKZSo6OOmuqGhtdvIHDTi1Q==",
+ "license": "MIT"
+ },
+ "node_modules/async.util.noop": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.noop/-/async.util.noop-0.5.2.tgz",
+ "integrity": "sha512-AdwShXwE0KoskgqVJAck8zcM32nIHj3AC8ZN62ZaR5srhrY235Nw18vOJZWxcOfhxdVM0hRVKM8kMx7lcl7cCQ==",
+ "license": "MIT"
+ },
+ "node_modules/async.util.onlyonce": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz",
+ "integrity": "sha512-UgQvkU9JZ+I0Cm1f56XyGXcII+J3d/5XWUuHpcevlItuA3WFSJcqZrsyAUck2FkRSD8BwYQX1zUTDp3SJMVESg==",
+ "license": "MIT"
+ },
+ "node_modules/async.util.queue": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.queue/-/async.util.queue-0.5.2.tgz",
+ "integrity": "sha512-DlKOFnhCzERL9D3bLKlNdgXwSckckcj+XkCvNuX4KMs4brBc2lHvPg8MK4NoPIhwAvUBGvE4NECdNRY0I5UOEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "async.util.arrayeach": "0.5.2",
+ "async.util.isarray": "0.5.2",
+ "async.util.map": "0.5.2",
+ "async.util.noop": "0.5.2",
+ "async.util.onlyonce": "0.5.2",
+ "async.util.setimmediate": "0.5.2"
+ }
+ },
+ "node_modules/async.util.restparam": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.restparam/-/async.util.restparam-0.5.2.tgz",
+ "integrity": "sha512-Q9Z+zgmtMxFX5i7CnBvNOkgrL5hptztCqwarQluyNudUUk4iCmyjmsQl8MuQEjNh3gGqP5ayvDaextL1VXXgIg==",
+ "license": "MIT"
+ },
+ "node_modules/async.util.setimmediate": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.setimmediate/-/async.util.setimmediate-0.5.2.tgz",
+ "integrity": "sha512-aCYF85ZFCQ9Xn0106GcOVx+LvFguIIzfbfRTOlQoie3G4KeSjURfA6f7CfpFAF09FNP2A1MtdjeFdvYeTGDebw==",
+ "license": "MIT"
+ },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -4589,6 +4680,12 @@
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
"license": "MIT"
},
+ "node_modules/bottleneck": {
+ "version": "1.16.0",
+ "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-1.16.0.tgz",
+ "integrity": "sha512-HinT6aCt+ZLPVvMtOy8Vd1vQtR2R/Qi06fKRCa4oGiIuFF+CQwNYR/KZTjrEynkER7y9WaY8fhwWKqZp+/aXeg==",
+ "license": "MIT"
+ },
"node_modules/bowser": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
@@ -5278,6 +5375,17 @@
"node": ">=6.6.0"
}
},
+ "node_modules/core-js": {
+ "version": "3.45.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.45.0.tgz",
+ "integrity": "sha512-c2KZL9lP4DjkN3hk/an4pWn5b5ZefhRJnAc42n6LJ19kSnbeRbdQZE5dSeE2LBol1OwJD3X1BQvFTAsa8ReeDA==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
"node_modules/core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@@ -5988,7 +6096,6 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.0"
@@ -9175,6 +9282,12 @@
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
"license": "MIT"
},
+ "node_modules/lodash.chunk": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz",
+ "integrity": "sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w==",
+ "license": "MIT"
+ },
"node_modules/lodash.defaults": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
@@ -9342,6 +9455,19 @@
"node": ">=16.14"
}
},
+ "node_modules/mailparser": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-0.6.2.tgz",
+ "integrity": "sha512-5Z5nv7TYojrdrKHjhCOKKFaYs0Lo7PCja4RnLZ2kFE1Fskqg+rRVwFpG9Oqx3YjosGM2QEItjHo7+Jc9qvxGqw==",
+ "deprecated": "Mailparser versions older than v2.3.0 are deprecated",
+ "license": "MIT",
+ "dependencies": {
+ "encoding": "^0.1.12",
+ "mime": "^1.3.4",
+ "mimelib": "^0.3.0",
+ "uue": "^3.1.0"
+ }
+ },
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@@ -9461,6 +9587,18 @@
"node": ">=8.6"
}
},
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -9482,6 +9620,17 @@
"node": ">= 0.6"
}
},
+ "node_modules/mimelib": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/mimelib/-/mimelib-0.3.1.tgz",
+ "integrity": "sha512-ipzNp6TBsNfD3hButGlPVlGmuCgybIM9SBf8YwIG+SYmBgtU0u8wjf+BSrJX0mvqtv59SLmwphw/XiCbkLWv7w==",
+ "deprecated": "This project is unmaintained",
+ "license": "EUPL-1.1",
+ "dependencies": {
+ "addressparser": "~1.0.1",
+ "encoding": "~0.1.12"
+ }
+ },
"node_modules/mimic-fn": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
@@ -11930,6 +12079,62 @@
"node": ">=10"
}
},
+ "node_modules/sendgrid": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/sendgrid/-/sendgrid-5.2.3.tgz",
+ "integrity": "sha512-FD7oR9TbJFUew1p0Vw9JX0wBetDyq634LzylSXz4n9+hwaf+6a9dNloZl8CcjpsX4NuEc3HJanTN4GjDwNyi4A==",
+ "deprecated": "Please see v6.X+ at https://www.npmjs.com/org/sendgrid",
+ "license": "MIT",
+ "dependencies": {
+ "async.ensureasync": "^0.5.2",
+ "async.queue": "^0.5.2",
+ "bottleneck": "^1.12.0",
+ "debug": "^2.2.0",
+ "lodash.chunk": "^4.2.0",
+ "mailparser": "^0.6.1",
+ "sendgrid-rest": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/sendgrid-rest": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/sendgrid-rest/-/sendgrid-rest-2.6.1.tgz",
+ "integrity": "sha512-W7gPROAPkEiD3+XQh+jeiU5mTNWqfgn45y1Xi8WiFA3CYKGOvHn+U0d62pTWjjynNqsmQIq9AJ0+93Bq67gbSQ==",
+ "license": "MIT",
+ "dependencies": {
+ "core-js": "^3.5.0",
+ "dotenv": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/sendgrid-rest/node_modules/dotenv": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz",
+ "integrity": "sha512-XcaMACOr3JMVcEv0Y/iUM2XaOsATRZ3U1In41/1jjK6vJZ2PZbQ1bzCG8uvaByfaBpl9gqc9QWJovpUGBXLLYQ==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.6.0"
+ }
+ },
+ "node_modules/sendgrid/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/sendgrid/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
"node_modules/seq-queue": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
@@ -13486,6 +13691,16 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"license": "MIT"
},
+ "node_modules/uue": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/uue/-/uue-3.1.2.tgz",
+ "integrity": "sha512-axKLXVqwtdI/czrjG0X8hyV1KLgeWx8F4KvSbvVCnS+RUvsQMGRjx0kfuZDXXqj0LYvVJmx3B9kWlKtEdRrJLg==",
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "~1.0.5",
+ "extend": "~3.0.0"
+ }
+ },
"node_modules/uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
diff --git a/package.json b/package.json
index 3ddff32..a48d218 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,7 @@
"mongodb-snapshot": "^1.4.1",
"mongoose": "^7.7.0",
"nodemailer": "^6.9.14",
+ "sendgrid": "^5.2.3",
"tsc-alias": "^1.8.10",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.5.3",
diff --git a/v2/scripts/generate_password.py b/v2/scripts/generate_password.py
index 648af1e..0d46306 100644
--- a/v2/scripts/generate_password.py
+++ b/v2/scripts/generate_password.py
@@ -29,7 +29,7 @@ def generate_passwords(input_file, output_file):
writer.writerow(row)
if __name__ == "__main__":
- input_file = "./csv/points_display/points.csv" # Change this to your input CSV file
- output_file = "./csv/points_display/passworded.csv" # Change this to your output CSV file
+ input_file = "./csv/ccaUsers.csv" # Change this to your input CSV file
+ output_file = "./csv/passworded.csv" # Change this to your output CSV file
generate_passwords(input_file, output_file)
\ No newline at end of file
diff --git a/v2/scripts/ccaConvert.ts b/v2/scripts/helpers/cca/ccaConvert.ts
similarity index 98%
rename from v2/scripts/ccaConvert.ts
rename to v2/scripts/helpers/cca/ccaConvert.ts
index 12ffaab..85dbec3 100644
--- a/v2/scripts/ccaConvert.ts
+++ b/v2/scripts/helpers/cca/ccaConvert.ts
@@ -20,7 +20,7 @@ function convert(s: string): string[] {
async function run() {
await mongoose.connect(process.env.MONGO_URI);
- const csvFilePath = "./v2/scripts/csv/ccaData.csv";
+ const csvFilePath = "./v2/scripts/csv/ccaData_2526.csv";
const fileContent = fs.readFileSync(csvFilePath, { encoding: "utf-8" });
parse(
diff --git a/v2/scripts/helpers/cca/createSubcommittee.ts b/v2/scripts/helpers/cca/createSubcommittee.ts
new file mode 100644
index 0000000..bf923ee
--- /dev/null
+++ b/v2/scripts/helpers/cca/createSubcommittee.ts
@@ -0,0 +1,19 @@
+/* eslint-disable no-console */
+import { Cca } from "@/v2/models/cca/cca";
+import { CcaSubcommittee } from "@/v2/models/cca/ccaSubcommittee";
+import mongoose from "mongoose";
+
+const { env } = process;
+
+async function run() {
+ await mongoose.connect(env.MONGO_URI);
+
+ const cca = await Cca.findOne({ name: "Dance Production" });
+ await CcaSubcommittee.create({ name: `Assistant Stage Manager`, cca, description: "" });
+ await CcaSubcommittee.create({ name: `Assistant Production Manager`, cca, description: "" });
+ console.log(`Finished.`);
+}
+
+run();
+
+export {};
diff --git a/v2/scripts/helpers/cca/createUsers.ts b/v2/scripts/helpers/cca/createUsers.ts
new file mode 100644
index 0000000..a5f9e77
--- /dev/null
+++ b/v2/scripts/helpers/cca/createUsers.ts
@@ -0,0 +1,79 @@
+/* eslint-disable no-console */
+
+/* eslint-disable no-restricted-syntax */
+
+/* eslint-disable no-await-in-loop */
+import { User } from "@/v2/models/user";
+import type { iUser } from "@/v2/models/user";
+import bcrypt from "bcrypt";
+import { parse } from "csv-parse";
+import * as fs from "fs";
+import mongoose from "mongoose";
+
+const SALT_ROUNDS = 10;
+
+interface Data {
+ username: string;
+ // role: string;
+ // gender: "Male" | "Female";
+ year: number;
+ room: string;
+ // id: string;
+ email: string;
+ password: string;
+}
+
+async function hashPassword(password: string) {
+ const hashedPw = await bcrypt.hash(password, SALT_ROUNDS);
+ return hashedPw;
+}
+
+(async () => {
+ await mongoose.connect(process.env.MONGO_URI);
+ const csvFilePath = "./v2/scripts/csv/passworded.csv";
+ const fileContent = fs.readFileSync(csvFilePath, { encoding: "utf-8" });
+
+ parse(
+ fileContent,
+ {
+ delimiter: ",",
+ columns: true,
+ },
+ async (error, result: Data[]) => {
+ if (error) {
+ console.error(error);
+ }
+ const res: iUser[] = [];
+ for (const user of result) {
+ user.password = await hashPassword(user.password);
+ user.year = 0;
+ res.push({
+ ...user,
+ gender: ["1", "4"].includes(user.username[1]) ? "male" : "female",
+ } as iUser);
+ }
+ const session = await mongoose.startSession();
+
+ await session.startTransaction({
+ readConcern: { level: `snapshot` },
+ writeConcern: { w: `majority`, j: true },
+ });
+ try {
+ await User.create(res, { session });
+
+ try {
+ await session.commitTransaction();
+ } catch (e) {
+ await session.abortTransaction();
+ console.error(e);
+ }
+ } catch (e) {
+ console.error(e);
+ } finally {
+ await session.endSession();
+ }
+
+ console.log(`Finished.`);
+ },
+ );
+})();
diff --git a/v2/scripts/helpers/cca/mail_password.ts b/v2/scripts/helpers/cca/mail_password.ts
new file mode 100644
index 0000000..b3e4067
--- /dev/null
+++ b/v2/scripts/helpers/cca/mail_password.ts
@@ -0,0 +1,123 @@
+/* eslint-disable no-console */
+
+/* eslint-disable no-restricted-syntax */
+
+/* eslint-disable no-await-in-loop */
+import { parse } from "csv-parse";
+import * as fs from "fs";
+import nodemailer from "nodemailer";
+import readline from "readline";
+
+const rl = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout,
+});
+
+interface Data {
+ username: string;
+ email: string;
+ // id: string;
+ password: string;
+}
+
+const transport = nodemailer.createTransport({
+ host: "smtp.sendgrid.net",
+ port: 465,
+ secure: true,
+ // service: "Outlook365",
+ auth: {
+ user: "apikey",
+ pass: process.env.SENDGRID_API,
+ },
+});
+
+async function mail(user: Data) {
+ try {
+ const { username, password, email } = user;
+ const template = `
+
+
+
+
+
+ Account Details
+
+
+
+
+
+
+
+
+
+
+ Welcome to Eusoff!
+ Eusoff Hackers welcomes you to a new AY in Eusoff! We will be in charge of collecting your details for CCA Signup. Here are your account details for CCA Signup:
+
+ Username: ${username}
+ Password: ${password}
+
+
+ Visit the Website
+
+ You will be able to log in to the site and indicate your preferences now! For further questions, you can directly ask @juancarlovieri on Telegram
+ If you are not the intended recipient of this email, please reply to this email immediately.
+
+ To an awesome year in Eusoff, Eusoff Hackers
+ |
+
+
+ |
+
+
+
+
+
+ `;
+
+ console.log(`Sending email to: ${username}`);
+ await transport.sendMail({
+ from: process.env.EMAIL, // sender address
+ to: email, // list of receivers
+ subject: "Credentials for CCA Signup", // Subject line
+ // text: mail.password, // plain text body
+ html: template, // html body
+ });
+ console.log(`Email to ${username} sent.`);
+ } catch (error) {
+ console.error(`Mailing error `, error);
+ }
+}
+
+function sleep(ms: number) {
+ return new Promise((resolve) => setTimeout(resolve, ms));
+}
+
+(async () => {
+ const csvFilePath = "./v2/scripts/csv/passworded.csv";
+ const fileContent = fs.readFileSync(csvFilePath, { encoding: "utf-8" });
+
+ parse(
+ fileContent,
+ {
+ delimiter: ",",
+ columns: true,
+ },
+ async (error, result: Data[]) => {
+ console.error(error);
+ mail(result.filter((u) => ["C422"].includes(u.username))[0]);
+ const answer = await new Promise((resolve) => {
+ rl.question(`Found ${result.length} documents containing user and password. Send? (y/n) `, resolve);
+ });
+
+ if (answer !== `y`) return;
+
+ for (const user of result) {
+ await mail(user);
+ await sleep(1000);
+ }
+
+ console.log(`Finished.`);
+ },
+ );
+})();