Files

268 lines
7.0 KiB
JavaScript

process.env.NODE_ENV === "development"
? require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` })
: require("dotenv").config();
const { SystemSettings } = require("../models/systemSettings");
const { Telemetry } = require("../models/telemetry");
const { User } = require("../models/user");
const { reqBody, makeJWT } = require("../utils/http");
const bcrypt = require("bcrypt");
function authenticationEndpoints(app) {
if (!app) return;
app.get("/auth/auto-onboard", async (_, response) => {
try {
const completeSetup = (await User.count({ role: "admin" })) > 0;
if (completeSetup) {
response.status(200).json({ completed: true });
return;
}
const onboardingUser = await User.get({ role: "root" });
if (!onboardingUser) {
response.status(200).json({ completed: true });
return;
}
await Telemetry.sendTelemetry("onboarding_complete"); // Have to send here since we have no other hooks.
response.status(200).json({
valid: true,
user: onboardingUser,
token: makeJWT(
{ id: onboardingUser.id, email: onboardingUser.email },
"1hr"
),
message: null,
});
} catch (e) {
console.log(e.message, e);
response.sendStatus(500).end();
}
});
app.post("/auth/login", async (request, response) => {
try {
const { email, password } = reqBody(request);
if (!email || !password) {
response.status(200).json({
user: null,
valid: false,
token: null,
message: "[002] No email or password provided.",
});
return;
}
if (email === process.env.SYS_EMAIL) {
const completeSetup = (await User.count({ role: "admin" })) > 0;
if (completeSetup) {
response.status(200).json({
user: null,
valid: false,
token: null,
message: "[004] Invalid login credentials.",
});
return;
}
}
const existingUser = await User.get({ email: email });
if (!existingUser) {
response.status(200).json({
user: null,
valid: false,
token: null,
message: "[001] Invalid login credentials.",
});
return;
}
if (!bcrypt.compareSync(password, existingUser.password)) {
response.status(200).json({
user: null,
valid: false,
token: null,
message: "[002] Invalid login credentials.",
});
return;
}
await Telemetry.sendTelemetry("login_event");
response.status(200).json({
valid: true,
user: existingUser,
token: makeJWT(
{ id: existingUser.id, email: existingUser.email },
"30d"
),
message: null,
});
return;
} catch (e) {
console.log(e.message, e);
response.sendStatus(500).end();
}
});
app.post("/auth/create-account", async (request, response) => {
try {
const { email, password } = reqBody(request);
if (!email || !password) {
response.status(200).json({
user: null,
valid: false,
token: null,
message: "[002] No email or password provided.",
});
return;
}
const adminCount = await User.count({ role: "admin" });
if (adminCount === 0) {
response.status(200).json({
user: null,
valid: false,
token: null,
message:
"[000] System setup has not been completed - account creation disabled.",
});
return;
}
const existingUser = await User.get({ email });
if (!!existingUser) {
response.status(200).json({
user: null,
valid: false,
token: null,
message: "[001] Account already exists by this email - use another.",
});
return;
}
const allowingAccounts = await SystemSettings.get({
label: "allow_account_creation",
});
if (
!!allowingAccounts &&
allowingAccounts.value !== null &&
allowingAccounts.value === "false"
) {
response.status(200).json({
user: null,
valid: false,
token: null,
message: "[003] Access denied.",
});
return;
}
const domainRestriction = await SystemSettings.get({
label: "account_creation_domain_scope",
});
if (domainRestriction && domainRestriction.value) {
const emailDomain = email.substring(email.lastIndexOf("@") + 1);
if (emailDomain !== domainRestriction.value) {
response.status(200).json({
user: null,
valid: false,
token: null,
message: "[003] Invalid account creation values.",
});
return;
}
}
const { user, message } = await User.create({ email, password });
if (!user) {
response.status(200).json({
user: null,
valid: false,
token: null,
message,
});
return;
}
await User.addToAllOrgs(user.id);
await Telemetry.sendTelemetry("login_event");
response.status(200).json({
user,
valid: true,
token: makeJWT({ id: user.id, email: user.email }, "30d"),
message: null,
});
return;
} catch (e) {
console.log(e.message, e);
response.sendStatus(500).end();
}
});
app.post("/auth/transfer-root", async (request, response) => {
try {
const { email, password } = reqBody(request);
if (!email || !password) {
response.status(200).json({
user: null,
valid: false,
token: null,
message: "[002] No email or password provided.",
});
return;
}
const adminCount = await User.count({ role: "admin" });
if (adminCount > 0) {
response.status(200).json({
user: null,
valid: false,
token: null,
message:
"[000] System setup has already been completed - you cannot do this again.",
});
return;
}
const existingUser = await User.get({ email });
if (!!existingUser) {
response.status(200).json({
user: null,
valid: false,
token: null,
message: "[001] Account already exists by this email - use another.",
});
return;
}
const { user, message } = await User.create({
email,
password,
role: "admin",
});
if (!user) {
response.status(200).json({
user: null,
valid: false,
token: null,
message,
});
return;
}
response.status(200).json({
user,
valid: true,
token: makeJWT({ id: user.id, email: user.email }, "30d"),
message: null,
});
return;
} catch (e) {
console.log(e.message, e);
response.sendStatus(500).end();
}
});
}
module.exports = { authenticationEndpoints };