Skip to content

Commit

Permalink
Implement script for seeding initial admin account
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielMajeri committed May 19, 2024
1 parent 2412bac commit 91160de
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 16 deletions.
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
"prisma:push": "dotenv -e .env.development -- npx prisma db push",
"prisma:migrate": "dotenv -e .env.development -- npx prisma migrate dev",
"prisma:generate": "dotenv -e .env.development -- npx prisma generate",
"seed:admin": "dotenv -e .env.development -e .env.local -- ts-node --project tsconfig.seed.json prisma/seed-admin.ts",
"seed:dev": "dotenv -e .env.development -- ts-node --project tsconfig.seed.json prisma/seed-dev.ts"
},
"dependencies": {
"@azure/identity": "^4.0.1",
"@azure/msal-browser": "^3.10.0",
"@azure/msal-node": "^2.7.0",
"@hookform/resolvers": "^3.3.4",
"@microsoft/microsoft-graph-client": "^3.0.7",
Expand Down
3 changes: 1 addition & 2 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ datasource db {
}

enum Role {
appAdmin @map("app_admin")
taxesAdmin @map("taxes_admin")
appAdmin @map("app_admin")
}

model User {
Expand Down
111 changes: 111 additions & 0 deletions prisma/seed-admin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import msal from "@azure/msal-node";
import {
AuthProvider,
AuthProviderCallback,
Client,
} from "@microsoft/microsoft-graph-client";
import { PrismaClient, Role } from "@prisma/client";
import { createInterface as readlineCreateInterface } from "readline";
import { stdin as input, stdout as output } from "process";

const MICROSOFT_GRAPH_ENDPOINT = "https://graph.microsoft.com/";

async function acquireAccessToken() {
const tenantId = process.env.AZURE_AD_TENANT_ID;
const clientId = process.env.AZURE_AD_CLIENT_ID;
const clientSecret = process.env.AZURE_AD_CLIENT_SECRET;

if (!tenantId) {
throw Error("Entra ID tenant ID is missing");
}

if (!clientId) {
throw Error("Entra ID client ID is missing");
}

if (!clientSecret) {
throw Error("Entra ID client secret is missing");
}

const msalConfig = {
auth: {
authority: `https://login.microsoftonline.com/${tenantId}`,
clientId,
clientSecret,
},
};

const tokenRequest = {
scopes: [`${MICROSOFT_GRAPH_ENDPOINT}/.default`],
};

const cca = new msal.ConfidentialClientApplication(msalConfig);

return await cca.acquireTokenByClientCredential(tokenRequest);
}

const prisma = new PrismaClient();

async function main() {
const authenticationResult = await acquireAccessToken();
if (!authenticationResult) {
throw Error("Failed to acquire access token for MSAL API");
}

const { accessToken } = authenticationResult;

const rl = readlineCreateInterface({ input, output });

rl.question(
"New admin user institutional e-mail address: ",
async (email: string) => {
const authProvider: AuthProvider = async (
callback: AuthProviderCallback,
) => callback(null, accessToken);

const client = Client.init({ authProvider });

let userInfo;
try {
userInfo = await client
.api(`/users/${email}?$select=id,displayName`)
.get();
} catch (exception) {
throw new Error(
`Failed to get user data from Microsoft 365: ${exception}`,
);
}

if (!userInfo || !userInfo["id"]) {
throw new Error("User with given e-mail address could not be found");
}

try {
const newUser = await prisma.user.create({
data: {
azureAdObjectId: userInfo["id"],
role: Role.appAdmin,
},
});

console.log(
`Successfully created admin account associated to user with ID ${newUser.azureAdObjectId}, full name ${userInfo["displayName"]}`,
);
} catch (exception) {
console.error(`Failed to create user in database: ${exception}`);
}

rl.close();
},
);
}

main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
12 changes: 0 additions & 12 deletions prisma/seed-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,6 @@ async function main() {
studentDorms.push(studentDorm);
}

// Insert 5 User records
const users = [];
for (let i = 1; i <= 25; i++) {
const user = await prisma.user.create({
data: {
azureAdObjectId: `UserObjectID${i}`,
role: i % 2 === 0 ? Role.appAdmin : Role.taxesAdmin, // Alternate between roles
},
});
users.push(user);
}

const facultyTaxValues = [];
for (let i = 1; i <= 25; i++) {
let studyCycle: StudyCycle = StudyCycle.bachelors;
Expand Down

0 comments on commit 91160de

Please sign in to comment.