Skip to content

Commit

Permalink
feat(environment): implement assertEnv
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrianAndersen committed Jul 7, 2024
1 parent 4137377 commit 9286b84
Show file tree
Hide file tree
Showing 15 changed files with 130 additions and 71 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"prettier": "prettier --write . --ignore-path=.gitignore",
"prettier:check": "prettier --check . --ignore-path=.gitignore",
"lint": "eslint .",
"test": "mocha \"src/**/*.spec.ts\"",
"test": "NODE_ENV=test mocha \"src/**/*.spec.ts\"",
"load_fixtures": "mongodb-fixtures rebuild -u mongodb://127.0.0.1:27017/test"
},
"license": "ISC",
Expand Down
9 changes: 5 additions & 4 deletions src/auth/facebook/facebook.auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Profile, Strategy, StrategyOptions } from "passport-facebook";

import { APP_CONFIG } from "../../application-config";
import { ApiPath } from "../../config/api-path";
import { assertEnv, BlEnvironment } from "../../config/environment";
import { SEResponseHandler } from "../../response/se.response.handler";
import { UserProvider } from "../user/user-provider/user-provider";

Expand All @@ -20,10 +21,10 @@ export class FacebookAuth {
this.apiPath = new ApiPath();

this.facebookPassportStrategySettings = {
clientID: process.env["FACEBOOK_CLIENT_ID"] ?? "",
clientSecret: process.env["FACEBOOK_SECRET"] ?? "",
clientID: assertEnv(BlEnvironment.FACEBOOK_CLIENT_ID),
clientSecret: assertEnv(BlEnvironment.FACEBOOK_SECRET),
callbackURL:
process.env["BL_API_URI"] +
assertEnv(BlEnvironment.BL_API_URI) +
this.apiPath.createPath("auth/facebook/callback"),
profileFields: ["id", "email", "name"],
enableProof: true,
Expand Down Expand Up @@ -98,7 +99,7 @@ export class FacebookAuth {
(err, tokens, blError: BlError) => {
if (!tokens && (err || blError)) {
return res.redirect(
process.env["CLIENT_URI"] +
assertEnv(BlEnvironment.CLIENT_URI) +
APP_CONFIG.path.client.auth.socialLoginFailure,
);
}
Expand Down
11 changes: 6 additions & 5 deletions src/auth/google/google.auth.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { BlError } from "@boklisten/bl-model";
import { Router } from "express";
import passport from "passport";
import { Strategy as GoogleStrategy, Profile } from "passport-google-oauth20";
import { Profile, Strategy as GoogleStrategy } from "passport-google-oauth20";

import { APP_CONFIG } from "../../application-config";
import { ApiPath } from "../../config/api-path";
import { assertEnv, BlEnvironment } from "../../config/environment";
import { SEResponseHandler } from "../../response/se.response.handler";
import { UserProvider } from "../user/user-provider/user-provider";

Expand All @@ -28,11 +29,11 @@ export class GoogleAuth {
passport.use(
new GoogleStrategy(
{
clientID: process.env["GOOGLE_CLIENT_ID"] ?? "",
clientSecret: process.env["GOOGLE_SECRET"] ?? "",
clientID: assertEnv(BlEnvironment.GOOGLE_CLIENT_ID),
clientSecret: assertEnv(BlEnvironment.GOOGLE_SECRET),
passReqToCallback: true,
callbackURL:
process.env["BL_API_URI"] +
assertEnv(BlEnvironment.BL_API_URI) +
this.apiPath.createPath("auth/google/callback"),
},
async (req, accessToken, refreshToken, profile, done) => {
Expand Down Expand Up @@ -95,7 +96,7 @@ export class GoogleAuth {

if (!tokens && (err || blError)) {
return res.redirect(
process.env["CLIENT_URI"] +
assertEnv(BlEnvironment.CLIENT_URI) +
APP_CONFIG.path.client.auth.socialLoginFailure,
);
}
Expand Down
4 changes: 3 additions & 1 deletion src/auth/token/access-token/access-token.secret.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { assertEnv, BlEnvironment } from "../../../config/environment";

export class AccessTokenSecret {
public get(): string {
return process.env["ACCESS_TOKEN_SECRET"] ?? "hello this is dog";
return assertEnv(BlEnvironment.ACCESS_TOKEN_SECRET);
}
}
6 changes: 3 additions & 3 deletions src/auth/token/refresh/refresh-token.secret.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { assertEnv, BlEnvironment } from "../../../config/environment";

export class RefreshTokenSecret {
get(): string {
return (
process.env["REFRESH_TOKEN_SECRET"] ?? "secretly a string is just chars"
);
return assertEnv(BlEnvironment.REFRESH_TOKEN_SECRET);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import moment from "moment";

import { BringDelivery } from "./bringDelivery";
import { APP_CONFIG } from "../../../../application-config";
import { assertEnv, BlEnvironment } from "../../../../config/environment";
import { isNullish } from "../../../../helper/typescript-helpers";
import { HttpHandler } from "../../../../http/http.handler";

Expand Down Expand Up @@ -58,8 +59,8 @@ export class BringDeliveryService {
}

const bringAuthHeaders = {
"X-MyBring-API-Key": process.env["BRING_API_KEY"],
"X-MyBring-API-Uid": process.env["BRING_API_ID"],
"X-MyBring-API-Key": assertEnv(BlEnvironment.BRING_API_KEY),
"X-MyBring-API-Uid": assertEnv(BlEnvironment.BRING_API_ID),
};

const postalInfoUrl = `https://api.bring.com/pickuppoint/api/postalCode/NO/getCityAndType/${shipmentAddress.postalCode}.json`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BlapiResponse, BlError } from "@boklisten/bl-model";

import { assertEnv, BlEnvironment } from "../../../config/environment";
import { isNullish } from "../../../helper/typescript-helpers";
import { HttpHandler } from "../../../http/http.handler";
import { Operation } from "../../../operation/operation";
Expand Down Expand Up @@ -47,8 +48,8 @@ export class PostalCodeLookupOperation implements Operation {
throw new BlError(`Malformed PostalCodeSpec`).code(701);
}
const bringAuthHeaders = {
"X-MyBring-API-Key": process.env["BRING_API_KEY"],
"X-MyBring-API-Uid": process.env["BRING_API_ID"],
"X-MyBring-API-Key": assertEnv(BlEnvironment.BRING_API_KEY),
"X-MyBring-API-Uid": assertEnv(BlEnvironment.BRING_API_ID),
};
try {
const response = (await this.httpHandler.getWithQuery(
Expand Down
9 changes: 3 additions & 6 deletions src/config/api-path.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import { IncomingHttpHeaders } from "http";

import { BlEnvironment, assertEnv } from "./environment";
import { APP_CONFIG } from "../application-config";

export class ApiPath {
private readonly baseHost: string;

constructor() {
if (process.env["NODE_ENV"] == "production") {
if (assertEnv(BlEnvironment.NODE_ENV) === "production") {
this.baseHost = APP_CONFIG.path.host;
} else {
this.baseHost = APP_CONFIG.path.local.host;
}
}

private getBasePath(): string {
return process.env["SERVER_PATH"] ?? "";
}

public createPath(customPath: string): string {
return this.getBasePath() + customPath;
return assertEnv(BlEnvironment.SERVER_PATH) + customPath;
}

public retrieveRefererPath(reqHeaders: IncomingHttpHeaders) {
Expand Down
49 changes: 49 additions & 0 deletions src/config/environment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { BlError } from "@boklisten/bl-model";

import { isNullish } from "../helper/typescript-helpers";

export enum BlEnvironment {
PORT = "PORT",
SERVER_PATH = "SERVER_PATH",
NODE_ENV = "NODE_ENV",
LOG_LEVEL = "LOG_LEVEL",
URI_WHITELIST = "URI_WHITELIST",
ACCESS_TOKEN_SECRET = "ACCESS_TOKEN_SECRET",
REFRESH_TOKEN_SECRET = "REFRESH_TOKEN_SECRET",
BL_API_URI = "BL_API_URI",
CLIENT_URI = "CLIENT_URI",
MONGODB_URI = "MONGODB_URI",
DIBS_SECRET_KEY = "DIBS_SECRET_KEY",
DIBS_URI = "DIBS_URI",
FACEBOOK_CLIENT_ID = "FACEBOOK_CLIENT_ID",
FACEBOOK_SECRET = "FACEBOOK_SECRET",
GOOGLE_CLIENT_ID = "GOOGLE_CLIENT_ID",
GOOGLE_SECRET = "GOOGLE_SECRET",
SENDGRID_API_KEY = "SENDGRID_API_KEY",
TWILIO_SMS_AUTH_TOKEN = "TWILIO_SMS_AUTH_TOKEN",
TWILIO_SMS_SID = "TWILIO_SMS_SID",
BRING_API_KEY = "BRING_API_KEY",
BRING_API_ID = "BRING_API_ID",
}

/**
*
*
* @param key the environment variable key
* @param callback optional callback that runs if the environment variable is present, and we are not in a test
* @returns the value of the environment variable if the environment variable is present, and we are not in a test
*
* @throws BlError if the environment variable is not present, and we are not in a test
*/
export function assertEnv(
key: BlEnvironment,
callback?: (value: string) => unknown,
): string {
const value = process.env[key];
if (process.env[BlEnvironment.NODE_ENV] === "test") return "placeholder";
if (isNullish(value)) {
throw new BlError(`${key} is a required environment variable`).code(200);
}
callback?.(value);
return value;
}
12 changes: 6 additions & 6 deletions src/logger/logger.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import moment from "moment";
import { createLogger, format, transports } from "winston";

import { assertEnv, BlEnvironment } from "../config/environment";

function formatTimestamp(timestamp: string) {
return moment(timestamp).format("HH:mm:ss.SSS");
}
Expand All @@ -19,10 +21,8 @@ export const logger = createLogger({
format: format.combine(
format.printf((info) => {
const colorizer = format.colorize();
if (
process.env["NODE_ENV"] === "production" ||
process.env["NODE_ENV"] === "dev"
) {
const nodeEnv = assertEnv(BlEnvironment.NODE_ENV);
if (nodeEnv === "production" || nodeEnv === "dev") {
return `${info.level} ${info.message}`;
}
return colorizer.colorize(
Expand All @@ -31,12 +31,12 @@ export const logger = createLogger({
);
}),
format.colorize({
all: process.env["NODE_ENV"] !== "production",
all: assertEnv(BlEnvironment.NODE_ENV) !== "production",
}),
),
transports: [
new transports.Console({
level: process.env["LOG_LEVEL"] ?? "info",
level: assertEnv(BlEnvironment.LOG_LEVEL),
handleExceptions: true,
}),
],
Expand Down
27 changes: 14 additions & 13 deletions src/messenger/email/email-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@ import { EmailOrder } from "@boklisten/bl-email/dist/ts/template/email-order";
import { EmailSetting } from "@boklisten/bl-email/dist/ts/template/email-setting";
import { EmailUser } from "@boklisten/bl-email/dist/ts/template/email-user";
import {
BlError,
CustomerItem,
Delivery,
Item,
Message,
Order,
OrderItem,
UserDetail,
CustomerItem,
Item,
Message,
BlError,
} from "@boklisten/bl-model";
import {
Recipient,
ItemList,
MessageOptions,
PostOffice,
postOffice,
ItemList,
PostOffice,
Recipient,
} from "@boklisten/bl-post-office";
import sgMail from "@sendgrid/mail";

Expand All @@ -26,11 +26,12 @@ import { OrderEmailHandler } from "./order-email/order-email-handler";
import { dateService } from "../../blc/date.service";
import { BlCollectionName } from "../../collections/bl-collection";
import { itemSchema } from "../../collections/item/item.schema";
import { assertEnv, BlEnvironment } from "../../config/environment";
import { logger } from "../../logger/logger";
import { BlDocumentStorage } from "../../storage/blDocumentStorage";
import {
MessengerService,
CustomerDetailWithCustomerItem,
MessengerService,
} from "../messenger-service";

export class EmailService implements MessengerService {
Expand All @@ -44,12 +45,12 @@ export class EmailService implements MessengerService {
itemStorage?: BlDocumentStorage<Item>,
inputPostOffice?: PostOffice,
) {
sgMail.setApiKey(process.env["SENDGRID_API_KEY"] ?? "SG.");
assertEnv(BlEnvironment.SENDGRID_API_KEY, (v) => sgMail.setApiKey(v));
this._emailHandler = emailHandler
? emailHandler
: new EmailHandler({
sendgrid: {
apiKey: process.env["SENDGRID_API_KEY"] ?? "",
apiKey: assertEnv(BlEnvironment.SENDGRID_API_KEY),
},
locale: "nb",
});
Expand Down Expand Up @@ -507,7 +508,7 @@ export class EmailService implements MessengerService {
userId: customerDetail.id,
};

let emailVerificationUri = process.env["CLIENT_URI"] ?? "localhost:4200/";
let emailVerificationUri = assertEnv(BlEnvironment.CLIENT_URI);
emailVerificationUri +=
EMAIL_SETTINGS.types.emailConfirmation.path + confirmationCode;

Expand All @@ -533,7 +534,7 @@ export class EmailService implements MessengerService {
userId: userId,
};

let passwordResetUri = process.env["CLIENT_URI"] ?? "localhost:4200/";
let passwordResetUri = assertEnv(BlEnvironment.CLIENT_URI);
passwordResetUri +=
EMAIL_SETTINGS.types.passwordReset.path +
pendingPasswordResetId +
Expand All @@ -558,7 +559,7 @@ export class EmailService implements MessengerService {
};
await this._emailHandler.sendGuardianSignatureRequest(
emailSetting,
(process.env["CLIENT_URI"] ?? "localhost:4200/") +
assertEnv(BlEnvironment.CLIENT_URI) +
EMAIL_SETTINGS.types.guardianSignature.path +
customerDetail.id,
branchName,
Expand Down
19 changes: 11 additions & 8 deletions src/messenger/sms/sms-service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import twilio from "twilio";
import twilio, { Twilio } from "twilio";

import { assertEnv, BlEnvironment } from "../../config/environment";
import { logger } from "../../logger/logger";

const accountSid = process.env["TWILIO_SMS_SID"];
const authToken = process.env["TWILIO_SMS_AUTH_TOKEN"];
const client = twilio(accountSid ?? "ACSid", authToken ?? "authToken", {
autoRetry: true,
maxRetries: 5,
});

let client: Twilio;
assertEnv(BlEnvironment.TWILIO_SMS_SID, (accountSid) =>
assertEnv(BlEnvironment.TWILIO_SMS_AUTH_TOKEN, (authToken) => {
client = twilio(accountSid, authToken, {
autoRetry: true,
maxRetries: 5,
});
}),
);
/**
* Send a single SMS to a single recipient
* @param toNumber Norwegian phone number (without country code)
Expand Down
Loading

0 comments on commit 9286b84

Please sign in to comment.