Skip to content

Commit 35cee38

Browse files
committed
Add Joi for environment variable validation and update lifecycle service cron expression
1 parent c8c53fd commit 35cee38

File tree

4 files changed

+185
-1
lines changed

4 files changed

+185
-1
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
"hibp": "^14.1.2",
8383
"ioredis": "^5.4.1",
8484
"is-plain-object": "^5.0.0",
85+
"joi": "^18.0.1",
8586
"loglevel": "^1.9.1",
8687
"lru-cache": "^11.0.2",
8788
"microdiff": "^1.5.0",

src/config.ts

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,133 @@ import { MongooseModuleOptions } from '@nestjs/mongoose';
22
import { RedisOptions } from 'ioredis';
33
import { HelmetOptions } from 'helmet';
44
import { SwaggerCustomOptions } from '@nestjs/swagger';
5+
import Joi from 'joi';
56
import { IAuthModuleOptions } from '@nestjs/passport';
67
import { JwtModuleOptions } from '@nestjs/jwt';
78
import { StorageManagerConfig } from '~/_common/factorydrive';
89
import { AmazonWebServicesS3StorageConfig } from '~/_common/factorydrive';
910
import { HttpModuleOptions } from '@nestjs/axios';
1011

12+
export const validationSchema = Joi.object({
13+
LANG: Joi
14+
.string()
15+
.default('en'),
16+
17+
SESAME_LOG_LEVEL: Joi
18+
.string()
19+
.valid('error', 'warn', 'info', 'debug')
20+
.default('info'),
21+
22+
SESAME_NAME_QUEUE: Joi
23+
.string()
24+
.default('sesame'),
25+
26+
SESAME_HTTPS_ENABLED: Joi
27+
.string()
28+
.valid('0', '1', 'true', 'false', 'on', 'off')
29+
.default('false'),
30+
31+
SESAME_HTTPS_PATH_KEY: Joi
32+
.string()
33+
.when('SESAME_HTTPS_ENABLED', {
34+
is: /yes|1|on|true/i,
35+
then: Joi.required(),
36+
otherwise: Joi.optional().allow(''),
37+
})
38+
.default(''),
39+
40+
SESAME_HTTPS_PATH_CERT: Joi
41+
.string()
42+
.when('SESAME_HTTPS_ENABLED', {
43+
is: /yes|1|on|true/i,
44+
then: Joi.required(),
45+
otherwise: Joi.optional().allow(''),
46+
})
47+
.default(''),
48+
49+
SESAME_REDIS_URI: Joi
50+
.string()
51+
.uri()
52+
.default('redis://localhost:6379/0'),
53+
54+
SESAME_MONGO_URI: Joi
55+
.string()
56+
.uri()
57+
.default('mongodb://localhost:27017/backend'),
58+
59+
SESAME_AXIOS_TIMEOUT: Joi
60+
.number()
61+
.integer()
62+
.min(1)
63+
.default(5000),
64+
65+
SESAME_AXIOS_MAX_REDIRECTS: Joi
66+
.number()
67+
.integer()
68+
.min(0)
69+
.default(5),
70+
71+
SESAME_JWT_SECRET: Joi
72+
.string()
73+
.required(),
74+
75+
SESAME_SMTP_SERVER: Joi
76+
.string()
77+
.hostname()
78+
.required(),
79+
80+
SESAME_SMTP_PORT: Joi
81+
.number()
82+
.integer()
83+
.min(1)
84+
.max(65535)
85+
.default(25),
86+
87+
SESAME_MDP_SENDER: Joi
88+
.string()
89+
.email()
90+
.default(''),
91+
92+
SESAME_FRONT_MDP: Joi
93+
.string()
94+
.uri()
95+
.required(),
96+
97+
SESAME_RESET_PWD_MAIL: Joi
98+
.string()
99+
.default(''),
100+
101+
SESAME_RESET_PWD_MOBILE: Joi
102+
.string()
103+
.default(''),
104+
105+
SESAME_LIFECYCLE_TRIGGER_CRON: Joi
106+
.string()
107+
.pattern(/^(\*|([0-5]?\d))(\/\d+)? (\*|([01]?\d|2[0-3]))(\/\d+)? (\*|([01]?\d|2[0-9]|3[01]))(\/\d+)? (\*|(1[0-2]|0?[1-9]))(\/\d+)? (\*|([0-6]))(\/\d+)?$/)
108+
.default('*/5 * * * *'),
109+
110+
SESAME_SMPP_SERVER: Joi
111+
.string()
112+
.hostname()
113+
.default(''),
114+
115+
SESAME_SMPP_SYSTEMID: Joi
116+
.string()
117+
.default(''),
118+
119+
SESAME_SMPP_PASSWORD: Joi
120+
.string()
121+
.default(''),
122+
123+
SESAME_SMPP_SOURCEADDR: Joi
124+
.string()
125+
.default(''),
126+
127+
SESAME_SMPP_REGIONCODE: Joi
128+
.string()
129+
.default('FR'),
130+
});
131+
11132
export interface MongoosePlugin {
12133
package: string;
13134
enabled?: boolean;
@@ -75,6 +196,9 @@ export interface ConfigInstance {
75196
identityMailAttribute: string;
76197
identityMobileAttribute: string;
77198
};
199+
lifecycle: {
200+
triggerCronExpression: string;
201+
};
78202
swagger: {
79203
path: string;
80204
api: string;
@@ -184,6 +308,9 @@ export default (): ConfigInstance => ({
184308
identityMailAttribute: process.env['SESAME_RESET_PWD_MAIL'] || '',
185309
identityMobileAttribute: process.env['SESAME_RESET_PWD_MOBILE'] || '',
186310
},
311+
lifecycle: {
312+
triggerCronExpression: process.env['SESAME_LIFECYCLE_TRIGGER_CRON'] || '*/5 * * * *',
313+
},
187314
sms: {
188315
host: process.env['SESAME_SMPP_SERVER'] || '',
189316
systemId: process.env['SESAME_SMPP_SYSTEMID'] || '',

src/management/lifecycle/lifecycle.service.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { Identities } from '../identities/_schemas/identities.schema';
1414
import { IdentitiesCrudService } from '../identities/identities-crud.service';
1515
import { ConfigObjectIdentitiesDTO, ConfigObjectSchemaDTO } from './_dto/config.dto';
1616
import { Lifecycle, LifecycleRefId } from './_schemas/lifecycle.schema';
17+
import { ConfigService } from '@nestjs/config';
1718

1819
interface LifecycleSource {
1920
[source: string]: Partial<ConfigObjectIdentitiesDTO>[];
@@ -27,6 +28,7 @@ export class LifecycleService extends AbstractServiceSchema implements OnApplica
2728
@InjectModel(Lifecycle.name) protected _model: Model<Lifecycle>,
2829
protected readonly identitiesService: IdentitiesCrudService,
2930
private schedulerRegistry: SchedulerRegistry,
31+
private configService: ConfigService,
3032
) {
3133
super();
3234
}
@@ -79,8 +81,10 @@ export class LifecycleService extends AbstractServiceSchema implements OnApplica
7981

8082
const lifecycleRules = await this.loadLifecycleRules();
8183

82-
const job = new CronJob('*/5 * * * * *', this.handleCron.bind(this, { lifecycleRules }));
84+
const cronExpression = this.configService.get<string>('lifecycle.triggerCronExpression') || '*/5 * * * *';
85+
const job = new CronJob(cronExpression, this.handleCron.bind(this, { lifecycleRules }));
8386
this.schedulerRegistry.addCronJob(`lifecycle-trigger`, job);
87+
this.logger.warn(`Lifecycle trigger cron job scheduled with expression: <${cronExpression}>`);
8488
job.start();
8589

8690
this.logger.log('LifecycleService bootstraped');

yarn.lock

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2079,6 +2079,40 @@
20792079
dependencies:
20802080
lodash "^4.17.21"
20812081

2082+
"@hapi/address@^5.1.1":
2083+
version "5.1.1"
2084+
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-5.1.1.tgz#e9925fc1b65f5cc3fbea821f2b980e4652e84cb6"
2085+
integrity sha512-A+po2d/dVoY7cYajycYI43ZbYMXukuopIsqCjh5QzsBCipDtdofHntljDlpccMjIfTy6UOkg+5KPriwYch2bXA==
2086+
dependencies:
2087+
"@hapi/hoek" "^11.0.2"
2088+
2089+
"@hapi/formula@^3.0.2":
2090+
version "3.0.2"
2091+
resolved "https://registry.yarnpkg.com/@hapi/formula/-/formula-3.0.2.tgz#81b538060ee079481c906f599906d163c4badeaf"
2092+
integrity sha512-hY5YPNXzw1He7s0iqkRQi+uMGh383CGdyyIGYtB+W5N3KHPXoqychklvHhKCC9M3Xtv0OCs/IHw+r4dcHtBYWw==
2093+
2094+
"@hapi/hoek@^11.0.2", "@hapi/hoek@^11.0.7":
2095+
version "11.0.7"
2096+
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-11.0.7.tgz#56a920793e0a42d10e530da9a64cc0d3919c4002"
2097+
integrity sha512-HV5undWkKzcB4RZUusqOpcgxOaq6VOAH7zhhIr2g3G8NF/MlFO75SjOr2NfuSx0Mh40+1FqCkagKLJRykUWoFQ==
2098+
2099+
"@hapi/pinpoint@^2.0.1":
2100+
version "2.0.1"
2101+
resolved "https://registry.yarnpkg.com/@hapi/pinpoint/-/pinpoint-2.0.1.tgz#32077e715655fc00ab8df74b6b416114287d6513"
2102+
integrity sha512-EKQmr16tM8s16vTT3cA5L0kZZcTMU5DUOZTuvpnY738m+jyP3JIUj+Mm1xc1rsLkGBQ/gVnfKYPwOmPg1tUR4Q==
2103+
2104+
"@hapi/tlds@^1.1.1":
2105+
version "1.1.3"
2106+
resolved "https://registry.yarnpkg.com/@hapi/tlds/-/tlds-1.1.3.tgz#bf5fee927d213f140cd54d4650965e504a546789"
2107+
integrity sha512-QIvUMB5VZ8HMLZF9A2oWr3AFM430QC8oGd0L35y2jHpuW6bIIca6x/xL7zUf4J7L9WJ3qjz+iJII8ncaeMbpSg==
2108+
2109+
"@hapi/topo@^6.0.2":
2110+
version "6.0.2"
2111+
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-6.0.2.tgz#f219c1c60da8430228af4c1f2e40c32a0d84bbb4"
2112+
integrity sha512-KR3rD5inZbGMrHmgPxsJ9dbi6zEK+C3ZwUwTa+eMwWLz7oijWUTWD2pMSNNYJAU6Qq+65NkxXjqHr/7LM2Xkqg==
2113+
dependencies:
2114+
"@hapi/hoek" "^11.0.2"
2115+
20822116
"@humanfs/core@^0.19.1":
20832117
version "0.19.1"
20842118
resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77"
@@ -3247,6 +3281,11 @@
32473281
dependencies:
32483282
tslib "^2.6.2"
32493283

3284+
"@standard-schema/spec@^1.0.0":
3285+
version "1.0.0"
3286+
resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0.tgz#f193b73dc316c4170f2e82a881da0f550d551b9c"
3287+
integrity sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==
3288+
32503289
"@swc/cli@^0.5.1":
32513290
version "0.5.1"
32523291
resolved "https://registry.yarnpkg.com/@swc/cli/-/cli-0.5.1.tgz#911dc47f68baaa2bdffc259c4fa2cc7fe48bb825"
@@ -7604,6 +7643,19 @@ jest@^29.7.0:
76047643
import-local "^3.0.2"
76057644
jest-cli "^29.7.0"
76067645

7646+
joi@^18.0.1:
7647+
version "18.0.1"
7648+
resolved "https://registry.yarnpkg.com/joi/-/joi-18.0.1.tgz#1e1885d035cc6ca1624e81bf22112e7c1ee38e1b"
7649+
integrity sha512-IiQpRyypSnLisQf3PwuN2eIHAsAIGZIrLZkd4zdvIar2bDyhM91ubRjy8a3eYablXsh9BeI/c7dmPYHca5qtoA==
7650+
dependencies:
7651+
"@hapi/address" "^5.1.1"
7652+
"@hapi/formula" "^3.0.2"
7653+
"@hapi/hoek" "^11.0.7"
7654+
"@hapi/pinpoint" "^2.0.1"
7655+
"@hapi/tlds" "^1.1.1"
7656+
"@hapi/topo" "^6.0.2"
7657+
"@standard-schema/spec" "^1.0.0"
7658+
76077659
js-beautify@^1.6.14:
76087660
version "1.15.1"
76097661
resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.15.1.tgz#4695afb508c324e1084ee0b952a102023fc65b64"

0 commit comments

Comments
 (0)