Skip to content
This repository has been archived by the owner on Apr 19, 2023. It is now read-only.

Commit

Permalink
♻️ Update configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
AnandChowdhary committed Jan 9, 2021
1 parent 55b4514 commit 10f6cc8
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 219 deletions.
203 changes: 20 additions & 183 deletions src/config/configuration.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,168 +2,41 @@ import { ApiKeyAuth, BasicAuth } from '@elastic/elasticsearch/lib/pool';
import Stripe from 'stripe';

export interface Configuration {
/** Project name and other metadata */
frontendUrl: string;

meta: {
/**
* Frontend URL (Staart UI or compatible app)
* Used for redirects and links in emails
*/
frontendUrl: string;
/**
* Title cased application name
* Used as the "Issuer" in MFA TOTP and in SMS OTPs
*/
appName: string;
/**
* Domain verification file
* To verify groups' domains, users can upload a file to this path
* By default, it will be staart-verify.txt in the .well-known directory
*/
domainVerificationFile: string;
};

/** Rate limitng */
rateLimit: {
/** Rate limit for public (no authentication) */
public: {
/**
* Maximum number of consumable points
* @default 250
*/
points: number;
/**
* Time in seconds before rate limit is reset
* @default 3600
*/
duration: number;
};
/** Rate limit for authenticated users */
authenticated: {
/**
* Maximum number of consumable points
* @default 5000
*/
points: number;
/**
* Time in seconds before rate limit is reset
* @default 3600
*/
duration: number;
};
/** Rate limit for API key authentication */
apiKey: {
/**
* Maximum number of consumable points
* @default 10000
*/
points: number;
/**
* Time in seconds before rate limit is reset
* @default 3600
*/
duration: number;
};
};

/** Caching */
caching: {
/**
* Least Recently Used (LRU) cache size for geolocation
* @default 100
*/
geolocationLruSize: number;
/**
* Least Recently Used (LRU) cache size for API key
* @default 100
*/
apiKeyLruSize: number;
};

rateLimit: {
public: { points: number; duration: number };
authenticated: { points: number; duration: number };
apiKey: { points: number; duration: number };
};

security: {
/**
* Number of salt rounds when hashing passwords
* @default 10
*/
saltRounds: number;
/**
* Secret for signing JSON Web Tokens (JWT)
*/
jwtSecret: string;
/**
* Issuer domain for acct: URIs and JWTs
* For example, acct:[email protected] in access tokens
* Also used as the "iss" claim in JWTs
*/
issuerDomain: string;
/**
* Window of (number of) past TOTPs allowed
* @default 1
*/
totpWindowPast: number;
/**
* Window of (number of) future TOTPs allowed
* @default 0
*/
totpWindowFuture: number;
/**
* MFA tokens expiry time
* @default 10m
*/
mfaTokenExpiry: string;
/**
* Merge users expiry time
* @default 30m
*/
mergeUsersTokenExpiry: string;
/**
* Access token expiry time
* @default 1h
*/
accessTokenExpiry: string;
/**
* Check for pwned passwords
* @default true
*/
passwordPwnedCheck: boolean;
/**
* Delete unused refresh tokens after these many days
* @default 30
*/
unusedRefreshTokenExpiryDays: number;
/**
* Delete deactivated users after these many days
* @default 30
*/
inactiveUserDeleteDays: number;
};

/** ElasticSearch for logging */
elasticSearch: {
node: string;
/**
* Number of times to retry saving records
* @default 3
*/
retries: number;
auth?: BasicAuth | ApiKeyAuth;
aws?: {
accessKeyId: string;
secretAccessKey: string;
region: string;
};
};

/** Email */
email: {
/** Name for email "From" */
name: string;
from: string;
/**
* Number of times to retry sending failed emails
* @default 3
*/
retries: number;
/** AWS SES */
ses?: {
accessKeyId: string;
secretAccessKey: string;
Expand All @@ -180,101 +53,65 @@ export interface Configuration {
};
};

/** Outgoing webhooks */
elasticSearch: {
node: string;
retries: number;
auth?: BasicAuth | ApiKeyAuth;
aws?: {
accessKeyId: string;
secretAccessKey: string;
region: string;
};
};

webhooks: {
/**
* Number of times to retry triggering webhooks
* @default 3
*/
retries: number;
};

/** Sending messages */
sms: {
/**
* Number of times to retry sending an SMS
* @default 3
*/
retries: number;
twilioAccountSid: string;
twilioAuthToken: string;
};

/** Stripe payments */
payments: {
stripeApiKey: string;
stripeProductId: string;
stripeEndpointSecret: string;
paymentMethodTypes: Array<Stripe.Checkout.SessionCreateParams.PaymentMethodType>;
};

/** Server logs */
tracking: {
/**
* Types of server logs to save in ElasticSearch
* (a) all: Track all incoming requests
* (b) api-key: Track requests with an API key
* (c) authenticated: Track requests with a logged in user
* @default api-key
*/
mode: 'all' | 'api-key' | 'authenticated';
mode: 'all' | 'api-key' | 'user' | 'api-key-or-user';
index: string;
/**
* Whether to delete old ElasticSearch logs
* @default true
*/
deleteOldLogs: boolean;
/**
* Delete logs older than these many days
* @default 90
*/
deleteOldLogsDays: number;
};

/** Slack integration */
slack: {
token: string;
slackApiUrl?: string;
rejectRateLimitedCalls?: boolean;
retries: number;
};

/** Airtable integration */
airtable: {
apiKey: string;
endpointUrl?: string;
};

/** AWS S3 integration */
s3: {
accessKeyId: string;
secretAccessKey: string;
region: string;
bucket?: string;
};

/** Cloudinary integration */
cloudinary: {
cloudName: string;
apiKey: string;
apiSecret: string;
};

/** Firebase integration */
firebase: {
serviceAccountKey:
| string
| { projectId?: string; clientEmail?: string; privateKey?: string };
databaseUrl: string;
};

/** Github integration */
github: {
auth: string;
userAgent?: string;
};

/** Google Maps integration */
googleMaps: {
apiKey: string;
};
Expand Down
42 changes: 6 additions & 36 deletions src/config/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,20 @@
import { ConfigFactory } from '@nestjs/config/dist/interfaces';
import slugify from '@sindresorhus/slugify';
import { config } from 'dotenv';
import dotenvExpand from 'dotenv-expand';
import { Configuration } from './configuration.interface';
dotenvExpand(config());

/**
* Get an integer from an environment variable
* @param val - Value from process.env
* @param num - Fallback number value
*/
const int = (val: string | undefined, num: number): number =>
val ? (isNaN(parseInt(val)) ? num : parseInt(val)) : num;

/**
* Get boolean value from an environment variable
* @param val - Value from process.env
* @param bool - Fallback boolean value
*/
const bool = (val: string | undefined, bool: boolean): boolean =>
val == null ? bool : val == 'true';

/** Central configuration object */
const configuration: Configuration = {
frontendUrl: process.env.FRONTEND_URL ?? 'http://localhost:3000',
meta: {
frontendUrl: process.env.FRONTEND_URL ?? 'http://localhost:3000',
appName: process.env.APP_NAME ?? 'Staart',
domainVerificationFile:
process.env.DOMAIN_VERIFICATION_FILE ??
`${slugify(process.env.APP_NAME ?? 'Staart')}-verify.txt`,
process.env.DOMAIN_VERIFICATION_FILE ?? 'staart-verify.txt',
},
rateLimit: {
public: {
Expand All @@ -51,7 +37,6 @@ const configuration: Configuration = {
security: {
saltRounds: int(process.env.SALT_ROUNDS, 10),
jwtSecret: process.env.JWT_SECRET ?? 'staart',
issuerDomain: process.env.ISSUER_DOMAIN ?? 'staart.js.org',
totpWindowPast: int(process.env.TOTP_WINDOW_PAST, 1),
totpWindowFuture: int(process.env.TOTP_WINDOW_FUTURE, 0),
mfaTokenExpiry: process.env.MFA_TOKEN_EXPIRY ?? '10m',
Expand Down Expand Up @@ -86,7 +71,7 @@ const configuration: Configuration = {
},
},
email: {
name: process.env.EMAIL_NAME ?? process.env.APP_NAME ?? 'Staart',
name: process.env.EMAIL_NAME ?? 'Staart',
from: process.env.EMAIL_FROM ?? '',
retries: int(process.env.EMAIL_FAIL_RETRIES, 3),
ses: {
Expand Down Expand Up @@ -135,31 +120,16 @@ const configuration: Configuration = {
),
retries: int(process.env.SLACK_FAIL_RETRIES, 3),
},
airtable: {
apiKey: process.env.AIRTABLE_API_KEY ?? '',
endpointUrl: process.env.AIRTABLE_ENDPOINT_URL,
},
s3: {
accessKeyId: process.env.S3_ACCESS_KEY_ID ?? '',
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY ?? '',
region: process.env.S3_REGION ?? '',
bucket: process.env.S3_BUCKET,
accessKeyId: process.env.AWS_S3_ACCESS_KEY ?? '',
secretAccessKey: process.env.AWS_S3_SECRET_KEY ?? '',
region: process.env.AWS_S3_REGION ?? '',
},
cloudinary: {
cloudName: process.env.CLOUDINARY_CLOUD_NAME ?? '',
apiKey: process.env.CLOUDINARY_API_KEY ?? '',
apiSecret: process.env.CLOUDINARY_API_SECRET ?? '',
},
firebase: {
serviceAccountKey: process.env.FIREBASE_PROJECT_ID
? {
projectId: process.env.FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_PRIVATE_KEY,
}
: process.env.FIREBASE_SERVICE_ACCOUNT_KEY,
databaseUrl: process.env.FIREBASE_DATABASE_URL,
},
github: {
auth: process.env.GITHUB_AUTH,
userAgent: process.env.GITHUB_USER_AGENT,
Expand Down

0 comments on commit 10f6cc8

Please sign in to comment.