ENCOA-147: Uploading a batch of multiple users is now unrestricted by firebase auth request quotas
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import {initializeApp} from "firebase/app";
|
||||
import * as admin from "firebase-admin/app";
|
||||
import {getStorage} from "firebase/storage";
|
||||
import { base64 } from "@firebase/util";
|
||||
|
||||
const stagingServiceAccount = require("@/constants/staging.json");
|
||||
const platformServiceAccount = require("@/constants/platform.json");
|
||||
@@ -22,3 +23,10 @@ export const adminApp = admin.initializeApp(
|
||||
Math.random().toString(),
|
||||
);
|
||||
export const storage = getStorage(app);
|
||||
|
||||
export const firebaseAuthScryptParams = {
|
||||
memCost: Number(process.env.FIREBASE_SCRYPT_MEM_COST),
|
||||
rounds: Number(process.env.FIREBASE_SCRYPT_ROUNDS),
|
||||
saltSeparator: process.env.FIREBASE_SCRYPT_B64_SALT_SEPARATOR!,
|
||||
signerKey: process.env.FIREBASE_SCRYPT_B64_SIGNER_KEY!,
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ export default function BatchCreateUser({user, users, permissions, onFinish}: Pr
|
||||
demographicInformation: {
|
||||
country: countryItem?.countryCode,
|
||||
passport_id: passport_id?.toString().trim() || undefined,
|
||||
phone,
|
||||
phone: phone.toString(),
|
||||
},
|
||||
}
|
||||
: undefined;
|
||||
@@ -161,7 +161,7 @@ export default function BatchCreateUser({user, users, permissions, onFinish}: Pr
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
for (const newUser of newUsers) await axios.post("/api/make_user", {...newUser, type, expiryDate});
|
||||
await axios.post("/api/batch_users", { users: newUsers.map(user => ({...user, type, expiryDate})) });
|
||||
toast.success(`Successfully added ${newUsers.length} user(s)!`);
|
||||
onFinish();
|
||||
} catch {
|
||||
|
||||
61
src/pages/api/batch_users.ts
Normal file
61
src/pages/api/batch_users.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import type {NextApiRequest, NextApiResponse} from "next";
|
||||
import {withIronSessionApiRoute} from "iron-session/next";
|
||||
import {sessionOptions} from "@/lib/session";
|
||||
import { FirebaseScrypt } from 'firebase-scrypt';
|
||||
import { firebaseAuthScryptParams } from "@/firebase";
|
||||
import crypto from 'crypto';
|
||||
import axios from "axios";
|
||||
|
||||
export default withIronSessionApiRoute(handler, sessionOptions);
|
||||
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method === "POST") return post(req, res);
|
||||
|
||||
return res.status(404).json({ok: false});
|
||||
}
|
||||
|
||||
async function post(req: NextApiRequest, res: NextApiResponse) {
|
||||
const maker = req.session.user;
|
||||
if (!maker) {
|
||||
return res.status(401).json({ok: false, reason: "You must be logged in to make user!"});
|
||||
}
|
||||
|
||||
const scrypt = new FirebaseScrypt(firebaseAuthScryptParams)
|
||||
|
||||
const users = req.body.users as {
|
||||
email: string;
|
||||
name: string;
|
||||
type: string;
|
||||
passport_id: string;
|
||||
groupName?: string;
|
||||
corporate?: string;
|
||||
studentID?: string;
|
||||
expiryDate?: string;
|
||||
demographicInformation: {
|
||||
country?: string;
|
||||
passport_id?: string;
|
||||
phone: string;
|
||||
};
|
||||
passwordHash: string | undefined;
|
||||
passwordSalt: string | undefined;
|
||||
}[];
|
||||
|
||||
const usersWithPasswordHashes = await Promise.all(users.map(async (user) => {
|
||||
const currentUser = { ...user };
|
||||
const salt = crypto.randomBytes(16).toString('base64');
|
||||
const hash = await scrypt.hash(user.passport_id, salt);
|
||||
|
||||
currentUser.email = currentUser.email.toLowerCase();
|
||||
currentUser.passwordHash = hash;
|
||||
currentUser.passwordSalt = salt;
|
||||
return currentUser;
|
||||
}));
|
||||
|
||||
const backendRequest = await axios.post(`${process.env.BACKEND_URL}/batch_users`, { makerID: maker.id, users: usersWithPasswordHashes }, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.BACKEND_JWT}`,
|
||||
},
|
||||
});
|
||||
|
||||
return res.status(backendRequest.status).json(backendRequest.data)
|
||||
}
|
||||
Reference in New Issue
Block a user