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.`); + }, + ); +})();