chore: Centralize env parsing, validation, defaults, and deprecation notices (#3487)
* chore: Centralize env parsing, defaults, deprecation * wip * test * test * tsc * docs, more validation * fix: Allow empty REDIS_URL (defaults to localhost) * test * fix: SLACK_MESSAGE_ACTIONS not bool * fix: Add SMTP port validation
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import TestServer from "fetch-test-server";
|
||||
import env from "@server/env";
|
||||
import webService from "@server/services/web";
|
||||
import { buildUser, buildTeam } from "@server/test/factories";
|
||||
import { flushdb } from "@server/test/support";
|
||||
@@ -57,7 +58,7 @@ describe("#auth.config", () => {
|
||||
});
|
||||
|
||||
it("should return available providers for team subdomain", async () => {
|
||||
process.env.URL = "http://localoutline.com";
|
||||
env.URL = "http://localoutline.com";
|
||||
await buildTeam({
|
||||
guestSignin: false,
|
||||
subdomain: "example",
|
||||
@@ -102,7 +103,7 @@ describe("#auth.config", () => {
|
||||
});
|
||||
|
||||
it("should return email provider for team when guest signin enabled", async () => {
|
||||
process.env.URL = "http://localoutline.com";
|
||||
env.URL = "http://localoutline.com";
|
||||
await buildTeam({
|
||||
guestSignin: true,
|
||||
subdomain: "example",
|
||||
@@ -126,7 +127,7 @@ describe("#auth.config", () => {
|
||||
});
|
||||
|
||||
it("should not return provider when disabled", async () => {
|
||||
process.env.URL = "http://localoutline.com";
|
||||
env.URL = "http://localoutline.com";
|
||||
await buildTeam({
|
||||
guestSignin: false,
|
||||
subdomain: "example",
|
||||
@@ -149,7 +150,7 @@ describe("#auth.config", () => {
|
||||
});
|
||||
describe("self hosted", () => {
|
||||
it("should return available providers for team", async () => {
|
||||
process.env.DEPLOYMENT = "";
|
||||
env.DEPLOYMENT = "";
|
||||
await buildTeam({
|
||||
guestSignin: false,
|
||||
authenticationProviders: [
|
||||
@@ -166,7 +167,7 @@ describe("#auth.config", () => {
|
||||
expect(body.data.providers[0].name).toBe("Slack");
|
||||
});
|
||||
it("should return email provider for team when guest signin enabled", async () => {
|
||||
process.env.DEPLOYMENT = "";
|
||||
env.DEPLOYMENT = "";
|
||||
await buildTeam({
|
||||
guestSignin: true,
|
||||
authenticationProviders: [
|
||||
|
||||
@@ -2,6 +2,7 @@ import invariant from "invariant";
|
||||
import Router from "koa-router";
|
||||
import { find } from "lodash";
|
||||
import { parseDomain, isCustomSubdomain } from "@shared/utils/domains";
|
||||
import env from "@server/env";
|
||||
import auth from "@server/middlewares/authentication";
|
||||
import { Team, TeamDomain } from "@server/models";
|
||||
import { presentUser, presentTeam, presentPolicies } from "@server/presenters";
|
||||
@@ -10,7 +11,7 @@ import providers from "../auth/providers";
|
||||
|
||||
const router = new Router();
|
||||
|
||||
function filterProviders(team: Team) {
|
||||
function filterProviders(team?: Team) {
|
||||
return providers
|
||||
.sort((provider) => (provider.id === "email" ? 1 : -1))
|
||||
.filter((provider) => {
|
||||
@@ -39,7 +40,7 @@ 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") {
|
||||
if (env.DEPLOYMENT !== "hosted") {
|
||||
const teams = await Team.scope("withAuthenticationProviders").findAll();
|
||||
|
||||
if (teams.length === 1) {
|
||||
@@ -76,7 +77,7 @@ router.post("auth.config", async (ctx) => {
|
||||
// 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" &&
|
||||
env.SUBDOMAINS_ENABLED &&
|
||||
isCustomSubdomain(ctx.request.hostname) &&
|
||||
!isCustomDomain(ctx.request.hostname)
|
||||
) {
|
||||
@@ -103,7 +104,6 @@ router.post("auth.config", async (ctx) => {
|
||||
// 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(),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Context } from "koa";
|
||||
import Router from "koa-router";
|
||||
import env from "@server/env";
|
||||
import { AuthenticationError } from "@server/errors";
|
||||
import CleanupDeletedDocumentsTask from "@server/queues/tasks/CleanupDeletedDocumentsTask";
|
||||
import CleanupDeletedTeamsTask from "@server/queues/tasks/CleanupDeletedTeamsTask";
|
||||
@@ -11,7 +12,7 @@ const router = new Router();
|
||||
const cronHandler = async (ctx: Context) => {
|
||||
const { token, limit = 500 } = ctx.body as { token?: string; limit: number };
|
||||
|
||||
if (process.env.UTILS_SECRET !== token) {
|
||||
if (env.UTILS_SECRET !== token) {
|
||||
throw AuthenticationError("Invalid secret token");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import TestServer from "fetch-test-server";
|
||||
import env from "@server/env";
|
||||
import { IntegrationAuthentication, SearchQuery } from "@server/models";
|
||||
import webService from "@server/services/web";
|
||||
import { buildDocument, buildIntegration } from "@server/test/factories";
|
||||
@@ -24,7 +25,7 @@ describe("#hooks.unfurl", () => {
|
||||
});
|
||||
const res = await server.post("/api/hooks.unfurl", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
token: env.SLACK_VERIFICATION_TOKEN,
|
||||
team_id: "TXXXXXXXX",
|
||||
api_app_id: "AXXXXXXXXX",
|
||||
event: {
|
||||
@@ -51,7 +52,7 @@ describe("#hooks.slack", () => {
|
||||
const { user, team } = await seed();
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
token: env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "dsfkndfskndsfkn",
|
||||
@@ -71,7 +72,7 @@ describe("#hooks.slack", () => {
|
||||
});
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
token: env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "contains",
|
||||
@@ -93,7 +94,7 @@ describe("#hooks.slack", () => {
|
||||
});
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
token: env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "*contains",
|
||||
@@ -113,7 +114,7 @@ describe("#hooks.slack", () => {
|
||||
});
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
token: env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "contains",
|
||||
@@ -132,7 +133,7 @@ describe("#hooks.slack", () => {
|
||||
const { user, team } = await seed();
|
||||
await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
token: env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "contains",
|
||||
@@ -160,7 +161,7 @@ describe("#hooks.slack", () => {
|
||||
const { user, team } = await seed();
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
token: env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "help",
|
||||
@@ -175,7 +176,7 @@ describe("#hooks.slack", () => {
|
||||
const { user, team } = await seed();
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
token: env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.authentications[0].providerId,
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "",
|
||||
@@ -202,7 +203,7 @@ describe("#hooks.slack", () => {
|
||||
});
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
token: env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: "unknown-slack-user-id",
|
||||
team_id: team.authenticationProviders[0].providerId,
|
||||
text: "contains",
|
||||
@@ -234,7 +235,7 @@ describe("#hooks.slack", () => {
|
||||
});
|
||||
const res = await server.post("/api/hooks.slack", {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
token: env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: "unknown-slack-user-id",
|
||||
team_id: serviceTeamId,
|
||||
text: "contains",
|
||||
@@ -273,7 +274,7 @@ describe("#hooks.interactive", () => {
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const payload = JSON.stringify({
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
token: env.SLACK_VERIFICATION_TOKEN,
|
||||
user: {
|
||||
id: user.authentications[0].providerId,
|
||||
},
|
||||
@@ -302,7 +303,7 @@ describe("#hooks.interactive", () => {
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const payload = JSON.stringify({
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
token: env.SLACK_VERIFICATION_TOKEN,
|
||||
user: {
|
||||
id: "unknown-slack-user-id",
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import invariant from "invariant";
|
||||
import Router from "koa-router";
|
||||
import { escapeRegExp } from "lodash";
|
||||
import env from "@server/env";
|
||||
import { AuthenticationError, InvalidRequestError } from "@server/errors";
|
||||
import Logger from "@server/logging/logger";
|
||||
import {
|
||||
@@ -26,7 +27,7 @@ router.post("hooks.unfurl", async (ctx) => {
|
||||
return (ctx.body = ctx.body.challenge);
|
||||
}
|
||||
|
||||
if (token !== process.env.SLACK_VERIFICATION_TOKEN) {
|
||||
if (token !== env.SLACK_VERIFICATION_TOKEN) {
|
||||
throw AuthenticationError("Invalid token");
|
||||
}
|
||||
|
||||
@@ -89,7 +90,7 @@ router.post("hooks.interactive", async (ctx) => {
|
||||
assertPresent(token, "token is required");
|
||||
assertPresent(callback_id, "callback_id is required");
|
||||
|
||||
if (token !== process.env.SLACK_VERIFICATION_TOKEN) {
|
||||
if (token !== env.SLACK_VERIFICATION_TOKEN) {
|
||||
throw AuthenticationError("Invalid verification token");
|
||||
}
|
||||
|
||||
@@ -127,7 +128,7 @@ router.post("hooks.slack", async (ctx) => {
|
||||
assertPresent(team_id, "team_id is required");
|
||||
assertPresent(user_id, "user_id is required");
|
||||
|
||||
if (token !== process.env.SLACK_VERIFICATION_TOKEN) {
|
||||
if (token !== env.SLACK_VERIFICATION_TOKEN) {
|
||||
throw AuthenticationError("Invalid verification token");
|
||||
}
|
||||
|
||||
@@ -289,7 +290,7 @@ router.post("hooks.slack", async (ctx) => {
|
||||
result.document.collection,
|
||||
team,
|
||||
queryIsInTitle ? undefined : result.context,
|
||||
process.env.SLACK_MESSAGE_ACTIONS
|
||||
env.SLACK_MESSAGE_ACTIONS
|
||||
? [
|
||||
{
|
||||
name: "post",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Router from "koa-router";
|
||||
import env from "@server/env";
|
||||
import auth from "@server/middlewares/authentication";
|
||||
import { Team, NotificationSetting } from "@server/models";
|
||||
import { authorize } from "@server/policies";
|
||||
@@ -75,7 +76,7 @@ router.post("notificationSettings.unsubscribe", async (ctx) => {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.redirect(`${process.env.URL}?notice=invalid-auth`);
|
||||
ctx.redirect(`${env.URL}?notice=invalid-auth`);
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -5,6 +5,7 @@ import userInviter from "@server/commands/userInviter";
|
||||
import userSuspender from "@server/commands/userSuspender";
|
||||
import { sequelize } from "@server/database/sequelize";
|
||||
import InviteEmail from "@server/emails/templates/InviteEmail";
|
||||
import env from "@server/env";
|
||||
import { ValidationError } from "@server/errors";
|
||||
import logger from "@server/logging/logger";
|
||||
import auth from "@server/middlewares/authentication";
|
||||
@@ -338,11 +339,11 @@ router.post("users.resendInvite", auth(), async (ctx) => {
|
||||
user.incrementFlag(UserFlag.InviteSent);
|
||||
await user.save({ transaction });
|
||||
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
if (env.ENVIRONMENT === "development") {
|
||||
logger.info(
|
||||
"email",
|
||||
`Sign in immediately: ${
|
||||
process.env.URL
|
||||
env.URL
|
||||
}/auth/email.callback?token=${user.getEmailSigninToken()}`
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user