@mshima/generator-jhipster-nodejs 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +204 -0
- package/README.md +243 -2
- package/build-info.json +3 -0
- package/cli/cli-customizations.cjs +9 -0
- package/cli/cli.cjs +40 -0
- package/cli/logo.js +31 -0
- package/cli/version.cjs +12 -0
- package/generators/ci-cd/USAGE +5 -0
- package/generators/ci-cd/command.js +5 -0
- package/generators/ci-cd/generator.js +158 -0
- package/generators/ci-cd/index.js +2 -0
- package/generators/ci-cd/templates/.gitlab-ci.yml.ejs +137 -0
- package/generators/ci-cd/templates/azure-pipelines.yml.ejs +68 -0
- package/generators/ci-cd/templates/circle.yml.ejs +59 -0
- package/generators/ci-cd/templates/docker-registry.yml.ejs +58 -0
- package/generators/ci-cd/templates/github-ci.yml.ejs +90 -0
- package/generators/ci-cd/templates/jenkins/Jenkinsfile.ejs +104 -0
- package/generators/ci-cd/templates/jenkins/idea.gdsl +90 -0
- package/generators/ci-cd/templates/jenkins/jenkins.yml.ejs +33 -0
- package/generators/ci-cd/templates/travis.yml.ejs +75 -0
- package/generators/client/command.js +5 -0
- package/generators/client/generator.js +21 -0
- package/generators/client/generators/bootstrap/command.js +5 -0
- package/generators/client/generators/bootstrap/generator.js +28 -0
- package/generators/client/generators/bootstrap/index.js +2 -0
- package/generators/client/index.js +2 -0
- package/generators/common/generators/bootstrap/command.js +5 -0
- package/generators/common/generators/bootstrap/generator.js +37 -0
- package/generators/common/generators/bootstrap/index.js +2 -0
- package/generators/docker/command.js +5 -0
- package/generators/docker/generator.js +16 -0
- package/generators/docker/generators/bootstrap/command.js +5 -0
- package/generators/docker/generators/bootstrap/generator.js +56 -0
- package/generators/docker/generators/bootstrap/index.js +2 -0
- package/generators/docker/index.js +2 -0
- package/generators/docker/templates/docker/app.yml.ejs +25 -0
- package/generators/generator-nodejs-constants.js +32 -0
- package/generators/languages/command.js +5 -0
- package/generators/languages/generator.js +22 -0
- package/generators/languages/index.js +2 -0
- package/generators/languages/templates/src/main/webapp/i18n/en/home.json +19 -0
- package/generators/languages/templates/src/main/webapp/i18n/es/home.json +19 -0
- package/generators/languages/templates/src/main/webapp/i18n/it/home.json +19 -0
- package/generators/node-server/command.js +96 -0
- package/generators/node-server/entity-files.js +41 -0
- package/generators/node-server/files.js +254 -0
- package/generators/node-server/generator.js +702 -0
- package/generators/node-server/generators/bootstrap/command.js +5 -0
- package/generators/node-server/generators/bootstrap/generator.js +83 -0
- package/generators/node-server/generators/bootstrap/index.js +2 -0
- package/generators/node-server/index.js +2 -0
- package/generators/node-server/resources/package.json +76 -0
- package/generators/node-server/support/api-fake-data.js +54 -0
- package/generators/node-server/support/columns.js +73 -0
- package/generators/node-server/support/database.js +24 -0
- package/generators/node-server/support/entity-authorities.js +32 -0
- package/generators/node-server/support/entity-paths.js +13 -0
- package/generators/node-server/support/enums.js +11 -0
- package/generators/node-server/support/index.js +9 -0
- package/generators/node-server/support/mail-templates.js +82 -0
- package/generators/node-server/support/migrations.js +197 -0
- package/generators/node-server/support/validators.js +25 -0
- package/generators/node-server/templates/.dockerignore.ejs +16 -0
- package/generators/node-server/templates/.gitignore.jhi.nodejs.ejs +24 -0
- package/generators/node-server/templates/Dockerfile.ejs +54 -0
- package/generators/node-server/templates/README.md.jhi.nodejs.ejs +220 -0
- package/generators/node-server/templates/package.json.ejs +84 -0
- package/generators/node-server/templates/server/README.md.ejs +269 -0
- package/generators/node-server/templates/server/e2e/_entityFileName_.database.e2e-spec.ts.ejs +192 -0
- package/generators/node-server/templates/server/e2e/_entityFileName_.e2e-spec.ts.ejs +402 -0
- package/generators/node-server/templates/server/e2e/account.e2e-spec.ts.ejs +349 -0
- package/generators/node-server/templates/server/e2e/app.e2e-spec.ts.ejs +188 -0
- package/generators/node-server/templates/server/e2e/authority.e2e-spec.ts.ejs +50 -0
- package/generators/node-server/templates/server/e2e/cors.e2e-spec.ts.ejs +110 -0
- package/generators/node-server/templates/server/e2e/management.e2e-spec.ts.ejs +180 -0
- package/generators/node-server/templates/server/e2e/oauth2-bearer.e2e-spec.ts.ejs +71 -0
- package/generators/node-server/templates/server/e2e/session.e2e-spec.ts.ejs +219 -0
- package/generators/node-server/templates/server/e2e/setup.test.js.ejs +1 -0
- package/generators/node-server/templates/server/e2e/user.e2e-spec.ts.ejs +318 -0
- package/generators/node-server/templates/server/env.ejs +1 -0
- package/generators/node-server/templates/server/eslint.config.mjs.ejs +48 -0
- package/generators/node-server/templates/server/nest-cli.json.ejs +11 -0
- package/generators/node-server/templates/server/ormconfig.ts.ejs +35 -0
- package/generators/node-server/templates/server/package.json.ejs +143 -0
- package/generators/node-server/templates/server/sonar-project.properties.ejs +10 -0
- package/generators/node-server/templates/server/src/app.config.spec.ts.ejs +13 -0
- package/generators/node-server/templates/server/src/app.config.ts.ejs +179 -0
- package/generators/node-server/templates/server/src/app.module.ts.ejs +80 -0
- package/generators/node-server/templates/server/src/application-config.ts.ejs +153 -0
- package/generators/node-server/templates/server/src/auth/account.controller.ts.ejs +183 -0
- package/generators/node-server/templates/server/src/auth/auth.module.ts.ejs +104 -0
- package/generators/node-server/templates/server/src/auth/auth.service.ts.ejs +294 -0
- package/generators/node-server/templates/server/src/auth/csrf.middleware.spec.ts.ejs +65 -0
- package/generators/node-server/templates/server/src/auth/csrf.middleware.ts.ejs +76 -0
- package/generators/node-server/templates/server/src/auth/decorators/auth-user.decorator.ts.ejs +8 -0
- package/generators/node-server/templates/server/src/auth/decorators/roles.decorator.ts.ejs +4 -0
- package/generators/node-server/templates/server/src/auth/dto/key-and-password.dto.ts.ejs +17 -0
- package/generators/node-server/templates/server/src/auth/dto/password-change.dto.ts.ejs +17 -0
- package/generators/node-server/templates/server/src/auth/dto/user-login.dto.ts.ejs +21 -0
- package/generators/node-server/templates/server/src/auth/guards/auth.guard.ts.ejs +50 -0
- package/generators/node-server/templates/server/src/auth/guards/oauth2-login.guard.ts.ejs +6 -0
- package/generators/node-server/templates/server/src/auth/guards/roles.guard.ts.ejs +25 -0
- package/generators/node-server/templates/server/src/auth/index.ts.ejs +8 -0
- package/generators/node-server/templates/server/src/auth/jwt.config.spec.ts.ejs +22 -0
- package/generators/node-server/templates/server/src/auth/jwt.config.ts.ejs +29 -0
- package/generators/node-server/templates/server/src/auth/oauth2.authorities.spec.ts.ejs +24 -0
- package/generators/node-server/templates/server/src/auth/oauth2.authorities.ts.ejs +33 -0
- package/generators/node-server/templates/server/src/auth/oauth2.config.ts.ejs +51 -0
- package/generators/node-server/templates/server/src/auth/passport.jwt.strategy.ts.ejs +45 -0
- package/generators/node-server/templates/server/src/auth/passport.oauth2-bearer.strategy.ts.ejs +32 -0
- package/generators/node-server/templates/server/src/auth/passport.oauth2.strategy.spec.ts.ejs +27 -0
- package/generators/node-server/templates/server/src/auth/passport.oauth2.strategy.ts.ejs +44 -0
- package/generators/node-server/templates/server/src/auth/password-util.ts.ejs +10 -0
- package/generators/node-server/templates/server/src/auth/password.service.ts.ejs +34 -0
- package/generators/node-server/templates/server/src/auth/payload.interface.ts.ejs +14 -0
- package/generators/node-server/templates/server/src/auth/role-type.ts.ejs +7 -0
- package/generators/node-server/templates/server/src/auth/session-user.middleware.ts.ejs +33 -0
- package/generators/node-server/templates/server/src/auth/session.entity.ts.ejs +36 -0
- package/generators/node-server/templates/server/src/auth/session.store.spec.ts.ejs +99 -0
- package/generators/node-server/templates/server/src/auth/session.store.ts.ejs +116 -0
- package/generators/node-server/templates/server/src/auth/user.jwt.controller.ts.ejs +26 -0
- package/generators/node-server/templates/server/src/auth/user.oauth2.controller.ts.ejs +78 -0
- package/generators/node-server/templates/server/src/auth/user.session.controller.ts.ejs +103 -0
- package/generators/node-server/templates/server/src/common/common.module.ts.ejs +19 -0
- package/generators/node-server/templates/server/src/common/database/base.entity.ts.ejs +13 -0
- package/generators/node-server/templates/server/src/common/database/column-transformers.spec.ts.ejs +46 -0
- package/generators/node-server/templates/server/src/common/database/column-transformers.ts.ejs +69 -0
- package/generators/node-server/templates/server/src/common/database/column-types.spec.ts.ejs +21 -0
- package/generators/node-server/templates/server/src/common/database/column-types.ts.ejs +29 -0
- package/generators/node-server/templates/server/src/common/database/pagination.entity.spec.ts.ejs +66 -0
- package/generators/node-server/templates/server/src/common/database/pagination.entity.ts.ejs +108 -0
- package/generators/node-server/templates/server/src/common/dto/base.dto.ts.ejs +19 -0
- package/generators/node-server/templates/server/src/common/errors/error-constants.ts.ejs +10 -0
- package/generators/node-server/templates/server/src/common/errors/problem-details.filter.ts.ejs +63 -0
- package/generators/node-server/templates/server/src/common/errors/problem.exception.ts.ejs +92 -0
- package/generators/node-server/templates/server/src/common/field_validators.ejs +77 -0
- package/generators/node-server/templates/server/src/common/header-util.ts.ejs +105 -0
- package/generators/node-server/templates/server/src/common/interceptors/logging.interceptor.spec.ts.ejs +93 -0
- package/generators/node-server/templates/server/src/common/interceptors/logging.interceptor.ts.ejs +48 -0
- package/generators/node-server/templates/server/src/common/logging.spec.ts.ejs +83 -0
- package/generators/node-server/templates/server/src/common/logging.ts.ejs +129 -0
- package/generators/node-server/templates/server/src/common/metrics.spec.ts.ejs +43 -0
- package/generators/node-server/templates/server/src/common/metrics.ts.ejs +198 -0
- package/generators/node-server/templates/server/src/common/request.ts.ejs +8 -0
- package/generators/node-server/templates/server/src/common/sortable-properties.ts.ejs +43 -0
- package/generators/node-server/templates/server/src/common/updatable-properties.ts.ejs +14 -0
- package/generators/node-server/templates/server/src/config/application-dev.yml.ejs +118 -0
- package/generators/node-server/templates/server/src/config/application-prod.yml.ejs +97 -0
- package/generators/node-server/templates/server/src/config/application-secret-samples.yml.ejs +42 -0
- package/generators/node-server/templates/server/src/config/application-test.yml.ejs +68 -0
- package/generators/node-server/templates/server/src/config/application-tls-samples.yml.ejs +15 -0
- package/generators/node-server/templates/server/src/config/application-tls.yml.ejs +15 -0
- package/generators/node-server/templates/server/src/config/application.yml.ejs +149 -0
- package/generators/node-server/templates/server/src/config.spec.ts.ejs +81 -0
- package/generators/node-server/templates/server/src/config.ts.ejs +255 -0
- package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.controller.ts.ejs +178 -0
- package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.entity.ts.ejs +110 -0
- package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.mapper.ts.ejs +37 -0
- package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.module.ts.ejs +14 -0
- package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.service.ts.ejs +123 -0
- package/generators/node-server/templates/server/src/entities/_entityFileName_/dto/_entityFileName_.dto.ts.ejs +99 -0
- package/generators/node-server/templates/server/src/mail/mail.module.ts.ejs +49 -0
- package/generators/node-server/templates/server/src/mail/mail.service.spec.ts.ejs +105 -0
- package/generators/node-server/templates/server/src/mail/mail.service.ts.ejs +120 -0
- package/generators/node-server/templates/server/src/main.ts.ejs +114 -0
- package/generators/node-server/templates/server/src/management/api-docs.controller.ts.ejs +27 -0
- package/generators/node-server/templates/server/src/management/api-docs.service.ts.ejs +8 -0
- package/generators/node-server/templates/server/src/management/configuration.controller.ts.ejs +80 -0
- package/generators/node-server/templates/server/src/management/health.controller.spec.ts.ejs +79 -0
- package/generators/node-server/templates/server/src/management/health.controller.ts.ejs +87 -0
- package/generators/node-server/templates/server/src/management/health.module.ts.ejs +9 -0
- package/generators/node-server/templates/server/src/management/loggers.controller.ts.ejs +40 -0
- package/generators/node-server/templates/server/src/management/management.controller.spec.ts.ejs +26 -0
- package/generators/node-server/templates/server/src/management/management.controller.ts.ejs +34 -0
- package/generators/node-server/templates/server/src/management/management.module.ts.ejs +21 -0
- package/generators/node-server/templates/server/src/management/metrics.controller.ts.ejs +85 -0
- package/generators/node-server/templates/server/src/migrations/1570200270081-CreateTables.ts.ejs +64 -0
- package/generators/node-server/templates/server/src/migrations/1570200270082-CreateSessions.ts.ejs +26 -0
- package/generators/node-server/templates/server/src/migrations/1570200490072-SeedUsersRoles.ts.ejs +74 -0
- package/generators/node-server/templates/server/src/migrations/_entityConstraintsMigration_.ts.ejs +40 -0
- package/generators/node-server/templates/server/src/migrations/_entityMigration_.ts.ejs +26 -0
- package/generators/node-server/templates/server/src/migrations/support/schema.ts.ejs +202 -0
- package/generators/node-server/templates/server/src/orm.config.ts.ejs +147 -0
- package/generators/node-server/templates/server/src/registry/consul.service.ts.ejs +70 -0
- package/generators/node-server/templates/server/src/registry/eureka.service.ts.ejs +129 -0
- package/generators/node-server/templates/server/src/swagger.ts.ejs +24 -0
- package/generators/node-server/templates/server/src/tls.ts.ejs +27 -0
- package/generators/node-server/templates/server/src/users/authority.controller.ts.ejs +85 -0
- package/generators/node-server/templates/server/src/users/authority.entity.ts.ejs +22 -0
- package/generators/node-server/templates/server/src/users/dto/authority.dto.ts.ejs +10 -0
- package/generators/node-server/templates/server/src/users/dto/user.dto.ts.ejs +116 -0
- package/generators/node-server/templates/server/src/users/public.user.controller.ts.ejs +51 -0
- package/generators/node-server/templates/server/src/users/user.controller.ts.ejs +191 -0
- package/generators/node-server/templates/server/src/users/user.entity.ts.ejs +63 -0
- package/generators/node-server/templates/server/src/users/user.mapper.ts.ejs +26 -0
- package/generators/node-server/templates/server/src/users/user.module.ts.ejs +19 -0
- package/generators/node-server/templates/server/src/users/user.service.ts.ejs +156 -0
- package/generators/node-server/templates/server/tsconfig.build.json.ejs +9 -0
- package/generators/node-server/templates/server/tsconfig.json.ejs +23 -0
- package/generators/node-server/templates/server/typeorm-migration.ts.ejs +18 -0
- package/generators/node-server/templates/server/vitest.config.e2e.ts.ejs +16 -0
- package/generators/node-server/templates/server/vitest.config.ts.ejs +16 -0
- package/generators/server/command.js +7 -0
- package/generators/server/generator.js +20 -0
- package/generators/server/generators/bootstrap/command.js +5 -0
- package/generators/server/generators/bootstrap/generator.js +15 -0
- package/generators/server/generators/bootstrap/index.js +2 -0
- package/generators/server/index.js +2 -0
- package/package.json +75 -4
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { INestApplication, ValidationPipe } from '@nestjs/common';
|
|
2
|
+
import { ConfigService } from '@nestjs/config';
|
|
3
|
+
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
|
|
4
|
+
import { NextFunction, Request, Response } from 'express';
|
|
5
|
+
import { NestExpressApplication } from '@nestjs/platform-express';
|
|
6
|
+
<%_ if (authenticationUsesCsrf) { _%>
|
|
7
|
+
import session from 'express-session';
|
|
8
|
+
<%_ } _%>
|
|
9
|
+
|
|
10
|
+
import type { ApplicationConfig } from './application-config.ts';
|
|
11
|
+
import { HeaderUtil } from './common/header-util.ts';
|
|
12
|
+
import { ProblemDetailsFilter } from './common/errors/problem-details.filter.ts';
|
|
13
|
+
import { ValidationException } from './common/errors/problem.exception.ts';
|
|
14
|
+
<%_ if (authenticationUsesCsrf) { _%>
|
|
15
|
+
import { SESSION_MAX_AGE } from './auth/csrf.middleware.ts';
|
|
16
|
+
import { SessionStore } from './auth/session.store.ts';
|
|
17
|
+
<%_ } _%>
|
|
18
|
+
|
|
19
|
+
type AppConfigService = ConfigService<ApplicationConfig, true>;
|
|
20
|
+
|
|
21
|
+
// The paths of the API, which CORS applies to like the WebConfigurer of JHipster Spring Boot.
|
|
22
|
+
const CORS_PATHS = [/^\/api\//, /^\/management\//, /^\/v3\/api-docs(\?|$)/];
|
|
23
|
+
// The paths of the API as Express routes them: case insensitive, with or without a trailing slash.
|
|
24
|
+
const API_PATH = /^\/(?:api|management|v3\/api-docs)(?:\/|$)/i;
|
|
25
|
+
const REGEXP_SPECIAL_CHARACTERS = /[.+?^${}()|[\]\\]/g;
|
|
26
|
+
|
|
27
|
+
function propertyList(value: string | undefined): string[] {
|
|
28
|
+
return String(value ?? '')
|
|
29
|
+
.split(',')
|
|
30
|
+
.map(value => value.trim())
|
|
31
|
+
.filter(Boolean);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The CORS options of the jhipster.cors properties, like the CorsConfiguration of JHipster Spring Boot: undefined when
|
|
36
|
+
* neither allowed-origins nor allowed-origin-patterns is set (CORS disabled, the default but in the dev profile).
|
|
37
|
+
* A pattern matches any value where it has a *, like https://*.githubpreview.dev; * as methods or headers allows them all.
|
|
38
|
+
*/
|
|
39
|
+
export function corsOptions(configService: AppConfigService): CorsOptions | undefined {
|
|
40
|
+
const cors = configService.get('jhipster.cors', { infer: true });
|
|
41
|
+
const allowedOrigins = propertyList(cors['allowed-origins']);
|
|
42
|
+
const allowedOriginPatterns = propertyList(cors['allowed-origin-patterns']).map(
|
|
43
|
+
pattern => new RegExp(`^${pattern.replace(REGEXP_SPECIAL_CHARACTERS, '\\$&').replaceAll('*', '.*')}$`),
|
|
44
|
+
);
|
|
45
|
+
if (allowedOrigins.length === 0 && allowedOriginPatterns.length === 0) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const allowedMethods = propertyList(cors['allowed-methods']);
|
|
49
|
+
const allowedHeaders = propertyList(cors['allowed-headers']);
|
|
50
|
+
const maxAge = Number(cors['max-age']);
|
|
51
|
+
const credentials = String(cors['allow-credentials']) === 'true';
|
|
52
|
+
if (credentials && allowedOrigins.includes('*')) {
|
|
53
|
+
// Like the CorsConfiguration of Spring: browsers refuse * as the allowed origin of a request with credentials.
|
|
54
|
+
throw new Error(
|
|
55
|
+
'When jhipster.cors.allow-credentials is true, jhipster.cors.allowed-origins cannot contain *: list the origins, or use jhipster.cors.allowed-origin-patterns',
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
// * allows any origin, like the allowed origins of the CorsConfiguration of Spring (cors compares the origins as given).
|
|
60
|
+
origin: allowedOrigins.includes('*') ? '*' : [...allowedOrigins, ...allowedOriginPatterns],
|
|
61
|
+
// Left out for *: the default methods of cors (all of them), the request headers echoed.
|
|
62
|
+
...(allowedMethods.includes('*') ? {} : { methods: allowedMethods }),
|
|
63
|
+
...(allowedHeaders.includes('*') ? {} : { allowedHeaders }),
|
|
64
|
+
exposedHeaders: propertyList(cors['exposed-headers']),
|
|
65
|
+
credentials,
|
|
66
|
+
...(maxAge > 0 ? { maxAge } : {}),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A middleware writing the headers of every response, like the default headers of Spring Security and the headers of
|
|
72
|
+
* the SecurityConfiguration of JHipster Spring Boot<% if (!skipClient) { %> (jhipster.security.content-security-policy)<% } %>.
|
|
73
|
+
*/
|
|
74
|
+
function responseHeaders(<% if (!skipClient) { %>configService: AppConfigService<% } %>): (req: Request, res: Response, next: NextFunction) => void {
|
|
75
|
+
<%_ if (!skipClient) { _%>
|
|
76
|
+
const contentSecurityPolicy = String(configService.get('jhipster.security.content-security-policy', { infer: true }) ?? '');
|
|
77
|
+
<%_ } _%>
|
|
78
|
+
return (req, res, next) => {
|
|
79
|
+
if (API_PATH.test(req.path)) {
|
|
80
|
+
// The cache control of Spring Security on the responses of the API: not cached (the static files of the client are).
|
|
81
|
+
res.setHeader('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate');
|
|
82
|
+
res.setHeader('Pragma', 'no-cache');
|
|
83
|
+
res.setHeader('Expires', '0');
|
|
84
|
+
}
|
|
85
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
86
|
+
res.setHeader('X-XSS-Protection', '0');
|
|
87
|
+
<%_ if (skipClient) { _%>
|
|
88
|
+
res.setHeader('X-Frame-Options', 'DENY');
|
|
89
|
+
<%_ } else { _%>
|
|
90
|
+
if (contentSecurityPolicy) {
|
|
91
|
+
res.setHeader('Content-Security-Policy', contentSecurityPolicy);
|
|
92
|
+
}
|
|
93
|
+
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
|
|
94
|
+
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
|
|
95
|
+
res.setHeader(
|
|
96
|
+
'Permissions-Policy',
|
|
97
|
+
'camera=(), fullscreen=(self), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), sync-xhr=()',
|
|
98
|
+
);
|
|
99
|
+
<%_ } _%>
|
|
100
|
+
if (req.secure) {
|
|
101
|
+
// Like Spring Security, on the HTTPS requests only (the tls profile).
|
|
102
|
+
res.setHeader('Strict-Transport-Security', 'max-age=31536000 ; includeSubDomains');
|
|
103
|
+
}
|
|
104
|
+
next();
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Configures the application as it runs in production: main.ts and the e2e tests call it, so the e2e tests
|
|
110
|
+
* exercise the same validation and HTTP behaviour as the started application.
|
|
111
|
+
* It has no side effect at import (main.ts starts the application when imported), and does not listen.
|
|
112
|
+
*/
|
|
113
|
+
/**
|
|
114
|
+
* The proxies whose X-Forwarded-* headers (the protocol, the host and the address of the client) the application trusts, the
|
|
115
|
+
* trust proxy setting of Express, like the server.forward-headers-strategy of Spring Boot: none, or native, the proxies of
|
|
116
|
+
* the local networks like the internal proxies of the RemoteIpValve of Tomcat.<% if (authenticationUsesCsrf) { %> Behind a proxy of HTTPS, the session cookie is then
|
|
117
|
+
* secure.<% } %>
|
|
118
|
+
*/
|
|
119
|
+
export function trustProxy(strategy: string | undefined): string | false {
|
|
120
|
+
return strategy === 'native' ? 'loopback, linklocal, uniquelocal' : false;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function configureApp(app: INestApplication): INestApplication {
|
|
124
|
+
// Without the X-Powered-By: Express header, like the responses of JHipster Spring Boot.
|
|
125
|
+
app.getHttpAdapter().getInstance().disable('x-powered-by');
|
|
126
|
+
const configService = app.get<AppConfigService>(ConfigService);
|
|
127
|
+
(app as NestExpressApplication).set('trust proxy', trustProxy(configService.get('server.forward-headers-strategy', { infer: true })));
|
|
128
|
+
app.use(responseHeaders(<% if (!skipClient) { %>configService<% } %>));
|
|
129
|
+
const cors = corsOptions(configService);
|
|
130
|
+
if (cors) {
|
|
131
|
+
app.enableCors((req: Request, callback: (error: Error | null, options: CorsOptions) => void) =>
|
|
132
|
+
callback(null, CORS_PATHS.some(path => path.test(req.url)) ? cors : { origin: false }),
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
<%_ if (authenticationUsesCsrf) { _%>
|
|
136
|
+
app.use(
|
|
137
|
+
session({
|
|
138
|
+
// The session cookie of JHipster Spring Boot.
|
|
139
|
+
name: 'JSESSIONID',
|
|
140
|
+
secret: configService.get('jhipster.security.session.secret', { infer: true }),
|
|
141
|
+
// The sessions in the database of the application, which outlive a restart and are shared by its instances.
|
|
142
|
+
store: app.get(SessionStore),
|
|
143
|
+
resave: false,
|
|
144
|
+
saveUninitialized: false,
|
|
145
|
+
// Like the session of JHipster Spring Boot, it expires after 30 minutes without requests.
|
|
146
|
+
rolling: true,
|
|
147
|
+
cookie: { httpOnly: true, sameSite: 'lax', secure: 'auto', maxAge: SESSION_MAX_AGE },
|
|
148
|
+
}),
|
|
149
|
+
);
|
|
150
|
+
<%_ } _%>
|
|
151
|
+
app.useGlobalPipes(
|
|
152
|
+
new ValidationPipe({
|
|
153
|
+
// The errors of the fields, like JHipster Spring Boot.
|
|
154
|
+
exceptionFactory: errors => new ValidationException(errors),
|
|
155
|
+
// The body is an instance of its DTO without the properties the DTO does not declare, like JHipster Spring Boot
|
|
156
|
+
// binds a request to its DTO and ignores the unknown properties: the declared properties without validation are
|
|
157
|
+
// @Allow(). The instance keeps the properties excluded from the responses only (the password of a registration).
|
|
158
|
+
whitelist: true,
|
|
159
|
+
transform: true,
|
|
160
|
+
// https://github.com/nestjs/nest/issues/10683#issuecomment-1349614194
|
|
161
|
+
forbidUnknownValues: false,
|
|
162
|
+
// The target of an error names the objectName of its field error (ValidationException), which is not sent: Nest
|
|
163
|
+
// 12.2 leaves it out by default.
|
|
164
|
+
validationError: { target: true },
|
|
165
|
+
}),
|
|
166
|
+
);
|
|
167
|
+
// The errors as the problem details of JHipster Spring Boot.
|
|
168
|
+
app.useGlobalFilters(new ProblemDetailsFilter(app.get(HeaderUtil)));
|
|
169
|
+
<%_ if (generateUserManagement) { _%>
|
|
170
|
+
// The mail of a password reset request is a text/plain body, as the JHipster clients send it.
|
|
171
|
+
(app as NestExpressApplication).useBodyParser('text');
|
|
172
|
+
<%_ } _%>
|
|
173
|
+
// The JSON bodies up to 10 MB, the blobs of the entities as base64 included (the 100 KB default of Express refused an
|
|
174
|
+
// image of about 75 KB with 413).
|
|
175
|
+
(app as NestExpressApplication).useBodyParser('json', { limit: '10mb' });
|
|
176
|
+
// Disable cache.
|
|
177
|
+
app.getHttpAdapter().getInstance().set('etag', false);
|
|
178
|
+
return app;
|
|
179
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
3
|
+
import { APP_INTERCEPTOR } from '@nestjs/core';
|
|
4
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
5
|
+
<%_ if (generateUserManagement) { _%>
|
|
6
|
+
import { ScheduleModule } from '@nestjs/schedule';
|
|
7
|
+
<%_ } _%>
|
|
8
|
+
import { AuthModule } from './auth/auth.module.ts';
|
|
9
|
+
import { CommonModule } from './common/common.module.ts';
|
|
10
|
+
import { HealthModule } from './management/health.module.ts';
|
|
11
|
+
import { ManagementModule } from './management/management.module.ts';
|
|
12
|
+
import { ormConfig } from './orm.config.ts';
|
|
13
|
+
import { configuration } from './config.ts';
|
|
14
|
+
import { LoggingInterceptor } from './common/interceptors/logging.interceptor.ts';
|
|
15
|
+
<%_ if (serviceDiscoveryEureka) { _%>
|
|
16
|
+
import { EurekaService } from './registry/eureka.service.ts';
|
|
17
|
+
<%_ } _%>
|
|
18
|
+
<%_ if (serviceDiscoveryConsul) { _%>
|
|
19
|
+
import { ConsulService } from './registry/consul.service.ts';
|
|
20
|
+
<%_ } _%>
|
|
21
|
+
<%_ if (!skipClient) { _%>
|
|
22
|
+
import { config } from './config.ts';
|
|
23
|
+
import { ServeStaticModule } from '@nestjs/serve-static';
|
|
24
|
+
<%_ } _%>
|
|
25
|
+
// jhipster-needle-add-entity-module-to-main-import - JHipster will import entity modules here, do not remove
|
|
26
|
+
// jhipster-needle-add-controller-module-to-main-import - JHipster will import controller modules here, do not remove
|
|
27
|
+
// jhipster-needle-add-service-module-to-main-import - JHipster will import service modules here, do not remove
|
|
28
|
+
|
|
29
|
+
@Module({
|
|
30
|
+
imports: [
|
|
31
|
+
// The configuration of the application*.yml files, read with ConfigService. main.ts loads the .env file.
|
|
32
|
+
ConfigModule.forRoot({ isGlobal: true, ignoreEnvFile: true, cache: true, load: [configuration] }),
|
|
33
|
+
CommonModule,
|
|
34
|
+
// The database of the active profiles, from the configuration (their application-{profile}.yml files and the environment).
|
|
35
|
+
TypeOrmModule.forRootAsync({
|
|
36
|
+
inject: [ConfigService],
|
|
37
|
+
useFactory: (configService: ConfigService) => ormConfig(key => configService.get(key)),
|
|
38
|
+
}),
|
|
39
|
+
<%_ if (!skipClient) { _%>
|
|
40
|
+
<%_
|
|
41
|
+
const spaExcludedPrefixes = ['api', 'management', 'v3/api-docs'];
|
|
42
|
+
if (authenticationTypeOauth2 && (applicationTypeGateway || applicationTypeMonolith)) spaExcludedPrefixes.push('login', 'oauth2');
|
|
43
|
+
if (applicationTypeGateway) spaExcludedPrefixes.push('services');
|
|
44
|
+
_%>
|
|
45
|
+
ServeStaticModule.forRoot({
|
|
46
|
+
rootPath: config.getClientPath(),
|
|
47
|
+
// The index.html of the client for the paths of its routes only, like the SpaWebFilter of JHipster Spring Boot: an
|
|
48
|
+
// unknown path of the API, or a missing file (a path with a period), is not found.
|
|
49
|
+
exclude: /^\/(?:<%- spaExcludedPrefixes.map(prefix => prefix.replace('/', '\\/')).join('|') %>)|\./,
|
|
50
|
+
}),
|
|
51
|
+
<%_ } _%>
|
|
52
|
+
<%_ if (generateUserManagement) { _%>
|
|
53
|
+
// The scheduled tasks, like the removal of the users not activated (@Cron of UserService).
|
|
54
|
+
ScheduleModule.forRoot(),
|
|
55
|
+
<%_ } _%>
|
|
56
|
+
AuthModule,
|
|
57
|
+
HealthModule,
|
|
58
|
+
ManagementModule,
|
|
59
|
+
// jhipster-needle-add-entity-module-to-main - JHipster will add entity modules here, do not remove
|
|
60
|
+
],
|
|
61
|
+
controllers: [
|
|
62
|
+
// jhipster-needle-add-controller-module-to-main - JHipster will add controller modules here, do not remove
|
|
63
|
+
],
|
|
64
|
+
providers: [
|
|
65
|
+
// Logs the requests of every controller, opt out with @SkipLogging().
|
|
66
|
+
{ provide: APP_INTERCEPTOR, useClass: LoggingInterceptor },
|
|
67
|
+
<%_ if (serviceDiscoveryEureka) { _%>
|
|
68
|
+
// The registration in the Eureka server, started by main.ts once the application listens.
|
|
69
|
+
EurekaService,
|
|
70
|
+
<%_ } _%>
|
|
71
|
+
<%_ if (serviceDiscoveryConsul) { _%>
|
|
72
|
+
// The registration in Consul, started by main.ts once the application listens.
|
|
73
|
+
ConsulService,
|
|
74
|
+
<%_ } _%>
|
|
75
|
+
// jhipster-needle-add-service-module-to-main - JHipster will add service modules here, do not remove
|
|
76
|
+
],
|
|
77
|
+
})
|
|
78
|
+
export class AppModule {
|
|
79
|
+
|
|
80
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { isInt, isNotEmpty, isPort<% if (authenticationTypeOauth2 || serviceDiscoveryEureka) { %>, isURL<% } %> } from 'class-validator';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The properties of the application the providers read with ConfigService<ApplicationConfig, true>, nested by the dotted
|
|
5
|
+
* names of the application*.yml files, like the JHipsterProperties of JHipster Spring Boot: ConfigService infers the type
|
|
6
|
+
* of a property from its path (configService.get('jhipster.cors.max-age', { infer: true }) is a number).
|
|
7
|
+
*/
|
|
8
|
+
export interface ApplicationConfig {
|
|
9
|
+
server: {
|
|
10
|
+
port: string | number;
|
|
11
|
+
'forward-headers-strategy': 'none' | 'native';
|
|
12
|
+
ssl: { enabled: boolean; 'key-store': string; 'key-store-password': string; 'key-store-type': string };
|
|
13
|
+
};
|
|
14
|
+
jhipster: {
|
|
15
|
+
clientApp: { name: string };
|
|
16
|
+
security: {
|
|
17
|
+
'content-security-policy': string;
|
|
18
|
+
<%_ if (authenticationTypeJwt) { _%>
|
|
19
|
+
authentication: {
|
|
20
|
+
jwt: {
|
|
21
|
+
'base64-secret': string;
|
|
22
|
+
'token-validity-in-seconds': number;
|
|
23
|
+
'token-validity-in-seconds-for-remember-me': number;
|
|
24
|
+
'hash-salt-or-rounds': number;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
<%_ } _%>
|
|
28
|
+
<%_ if (authenticationTypeSession) { _%>
|
|
29
|
+
authentication: {
|
|
30
|
+
'hash-salt-or-rounds': number;
|
|
31
|
+
};
|
|
32
|
+
<%_ } _%>
|
|
33
|
+
<%_ if (authenticationUsesCsrf) { _%>
|
|
34
|
+
session: { secret: string };
|
|
35
|
+
<%_ } _%>
|
|
36
|
+
<%_ if (authenticationTypeOauth2) { _%>
|
|
37
|
+
oauth2: {
|
|
38
|
+
/** The audiences of the access tokens the API accepts, comma separated. */
|
|
39
|
+
audience: string;
|
|
40
|
+
client: {
|
|
41
|
+
provider: { oidc: { 'issuer-uri': string } };
|
|
42
|
+
registration: { oidc: { 'client-id': string; 'client-secret': string } };
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
<%_ } _%>
|
|
46
|
+
};
|
|
47
|
+
cors: {
|
|
48
|
+
'allowed-origins': string;
|
|
49
|
+
'allowed-origin-patterns': string;
|
|
50
|
+
'allowed-methods': string;
|
|
51
|
+
'allowed-headers': string;
|
|
52
|
+
'exposed-headers': string;
|
|
53
|
+
'allow-credentials': boolean;
|
|
54
|
+
'max-age': number;
|
|
55
|
+
};
|
|
56
|
+
mail: { from: string; 'base-url': string };
|
|
57
|
+
registry: { username?: string; password?: string };
|
|
58
|
+
};
|
|
59
|
+
<%_ if (generateUserManagement) { _%>
|
|
60
|
+
mail: { host: string; port: number; username: string; password: string };
|
|
61
|
+
<%_ } _%>
|
|
62
|
+
<%_ if (serviceDiscoveryEureka) { _%>
|
|
63
|
+
eureka: {
|
|
64
|
+
client: {
|
|
65
|
+
enabled: boolean;
|
|
66
|
+
'service-url': { defaultZone: string };
|
|
67
|
+
'register-with-eureka': boolean;
|
|
68
|
+
'fetch-registry': boolean;
|
|
69
|
+
'registry-fetch-interval-seconds': number;
|
|
70
|
+
};
|
|
71
|
+
instance: {
|
|
72
|
+
appname: string;
|
|
73
|
+
instanceId: string;
|
|
74
|
+
'prefer-ip-address': boolean;
|
|
75
|
+
'lease-renewal-interval-in-seconds': number;
|
|
76
|
+
'lease-expiration-duration-in-seconds': number;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
<%_ } _%>
|
|
80
|
+
<%_ if (serviceDiscoveryConsul) { _%>
|
|
81
|
+
cloud: {
|
|
82
|
+
consul: {
|
|
83
|
+
enabled: boolean;
|
|
84
|
+
host: string;
|
|
85
|
+
port: number;
|
|
86
|
+
discovery: {
|
|
87
|
+
'service-name': string;
|
|
88
|
+
'instance-id': string;
|
|
89
|
+
'prefer-ip-address': boolean;
|
|
90
|
+
'health-check-path': string;
|
|
91
|
+
'health-check-interval': string;
|
|
92
|
+
'health-check-timeout': string;
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
<%_ } _%>
|
|
97
|
+
ipAddress: string | null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** A rule of a property: its path, the check of its value and the value it expects. */
|
|
101
|
+
type Rule = [path: string, check: (value: any) => boolean, expected: string];
|
|
102
|
+
|
|
103
|
+
<%_ if (authenticationTypeJwt) { _%>
|
|
104
|
+
const positiveInt = (value: any): boolean => isInt(Number(value)) && Number(value) > 0;
|
|
105
|
+
<%_ } _%>
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The rules of the properties, like the validation of the configuration properties of Spring Boot: the application does
|
|
109
|
+
* not start with an invalid value, the error tells the property and what it expects. The JWT secret is checked when the
|
|
110
|
+
* JWT key is created (jwt.config.ts).
|
|
111
|
+
*/
|
|
112
|
+
const rules: Rule[] = [
|
|
113
|
+
['server.port', value => isPort(String(value)), 'a port'],
|
|
114
|
+
['server.forward-headers-strategy', value => ['none', 'native'].includes(value), 'none or native'],
|
|
115
|
+
['jhipster.clientApp.name', isNotEmpty, 'the name of the application'],
|
|
116
|
+
<%_ if (authenticationTypeJwt) { _%>
|
|
117
|
+
['jhipster.security.authentication.jwt.token-validity-in-seconds', positiveInt, 'a positive number of seconds'],
|
|
118
|
+
['jhipster.security.authentication.jwt.token-validity-in-seconds-for-remember-me', positiveInt, 'a positive number of seconds'],
|
|
119
|
+
<%_ } _%>
|
|
120
|
+
<%_ if (generateUserManagement) { _%>
|
|
121
|
+
['<%= nodejsPasswordRoundsProperty %>', value => isInt(Number(value)) && value >= 4 && value <= 31, 'bcrypt rounds, from 4 to 31'],
|
|
122
|
+
<%_ } _%>
|
|
123
|
+
['jhipster.cors.max-age', value => isInt(Number(value)) && value >= 0, 'a number of seconds'],
|
|
124
|
+
<%_ if (generateUserManagement) { _%>
|
|
125
|
+
['mail.port', value => isPort(String(value)), 'a port'],
|
|
126
|
+
<%_ } _%>
|
|
127
|
+
<%_ if (authenticationTypeOauth2) { _%>
|
|
128
|
+
['jhipster.security.oauth2.client.provider.oidc.issuer-uri', value => isURL(String(value), { require_tld: false }), 'the URL of the OpenID Connect issuer'],
|
|
129
|
+
<%_ } _%>
|
|
130
|
+
<%_ if (authenticationUsesCsrf) { _%>
|
|
131
|
+
['jhipster.security.session.secret', isNotEmpty, 'the secret of the sessions'],
|
|
132
|
+
<%_ } _%>
|
|
133
|
+
<%_ if (serviceDiscoveryEureka) { _%>
|
|
134
|
+
['eureka.client.service-url.defaultZone', value => isURL(String(value), { require_tld: false }), 'the URL of the Eureka server'],
|
|
135
|
+
<%_ } _%>
|
|
136
|
+
<%_ if (serviceDiscoveryConsul) { _%>
|
|
137
|
+
['cloud.consul.port', value => isPort(String(value)), 'a port'],
|
|
138
|
+
<%_ } _%>
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
const valueOf = (configuration: Record<string, any>, path: string): unknown =>
|
|
142
|
+
path.split('.').reduce<any>((value, name) => value?.[name], configuration);
|
|
143
|
+
|
|
144
|
+
/** Validates the configuration, nested by the dotted names of the properties: throws an error telling the invalid ones. */
|
|
145
|
+
export function validateConfiguration<T extends Record<string, any>>(configuration: T): T {
|
|
146
|
+
const errors = rules
|
|
147
|
+
.filter(([path, check]) => !check(valueOf(configuration, path)))
|
|
148
|
+
.map(([path, , expected]) => `${path} is ${JSON.stringify(valueOf(configuration, path))}, expected ${expected}`);
|
|
149
|
+
if (errors.length > 0) {
|
|
150
|
+
throw new Error(`Invalid configuration:\n ${errors.join('\n ')}`);
|
|
151
|
+
}
|
|
152
|
+
return configuration;
|
|
153
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { <%_ if (generateUserManagement) { _%> Body, Post, Query, <%_ } _%>UseGuards, Controller, Get, HttpCode, Logger, Req, UseInterceptors, ClassSerializerInterceptor, InternalServerErrorException } from '@nestjs/common';
|
|
2
|
+
import { AuthGuard } from './index.ts';
|
|
3
|
+
<%_ if (generateUserManagement) { _%>
|
|
4
|
+
import { PasswordChangeDTO } from './dto/password-change.dto.ts';
|
|
5
|
+
import { KeyAndPasswordDTO } from './dto/key-and-password.dto.ts';
|
|
6
|
+
import { MailService } from '../mail/mail.service.ts';
|
|
7
|
+
<%_ } _%>
|
|
8
|
+
import { <% if (generateUserManagement) { %>Managed<%- userLoginVmClass %>, <% } %><%- userLoginVmClass %> } from '../users/dto/user.dto.ts';
|
|
9
|
+
import { ApiBearerAuth, ApiTags, ApiResponse, ApiOperation } from '@nestjs/swagger';
|
|
10
|
+
import { AuthService } from './auth.service.ts';
|
|
11
|
+
|
|
12
|
+
@Controller('api')
|
|
13
|
+
@UseInterceptors(ClassSerializerInterceptor)
|
|
14
|
+
@ApiTags('account-resource')
|
|
15
|
+
export class AccountController {
|
|
16
|
+
logger = new Logger('AccountController');
|
|
17
|
+
|
|
18
|
+
constructor(
|
|
19
|
+
private readonly authService: AuthService,
|
|
20
|
+
<%_ if (generateUserManagement) { _%>
|
|
21
|
+
private readonly mailService: MailService,
|
|
22
|
+
<%_ } _%>
|
|
23
|
+
) { }
|
|
24
|
+
<%_ if (generateUserManagement) { _%>
|
|
25
|
+
|
|
26
|
+
@Post('/register')
|
|
27
|
+
@ApiOperation({ summary: 'Register user' })
|
|
28
|
+
@ApiResponse({
|
|
29
|
+
status: 201,
|
|
30
|
+
description: 'Registered user',
|
|
31
|
+
type: <%- user.dtoClass %>,
|
|
32
|
+
})
|
|
33
|
+
async registerAccount(@Req() req: { user: <%- userLoginVmClass %> }, @Body() userDTO: Managed<%- user.dtoClass %>): Promise <any> {
|
|
34
|
+
const user = await this.authService.registerNewUser(userDTO);
|
|
35
|
+
void this.mailService.sendActivationEmail(user);
|
|
36
|
+
return user;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@Get('/activate')
|
|
40
|
+
@ApiOperation({ summary: 'Activate the registered user' })
|
|
41
|
+
@ApiResponse({
|
|
42
|
+
status: 200,
|
|
43
|
+
description: 'activated',
|
|
44
|
+
})
|
|
45
|
+
@ApiResponse({ status: 500, description: 'No user was found for this activation key' })
|
|
46
|
+
async activateAccount(@Query('key') key: string): Promise<void> {
|
|
47
|
+
const user = await this.authService.activateRegistration(key);
|
|
48
|
+
if (!user) {
|
|
49
|
+
throw new InternalServerErrorException('No user was found for this activation key');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@Get('/authenticate')
|
|
54
|
+
@ApiBearerAuth()
|
|
55
|
+
@UseGuards(AuthGuard)
|
|
56
|
+
@ApiOperation({ summary: 'Check if the user is authenticated' })
|
|
57
|
+
@ApiResponse({
|
|
58
|
+
status: 200,
|
|
59
|
+
description: 'login authenticated',
|
|
60
|
+
})
|
|
61
|
+
isAuthenticated(@Req() req: { user: <%- userLoginVmClass %> }): any {
|
|
62
|
+
const { user } = req;
|
|
63
|
+
return (user).login;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@Get('/account')
|
|
67
|
+
@ApiBearerAuth()
|
|
68
|
+
@UseGuards(AuthGuard)
|
|
69
|
+
@ApiOperation({ summary: 'Get the current user.' })
|
|
70
|
+
@ApiResponse({
|
|
71
|
+
status: 200,
|
|
72
|
+
description: 'user retrieved',
|
|
73
|
+
})
|
|
74
|
+
async getAccount(@Req() req: { user: <%- userLoginVmClass %> }): Promise<any> {
|
|
75
|
+
const { user } = req;
|
|
76
|
+
const userProfileFound = await this.authService.getAccount(user.id!);
|
|
77
|
+
<%_ if (databaseType === 'mongodb') { _%>
|
|
78
|
+
if (userProfileFound && !userProfileFound.firstName) {
|
|
79
|
+
userProfileFound.firstName ='';
|
|
80
|
+
}
|
|
81
|
+
if (userProfileFound && !userProfileFound.lastName) {
|
|
82
|
+
userProfileFound.lastName ='';
|
|
83
|
+
}
|
|
84
|
+
<%_ } _%>
|
|
85
|
+
return userProfileFound;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@Post('/account')
|
|
89
|
+
@HttpCode(200)
|
|
90
|
+
@ApiBearerAuth()
|
|
91
|
+
@UseGuards(AuthGuard)
|
|
92
|
+
@ApiOperation({ summary: 'Update the current user information' })
|
|
93
|
+
@ApiResponse({
|
|
94
|
+
status: 200,
|
|
95
|
+
description: 'user info updated',
|
|
96
|
+
type: <%- user.dtoClass %>,
|
|
97
|
+
})
|
|
98
|
+
async saveAccount(@Req() req: { user: <%- userLoginVmClass %> }, @Body() newUserInfo: <%- user.dtoClass %>): Promise<any> {
|
|
99
|
+
const { user } = req;
|
|
100
|
+
return await this.authService.updateUserSettings(user.login, newUserInfo);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@Post('/account/change-password')
|
|
104
|
+
@HttpCode(200)
|
|
105
|
+
@ApiBearerAuth()
|
|
106
|
+
@UseGuards(AuthGuard)
|
|
107
|
+
@ApiOperation({ summary: 'Change current password' })
|
|
108
|
+
@ApiResponse({
|
|
109
|
+
status: 200,
|
|
110
|
+
description: 'user password changed',
|
|
111
|
+
type: PasswordChangeDTO,
|
|
112
|
+
})
|
|
113
|
+
async changePassword(@Req() req: { user: <%- userLoginVmClass %> }, @Body() passwordChange: PasswordChangeDTO): Promise<any> {
|
|
114
|
+
const { user } = req;
|
|
115
|
+
return await this.authService.changePassword(user.login, passwordChange.currentPassword, passwordChange.newPassword);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@Post('/account/reset-password/init')
|
|
119
|
+
@HttpCode(200)
|
|
120
|
+
@ApiOperation({ summary: 'Send an email to reset the password of the user' })
|
|
121
|
+
@ApiResponse({
|
|
122
|
+
status: 200,
|
|
123
|
+
description: 'Reset key given to the activated user of the mail, if any',
|
|
124
|
+
})
|
|
125
|
+
async requestPasswordReset(@Body() mail: string): Promise<void> {
|
|
126
|
+
const user = await this.authService.requestPasswordReset(String(mail));
|
|
127
|
+
if (user) {
|
|
128
|
+
void this.mailService.sendPasswordResetMail(user);
|
|
129
|
+
} else {
|
|
130
|
+
this.logger.warn('Password reset requested for non existing mail');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@Post('/account/reset-password/finish')
|
|
135
|
+
@HttpCode(200)
|
|
136
|
+
@ApiOperation({ summary: 'Finish to reset the password of the user' })
|
|
137
|
+
@ApiResponse({
|
|
138
|
+
status: 200,
|
|
139
|
+
description: 'password reset',
|
|
140
|
+
})
|
|
141
|
+
async finishPasswordReset(@Body() keyAndPassword: KeyAndPasswordDTO): Promise<void> {
|
|
142
|
+
await this.authService.completePasswordReset(keyAndPassword.newPassword, keyAndPassword.key);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
<%_ } else if (authenticationType === 'oauth2') { _%>
|
|
146
|
+
|
|
147
|
+
@Get('/account')
|
|
148
|
+
@ApiBearerAuth()
|
|
149
|
+
@UseGuards(AuthGuard)
|
|
150
|
+
@ApiOperation({ summary: 'Get the current user, of the session or of the bearer token, else 401' })
|
|
151
|
+
@ApiResponse({
|
|
152
|
+
status: 200,
|
|
153
|
+
description: 'User retrieved',
|
|
154
|
+
type: <%- userLoginVmClass %>,
|
|
155
|
+
})
|
|
156
|
+
getAccount(@Req() req: { user: <%- userLoginVmClass %> }): any {
|
|
157
|
+
return this.authService.getAccount(req.user);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
<%_ } else {_%>
|
|
161
|
+
|
|
162
|
+
@Get('/account')
|
|
163
|
+
@ApiBearerAuth()
|
|
164
|
+
@UseGuards(AuthGuard)
|
|
165
|
+
@ApiOperation({ summary: 'Get the current user.' })
|
|
166
|
+
@ApiResponse({
|
|
167
|
+
status: 200,
|
|
168
|
+
description: 'user retrieved',
|
|
169
|
+
})
|
|
170
|
+
<%_ if (generateBuiltInUserEntity) { _%>
|
|
171
|
+
async getAccount(@Req() req: { user: <%- userLoginVmClass %> }): Promise<any> {
|
|
172
|
+
const { user } = req;
|
|
173
|
+
return await this.authService.getAccount(user.id!);
|
|
174
|
+
}
|
|
175
|
+
<%_ } else { _%>
|
|
176
|
+
getAccount(@Req() req: { user: <%- userLoginVmClass %> }): <%- userLoginVmClass %> {
|
|
177
|
+
// The user of the token, without built-in User.
|
|
178
|
+
return req.user;
|
|
179
|
+
}
|
|
180
|
+
<%_ } _%>
|
|
181
|
+
<%_ } _%>
|
|
182
|
+
|
|
183
|
+
}
|