Files
outline/server/routes/api/auth.ts
Tom Moor 15b1069bcc chore: Move to Typescript (#2783)
This PR moves the entire project to Typescript. Due to the ~1000 ignores this will lead to a messy codebase for a while, but the churn is worth it – all of those ignore comments are places that were never type-safe previously.

closes #1282
2021-11-29 06:40:55 -08:00

129 lines
3.7 KiB
TypeScript

import Router from "koa-router";
import { find } from "lodash";
import { parseDomain, isCustomSubdomain } from "@shared/utils/domains";
import auth from "@server/middlewares/authentication";
import { Team } from "@server/models";
import { presentUser, presentTeam, presentPolicies } from "@server/presenters";
import { isCustomDomain } from "@server/utils/domains";
// @ts-expect-error ts-migrate(7034) FIXME: Variable 'providers' implicitly has type 'any[]' i... Remove this comment to see the full error message
import providers from "../auth/providers";
const router = new Router();
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'team' implicitly has an 'any' type.
function filterProviders(team) {
// @ts-expect-error ts-migrate(7005) FIXME: Variable 'providers' implicitly has an 'any[]' typ... Remove this comment to see the full error message
return providers
.sort((provider) => (provider.id === "email" ? 1 : -1))
.filter((provider) => {
// guest sign-in is an exception as it does not have an authentication
// provider using passport, instead it exists as a boolean option on the team
if (provider.id === "email") {
return team && team.guestSignin;
}
return (
!team ||
find(team.authenticationProviders, {
name: provider.id,
enabled: true,
})
);
})
.map((provider) => ({
id: provider.id,
name: provider.name,
authUrl: provider.authUrl,
}));
}
router.post("auth.config", async (ctx) => {
// If self hosted AND there is only one team then that team becomes the
// brand for the knowledge base and it's guest signin option is used for the
// root login page.
if (process.env.DEPLOYMENT !== "hosted") {
const teams = await Team.scope("withAuthenticationProviders").findAll();
if (teams.length === 1) {
const team = teams[0];
ctx.body = {
data: {
name: team.name,
providers: filterProviders(team),
},
};
return;
}
}
if (isCustomDomain(ctx.request.hostname)) {
const team = await Team.scope("withAuthenticationProviders").findOne({
where: {
domain: ctx.request.hostname,
},
});
if (team) {
ctx.body = {
data: {
name: team.name,
hostname: ctx.request.hostname,
providers: filterProviders(team),
},
};
return;
}
}
// If subdomain signin page then we return minimal team details to allow
// for a custom screen showing only relevant signin options for that team.
if (
process.env.SUBDOMAINS_ENABLED === "true" &&
isCustomSubdomain(ctx.request.hostname) &&
!isCustomDomain(ctx.request.hostname)
) {
const domain = parseDomain(ctx.request.hostname);
const subdomain = domain ? domain.subdomain : undefined;
const team = await Team.scope("withAuthenticationProviders").findOne({
where: {
subdomain,
},
});
if (team) {
ctx.body = {
data: {
name: team.name,
hostname: ctx.request.hostname,
providers: filterProviders(team),
},
};
return;
}
}
// Otherwise, we're requesting from the standard root signin page
ctx.body = {
data: {
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0.
providers: filterProviders(),
},
};
});
router.post("auth.info", auth(), async (ctx) => {
const user = ctx.state.user;
const team = await Team.findByPk(user.teamId);
ctx.body = {
data: {
user: presentUser(user, {
includeDetails: true,
}),
team: presentTeam(team),
},
policies: presentPolicies(user, [team]),
};
});
export default router;