mirror of
https://github.com/apricote/Listory.git
synced 2026-01-13 21:21:02 +00:00
feat(api): validate configuration
This commit is contained in:
parent
ad98ce4e88
commit
e78c6e312d
8 changed files with 109 additions and 12 deletions
|
|
@ -16,9 +16,11 @@ services:
|
||||||
target: build-api
|
target: build-api
|
||||||
command: ["npm", "run", "start:dev"]
|
command: ["npm", "run", "start:dev"]
|
||||||
environment:
|
environment:
|
||||||
|
DB_HOST: db
|
||||||
DB_USERNAME: listory
|
DB_USERNAME: listory
|
||||||
DB_PASSWORD: listory
|
DB_PASSWORD: listory
|
||||||
DB_HOST: db
|
DB_DATABASE: listory
|
||||||
|
APP_URL: "http://localhost:3000"
|
||||||
env_file: .env
|
env_file: .env
|
||||||
volumes:
|
volumes:
|
||||||
- ./src:/app/src
|
- ./src:/app/src
|
||||||
|
|
|
||||||
49
package-lock.json
generated
49
package-lock.json
generated
|
|
@ -484,6 +484,49 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@hapi/address": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-0oEP5UiyV4f3d6cBL8F3Z5S7iWSX39Knnl0lY8i+6gfmmIBj44JCBNtcMgwyS+5v7j3VYavNay0NFHDS+UGQcw==",
|
||||||
|
"requires": {
|
||||||
|
"@hapi/hoek": "^9.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@hapi/formula": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A=="
|
||||||
|
},
|
||||||
|
"@hapi/hoek": {
|
||||||
|
"version": "9.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
|
||||||
|
"integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
|
||||||
|
},
|
||||||
|
"@hapi/joi": {
|
||||||
|
"version": "17.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz",
|
||||||
|
"integrity": "sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==",
|
||||||
|
"requires": {
|
||||||
|
"@hapi/address": "^4.0.1",
|
||||||
|
"@hapi/formula": "^2.0.0",
|
||||||
|
"@hapi/hoek": "^9.0.0",
|
||||||
|
"@hapi/pinpoint": "^2.0.0",
|
||||||
|
"@hapi/topo": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@hapi/pinpoint": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw=="
|
||||||
|
},
|
||||||
|
"@hapi/topo": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==",
|
||||||
|
"requires": {
|
||||||
|
"@hapi/hoek": "^9.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@istanbuljs/load-nyc-config": {
|
"@istanbuljs/load-nyc-config": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz",
|
||||||
|
|
@ -1523,6 +1566,12 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/hapi__joi": {
|
||||||
|
"version": "16.0.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/hapi__joi/-/hapi__joi-16.0.12.tgz",
|
||||||
|
"integrity": "sha512-xJYifuz59jXdWY5JMS15uvA3ycS3nQYOGqoIIE0+fwQ0qI3/4CxBc6RHsOTp6wk9M0NWEdpcTl02lOQOKMifbQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/istanbul-lib-coverage": {
|
"@types/istanbul-lib-coverage": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
"test:e2e": "jest --config ./apps/listory/test/jest-e2e.json"
|
"test:e2e": "jest --config ./apps/listory/test/jest-e2e.json"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@hapi/joi": "^17.1.1",
|
||||||
"@nestjs/common": "^7.0.9",
|
"@nestjs/common": "^7.0.9",
|
||||||
"@nestjs/config": "^0.4.0",
|
"@nestjs/config": "^0.4.0",
|
||||||
"@nestjs/core": "^7.0.9",
|
"@nestjs/core": "^7.0.9",
|
||||||
|
|
@ -48,6 +49,7 @@
|
||||||
"@nestjs/schematics": "^7.0.0",
|
"@nestjs/schematics": "^7.0.0",
|
||||||
"@nestjs/testing": "^7.0.9",
|
"@nestjs/testing": "^7.0.9",
|
||||||
"@types/express": "^4.17.6",
|
"@types/express": "^4.17.6",
|
||||||
|
"@types/hapi__joi": "^16.0.12",
|
||||||
"@types/jest": "^25.2.1",
|
"@types/jest": "^25.2.1",
|
||||||
"@types/node": "^13.13.4",
|
"@types/node": "^13.13.4",
|
||||||
"@types/passport-jwt": "^3.0.3",
|
"@types/passport-jwt": "^3.0.3",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
import { ConfigModule } from "@nestjs/config";
|
|
||||||
import { ScheduleModule } from "@nestjs/schedule";
|
import { ScheduleModule } from "@nestjs/schedule";
|
||||||
import { ServeStaticModule } from "@nestjs/serve-static";
|
import { ServeStaticModule } from "@nestjs/serve-static";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
|
|
@ -10,12 +9,14 @@ import { LoggerModule } from "./logger/logger.module";
|
||||||
import { MusicLibraryModule } from "./music-library/music-library.module";
|
import { MusicLibraryModule } from "./music-library/music-library.module";
|
||||||
import { SourcesModule } from "./sources/sources.module";
|
import { SourcesModule } from "./sources/sources.module";
|
||||||
import { UsersModule } from "./users/users.module";
|
import { UsersModule } from "./users/users.module";
|
||||||
|
import { ConfigModule } from "./config/config.module";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot({ isGlobal: true }),
|
LoggerModule,
|
||||||
ScheduleModule.forRoot(),
|
ConfigModule,
|
||||||
DatabaseModule,
|
DatabaseModule,
|
||||||
|
ScheduleModule.forRoot(),
|
||||||
ServeStaticModule.forRoot({
|
ServeStaticModule.forRoot({
|
||||||
rootPath: join(__dirname, "..", "static"),
|
rootPath: join(__dirname, "..", "static"),
|
||||||
exclude: ["/api*"],
|
exclude: ["/api*"],
|
||||||
|
|
@ -25,7 +26,6 @@ import { UsersModule } from "./users/users.module";
|
||||||
SourcesModule,
|
SourcesModule,
|
||||||
MusicLibraryModule,
|
MusicLibraryModule,
|
||||||
ListensModule,
|
ListensModule,
|
||||||
LoggerModule,
|
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ export class SpotifyStrategy extends PassportStrategy(Strategy) {
|
||||||
super({
|
super({
|
||||||
clientID: config.get<string>("SPOTIFY_CLIENT_ID"),
|
clientID: config.get<string>("SPOTIFY_CLIENT_ID"),
|
||||||
clientSecret: config.get<string>("SPOTIFY_CLIENT_SECRET"),
|
clientSecret: config.get<string>("SPOTIFY_CLIENT_SECRET"),
|
||||||
callbackURL: `${
|
callbackURL: `${config.get<string>(
|
||||||
config.get<string>("BASE_DOMAIN") || "http://localhost:3000"
|
"APP_URL"
|
||||||
}/api/v1/auth/spotify/callback`,
|
)}/api/v1/auth/spotify/callback`,
|
||||||
scope: [
|
scope: [
|
||||||
"user-read-private",
|
"user-read-private",
|
||||||
"user-read-email",
|
"user-read-email",
|
||||||
|
|
|
||||||
40
src/config/config.module.ts
Normal file
40
src/config/config.module.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
import * as Joi from "@hapi/joi";
|
||||||
|
import { Module } from "@nestjs/common";
|
||||||
|
import {
|
||||||
|
ConfigModule as NestConfigModule,
|
||||||
|
ConfigService,
|
||||||
|
} from "@nestjs/config";
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
NestConfigModule.forRoot({
|
||||||
|
isGlobal: true,
|
||||||
|
validationSchema: Joi.object({
|
||||||
|
// Application
|
||||||
|
NODE_ENV: Joi.string().valid("dev", "production").default("dev"),
|
||||||
|
PORT: Joi.number().default(3000),
|
||||||
|
APP_URL: Joi.string().default("http://localhost:3000"),
|
||||||
|
|
||||||
|
// JWT
|
||||||
|
JWT_SECRET: Joi.string().required(),
|
||||||
|
JWT_EXPIRATION_TIME: Joi.string().default("1d"),
|
||||||
|
|
||||||
|
// Spotify
|
||||||
|
SPOTIFY_CLIENT_ID: Joi.string().required(),
|
||||||
|
SPOTIFY_CLIENT_SECRET: Joi.string().required(),
|
||||||
|
SPOTIFY_FETCH_INTERVAL_MS: Joi.number().default(5 * 60 * 1000),
|
||||||
|
SPOTIFY_WEB_API_URL: Joi.string().default("https://api.spotify.com/"),
|
||||||
|
SPOTIFY_AUTH_API_URL: Joi.string().default(
|
||||||
|
"https://accounts.spotify.com/"
|
||||||
|
),
|
||||||
|
|
||||||
|
// DB
|
||||||
|
DB_HOST: Joi.string().required(),
|
||||||
|
DB_USERNAME: Joi.string().required(),
|
||||||
|
DB_PASSWORD: Joi.string().required(),
|
||||||
|
DB_DATABASE: Joi.string().required(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class ConfigModule {}
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
import { HttpModule, Module } from "@nestjs/common";
|
import { HttpModule, Module } from "@nestjs/common";
|
||||||
|
import { ConfigService } from "@nestjs/config";
|
||||||
import { SpotifyApiService } from "./spotify-api.service";
|
import { SpotifyApiService } from "./spotify-api.service";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
HttpModule.registerAsync({
|
HttpModule.registerAsync({
|
||||||
useFactory: () => ({
|
useFactory: (config: ConfigService) => ({
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
baseURL: "https://api.spotify.com/",
|
baseURL: config.get<string>("SPOTIFY_WEB_API_URL"),
|
||||||
}),
|
}),
|
||||||
|
inject: [ConfigService],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
providers: [SpotifyApiService],
|
providers: [SpotifyApiService],
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
import { HttpModule, Module } from "@nestjs/common";
|
import { HttpModule, Module } from "@nestjs/common";
|
||||||
|
import { ConfigService } from "@nestjs/config";
|
||||||
import { SpotifyAuthService } from "./spotify-auth.service";
|
import { SpotifyAuthService } from "./spotify-auth.service";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
HttpModule.registerAsync({
|
HttpModule.registerAsync({
|
||||||
useFactory: () => ({
|
useFactory: (config: ConfigService) => ({
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
baseURL: "https://accounts.spotify.com/",
|
baseURL: config.get<string>("SPOTIFY_AUTH_API_URL"),
|
||||||
}),
|
}),
|
||||||
|
inject: [ConfigService],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
providers: [SpotifyAuthService],
|
providers: [SpotifyAuthService],
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue