@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,318 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, type MockInstance, vi } from 'vitest';
|
|
2
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
|
3
|
+
import request from 'supertest';
|
|
4
|
+
import { AppModule } from '../src/app.module.ts';
|
|
5
|
+
import { configureApp } from '../src/app.config.ts';
|
|
6
|
+
import { INestApplication } from '@nestjs/common';
|
|
7
|
+
import { AuthGuard } from '../src/auth/guards/auth.guard.ts';
|
|
8
|
+
import { RolesGuard } from '../src/auth/guards/roles.guard.ts';
|
|
9
|
+
import { <%= user.dtoClass%> } from '../src/users/dto/user.dto.ts';
|
|
10
|
+
import { UserService } from '../src/users/user.service.ts';
|
|
11
|
+
import { MailService } from '../src/mail/mail.service.ts';
|
|
12
|
+
import { comparePassword } from '../src/auth/password-util.ts';
|
|
13
|
+
<%_ if (databaseTypeMongodb) { _%>
|
|
14
|
+
import { getRepositoryToken } from '@nestjs/typeorm';
|
|
15
|
+
import { Repository } from 'typeorm';
|
|
16
|
+
import { User } from '../src/users/user.entity.ts';
|
|
17
|
+
<%_ } _%>
|
|
18
|
+
|
|
19
|
+
describe('User', () => {
|
|
20
|
+
let app: INestApplication;
|
|
21
|
+
let service: UserService;
|
|
22
|
+
let sendCreationEmail: MockInstance<MailService['sendCreationEmail']>;
|
|
23
|
+
<%_ if (databaseTypeMongodb) { _%>
|
|
24
|
+
let userRepository: Repository<User>;
|
|
25
|
+
<%_ } _%>
|
|
26
|
+
|
|
27
|
+
const authGuardMock = { canActivate: (): any => true };
|
|
28
|
+
const rolesGuardMock = { canActivate: (): any => true };
|
|
29
|
+
|
|
30
|
+
const testUserRequestObject: any = {
|
|
31
|
+
login: 'userTestLogin',
|
|
32
|
+
firstName: 'UserTest',
|
|
33
|
+
lastName: 'UserTest',
|
|
34
|
+
email: 'usertest@localhost.it'
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const testUserDTO: <%= user.dtoClass%> = {
|
|
38
|
+
login: 'userTestLogin',
|
|
39
|
+
firstName: 'UserTest',
|
|
40
|
+
lastName: 'UserTest',
|
|
41
|
+
email: 'usertest@localhost.it',
|
|
42
|
+
password: 'userTestLogin'
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
<%_ if (databaseType !== 'mongodb') { _%>
|
|
46
|
+
// The user as the API gives it: without the keys the mails send.
|
|
47
|
+
const withoutKeys = ({ activationKey: _activationKey, resetKey: _resetKey, resetDate: _resetDate, ...user }: Partial<<%= user.dtoClass%>>): Partial<<%= user.dtoClass%>> => user;
|
|
48
|
+
|
|
49
|
+
<%_ } _%>
|
|
50
|
+
beforeEach(async () => {
|
|
51
|
+
const moduleFixture: TestingModule = await Test.createTestingModule({
|
|
52
|
+
imports: [AppModule],
|
|
53
|
+
})
|
|
54
|
+
.overrideGuard(AuthGuard)
|
|
55
|
+
.useValue(authGuardMock)
|
|
56
|
+
.overrideGuard(RolesGuard)
|
|
57
|
+
.useValue(rolesGuardMock)
|
|
58
|
+
.compile();
|
|
59
|
+
|
|
60
|
+
app = moduleFixture.createNestApplication();
|
|
61
|
+
configureApp(app);
|
|
62
|
+
await app.init();
|
|
63
|
+
service = moduleFixture.get<UserService>(UserService);
|
|
64
|
+
// The mails are not sent, the tests check the users they are for.
|
|
65
|
+
sendCreationEmail = vi.spyOn(moduleFixture.get<MailService>(MailService), 'sendCreationEmail').mockResolvedValue();
|
|
66
|
+
<%_ if (databaseTypeMongodb) { _%>
|
|
67
|
+
userRepository = moduleFixture.get<Repository<User>>(getRepositoryToken(User));
|
|
68
|
+
<%_ } _%>
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('/POST create user', async () => {
|
|
72
|
+
const response = await request(app.getHttpServer())
|
|
73
|
+
.post('/api/admin/users')
|
|
74
|
+
.send(testUserRequestObject)
|
|
75
|
+
.expect(201);
|
|
76
|
+
const createdUser: <%= user.dtoClass%> = response.body;
|
|
77
|
+
|
|
78
|
+
// Like JHipster Spring Boot, the login in lower case, and the location of the user by its login.
|
|
79
|
+
expect(createdUser.login).toEqual(testUserRequestObject.login.toLowerCase());
|
|
80
|
+
expect(response.headers.location).toBe(`/api/admin/users/${encodeURIComponent(createdUser.login)}`);
|
|
81
|
+
// Like JHipster Spring Boot, an activated user with a random password, and a reset key sent by mail.
|
|
82
|
+
const savedUser = (await service.findByFields({ where: { login: createdUser.login } }))!;
|
|
83
|
+
expect(savedUser.activated).toBe(true);
|
|
84
|
+
expect(savedUser.resetKey).toBeTruthy();
|
|
85
|
+
expect(await comparePassword(testUserRequestObject.login, savedUser.password)).toBe(false);
|
|
86
|
+
expect(sendCreationEmail).toHaveBeenCalledWith(expect.objectContaining({ login: createdUser.login, resetKey: savedUser.resetKey }));
|
|
87
|
+
await service.delete(createdUser);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('/POST create user with an id is a bad request, like JHipster Spring Boot', async () => {
|
|
91
|
+
const problem = (
|
|
92
|
+
await request(app.getHttpServer())
|
|
93
|
+
.post('/api/admin/users')
|
|
94
|
+
.send({ ...testUserRequestObject, id: <%- databaseTypeMongodb ? "'000000000000000000000042'" : '42' %> })
|
|
95
|
+
.expect(400)
|
|
96
|
+
).body;
|
|
97
|
+
|
|
98
|
+
expect(problem).toMatchObject({ message: 'error.idexists', params: 'userManagement' });
|
|
99
|
+
expect(await service.findByFields({ where: { login: testUserRequestObject.login.toLowerCase() } })).toBeFalsy();
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('/POST create user keeps the fields of the user only: activated, its own keys and audit', async () => {
|
|
103
|
+
const createdUser: <%= user.dtoClass%> = (
|
|
104
|
+
await request(app.getHttpServer())
|
|
105
|
+
.post('/api/admin/users')
|
|
106
|
+
.send({ ...testUserRequestObject, activated: false, password: 'chosenPassword', activationKey: 'chosenKey', resetKey: 'chosenKey', createdBy: 'someone' })
|
|
107
|
+
.expect(201)
|
|
108
|
+
).body;
|
|
109
|
+
|
|
110
|
+
const savedUser = (await service.findByFields({ where: { login: testUserRequestObject.login.toLowerCase() } }))!;
|
|
111
|
+
expect(savedUser.activated).toBe(true);
|
|
112
|
+
expect(savedUser.password).not.toEqual('chosenPassword');
|
|
113
|
+
expect(savedUser.activationKey).toBeFalsy();
|
|
114
|
+
expect(savedUser.resetKey).toEqual(expect.any(String));
|
|
115
|
+
expect(savedUser.resetKey).not.toEqual('chosenKey');
|
|
116
|
+
expect(savedUser.createdBy).not.toEqual('someone');
|
|
117
|
+
await service.delete(createdUser);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('/POST create user with the login of another user is a login already used problem', async () => {
|
|
121
|
+
const savedUser = await service.save({ ...testUserDTO, login: 'usedlogin', email: 'usedlogin@localhost.it' });
|
|
122
|
+
|
|
123
|
+
const problem = (
|
|
124
|
+
await request(app.getHttpServer())
|
|
125
|
+
.post('/api/admin/users')
|
|
126
|
+
.send({ ...testUserRequestObject, login: 'UsedLogin' })
|
|
127
|
+
.expect(400)
|
|
128
|
+
).body;
|
|
129
|
+
|
|
130
|
+
expect(problem).toMatchObject({ type: 'https://www.jhipster.tech/problem/login-already-used' });
|
|
131
|
+
await service.delete(savedUser);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('removes the users not activated 3 days after their registration', async () => {
|
|
135
|
+
const registeredDate = new Date(Date.now() - 4 * 24 * 60 * 60 * 1000);
|
|
136
|
+
const notActivatedUser = await service.save({ ...testUserDTO, login: 'notactivated', email: 'notactivated@localhost.it', activated: false, activationKey: 'notActivatedKey', createdDate: registeredDate });
|
|
137
|
+
const recentUser = await service.save({ ...testUserDTO, login: 'recentuser', email: 'recentuser@localhost.it', activated: false, activationKey: 'recentKey' });
|
|
138
|
+
|
|
139
|
+
<%_ if (databaseTypeMongodb) { _%>
|
|
140
|
+
// MongoDB gives the date of the creation whatever the saved user has.
|
|
141
|
+
await userRepository.update(notActivatedUser.id!, { createdDate: registeredDate });
|
|
142
|
+
<%_ } _%>
|
|
143
|
+
await service.removeNotActivatedUsers();
|
|
144
|
+
|
|
145
|
+
expect(await service.findByFields({ where: { login: notActivatedUser.login } })).toBeFalsy();
|
|
146
|
+
expect(await service.findByFields({ where: { login: recentUser.login } })).toBeTruthy();
|
|
147
|
+
await service.delete(recentUser);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('/GET public users gives the activated users by their id and login only, like JHipster Spring Boot', async () => {
|
|
151
|
+
const activated = await service.save({ ...testUserDTO, login: 'publicactive', email: 'publicactive@localhost.it', activated: true });
|
|
152
|
+
const inactive = await service.save({ ...testUserDTO, login: 'publicinactive', email: 'publicinactive@localhost.it', activated: false });
|
|
153
|
+
|
|
154
|
+
const users: Record<string, unknown>[] = (await request(app.getHttpServer()).get('/api/users?size=2000').expect(200)).body;
|
|
155
|
+
|
|
156
|
+
expect(users.find(user => user.login === 'publicactive')).toEqual({ id: expect.anything(), login: 'publicactive' });
|
|
157
|
+
expect(users.map(user => user.login)).not.toContain('publicinactive');
|
|
158
|
+
expect(users.every(user => Object.keys(user).sort().join() === 'id,login')).toBe(true);
|
|
159
|
+
await service.delete(activated);
|
|
160
|
+
await service.delete(inactive);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('/GET public users sorted on a property out of the allowed ones is a bad request', () =>
|
|
164
|
+
request(app.getHttpServer()).get('/api/users?sort=password,asc').expect(400));
|
|
165
|
+
|
|
166
|
+
it('/POST create user with an invalid email is a validation error', async () => {
|
|
167
|
+
const response = await request(app.getHttpServer())
|
|
168
|
+
.post('/api/admin/users')
|
|
169
|
+
.send({ ...testUserRequestObject, email: 'not an email' })
|
|
170
|
+
.expect(400)
|
|
171
|
+
.expect('Content-Type', /application\/problem\+json/);
|
|
172
|
+
|
|
173
|
+
// The problem detail of JHipster Spring Boot, with the errors of the fields.
|
|
174
|
+
expect(response.body).toMatchObject({
|
|
175
|
+
type: 'https://www.jhipster.tech/problem/constraint-violation',
|
|
176
|
+
status: 400,
|
|
177
|
+
message: 'error.validation',
|
|
178
|
+
path: '/api/admin/users',
|
|
179
|
+
fieldErrors: [{ objectName: 'user', field: 'email', message: expect.any(String) }],
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('/GET all users', async () => {
|
|
184
|
+
const savedUser = await service.save({ ...testUserDTO, login: 'listeduser', email: 'listeduser@localhost.it' });
|
|
185
|
+
const response = await request(app.getHttpServer())
|
|
186
|
+
.get('/api/admin/users')
|
|
187
|
+
.expect(200);
|
|
188
|
+
|
|
189
|
+
expect(response.body.map((user: any) => user.login)).toContain(savedUser.login);
|
|
190
|
+
expect(Number(response.headers['x-total-count'])).toBeGreaterThanOrEqual(response.body.length);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('/PUT update user', async () => {
|
|
194
|
+
testUserDTO.login = 'TestUserUpdate';
|
|
195
|
+
const { password: _savedPassword, lastModifiedDate: _savedLastModifiedDate, ...savedUser } = await service.save(testUserDTO);
|
|
196
|
+
savedUser.firstName = 'Updated Name';
|
|
197
|
+
|
|
198
|
+
const { password: _updatedPassword, lastModifiedDate: _updatedLastModifiedDate, ...updatedUser } = (
|
|
199
|
+
await request(app.getHttpServer())
|
|
200
|
+
.put('/api/admin/users')
|
|
201
|
+
.send(savedUser)
|
|
202
|
+
.expect(200)
|
|
203
|
+
).body;
|
|
204
|
+
|
|
205
|
+
<%_ if (databaseType !== 'mongodb') { _%>
|
|
206
|
+
// Like JHipster Spring Boot, the login in lower case.
|
|
207
|
+
expect(updatedUser).toEqual(JSON.parse(JSON.stringify(withoutKeys({ ...savedUser, login: savedUser.login.toLowerCase() }))));
|
|
208
|
+
<%_ } else { _%>
|
|
209
|
+
expect(updatedUser.firstName).toEqual(savedUser.firstName);
|
|
210
|
+
<%_ } _%>
|
|
211
|
+
|
|
212
|
+
await service.delete(savedUser as <%= user.dtoClass%>);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('/PUT update user with a login name', async () => {
|
|
216
|
+
testUserDTO.login = 'TestUserUpdateLogin';
|
|
217
|
+
const { password: _savedPassword, lastModifiedDate: _savedLastModifiedDate, ...savedUser } = await service.save(testUserDTO);
|
|
218
|
+
savedUser.firstName = 'Updated Name';
|
|
219
|
+
|
|
220
|
+
const { password: _updatedPassword, lastModifiedDate: _updatedLastModifiedDate, ...updatedUser } = (
|
|
221
|
+
await request(app.getHttpServer())
|
|
222
|
+
.put('/api/admin/users/' + savedUser.login)
|
|
223
|
+
.send(savedUser)
|
|
224
|
+
.expect(200)
|
|
225
|
+
).body;
|
|
226
|
+
|
|
227
|
+
<%_ if (databaseType !== 'mongodb') { _%>
|
|
228
|
+
// Like JHipster Spring Boot, the login in lower case.
|
|
229
|
+
expect(updatedUser).toEqual(JSON.parse(JSON.stringify(withoutKeys({ ...savedUser, login: savedUser.login.toLowerCase() }))));
|
|
230
|
+
<%_ } else { _%>
|
|
231
|
+
expect(updatedUser.firstName).toEqual(savedUser.firstName);
|
|
232
|
+
<%_ } _%>
|
|
233
|
+
|
|
234
|
+
await service.delete(savedUser as <%= user.dtoClass%>);
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('/PUT update user keeps the password and the keys of the user', async () => {
|
|
238
|
+
testUserDTO.login = 'testuserkeep';
|
|
239
|
+
const savedUser = await service.save({ ...testUserDTO, resetKey: 'savedKey' });
|
|
240
|
+
|
|
241
|
+
await request(app.getHttpServer())
|
|
242
|
+
.put('/api/admin/users')
|
|
243
|
+
.send({ ...savedUser, firstName: 'Updated Name', password: 'chosenPassword', resetKey: 'chosenKey' })
|
|
244
|
+
.expect(200);
|
|
245
|
+
|
|
246
|
+
const updatedUser = (await service.findByFields({ where: { login: 'testuserkeep' } }))!;
|
|
247
|
+
expect(updatedUser.firstName).toEqual('Updated Name');
|
|
248
|
+
expect(updatedUser.password).toEqual(savedUser.password);
|
|
249
|
+
expect(updatedUser.resetKey).toEqual('savedKey');
|
|
250
|
+
await service.delete(updatedUser);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('/PUT update an unknown user is not found, like JHipster Spring Boot', () =>
|
|
254
|
+
request(app.getHttpServer())
|
|
255
|
+
.put('/api/admin/users')
|
|
256
|
+
.send({ ...testUserRequestObject, login: 'unknownuser', email: 'unknownuser@localhost.it', id: <%- databaseTypeMongodb ? "'000000000000000000000042'" : '42' %> })
|
|
257
|
+
.expect(404));
|
|
258
|
+
|
|
259
|
+
it('/GET user with a login name gives its authorities', async () => {
|
|
260
|
+
testUserDTO.login = 'testusergetauthorities';
|
|
261
|
+
const savedUser = await service.save({ ...testUserDTO, authorities: ['ROLE_USER'] });
|
|
262
|
+
|
|
263
|
+
const getUser: <%= user.dtoClass%> = (await request(app.getHttpServer()).get('/api/admin/users/testusergetauthorities').expect(200)).body;
|
|
264
|
+
|
|
265
|
+
expect(getUser.authorities).toEqual(['ROLE_USER']);
|
|
266
|
+
await service.delete(savedUser);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('/GET user with a login name', async () => {
|
|
270
|
+
testUserDTO.login = 'TestUserGet';
|
|
271
|
+
const savedUser: <%= user.dtoClass%> = await service.save(testUserDTO);
|
|
272
|
+
<%_ if (databaseType !== 'mongodb') { _%>
|
|
273
|
+
const { password: _password, ...savedUserWithoutPassword } = savedUser;
|
|
274
|
+
<%_ } _%>
|
|
275
|
+
|
|
276
|
+
const getUser: <%= user.dtoClass%> = (
|
|
277
|
+
await request(app.getHttpServer())
|
|
278
|
+
.get('/api/admin/users/' + savedUser.login)
|
|
279
|
+
.expect(200)
|
|
280
|
+
).body;
|
|
281
|
+
|
|
282
|
+
<%_ if (databaseType !== 'mongodb') { _%>
|
|
283
|
+
expect(getUser).toEqual(JSON.parse(JSON.stringify({ ...withoutKeys(savedUserWithoutPassword), authorities: [] })));
|
|
284
|
+
<%_ } else { _%>
|
|
285
|
+
expect(getUser.login).toEqual(savedUser.login);
|
|
286
|
+
<%_ } _%>
|
|
287
|
+
|
|
288
|
+
await service.delete(savedUser);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it('/DELETE user', async () => {
|
|
292
|
+
testUserDTO.login = 'TestUserDelete';
|
|
293
|
+
const savedUser: <%= user.dtoClass%> = await service.save(testUserDTO);
|
|
294
|
+
|
|
295
|
+
await request(app.getHttpServer())
|
|
296
|
+
.delete('/api/admin/users/' + savedUser.login)
|
|
297
|
+
.expect(204);
|
|
298
|
+
|
|
299
|
+
const userUndefined = await service.findById(savedUser.id!);
|
|
300
|
+
expect(userUndefined).toBeUndefined();
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it('/GET users sorted on a property of the user', async () => {
|
|
304
|
+
await request(app.getHttpServer()).get('/api/admin/users?sort=login,desc').expect(200);
|
|
305
|
+
await request(app.getHttpServer()).get('/api/admin/users?sort=createdDate,asc').expect(200);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it('/GET users sorted on the password or a key of the user', async () => {
|
|
309
|
+
for (const property of ['password', 'activationKey', 'resetKey']) {
|
|
310
|
+
const response = await request(app.getHttpServer()).get(`/api/admin/users?sort=${property},asc`).expect(400);
|
|
311
|
+
expect(response.body.detail).toBe(`Invalid sort property: ${property}`);
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
afterEach(async () => {
|
|
316
|
+
await app?.close();
|
|
317
|
+
});
|
|
318
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
BACKEND_ENV=dev
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import eslint from '@eslint/js';
|
|
2
|
+
import globals from 'globals';
|
|
3
|
+
import prettier from 'eslint-plugin-prettier/recommended';
|
|
4
|
+
import tseslint from 'typescript-eslint';
|
|
5
|
+
|
|
6
|
+
export default tseslint.config(
|
|
7
|
+
{
|
|
8
|
+
linterOptions: {
|
|
9
|
+
reportUnusedDisableDirectives: 'error',
|
|
10
|
+
},
|
|
11
|
+
languageOptions: {
|
|
12
|
+
globals: {
|
|
13
|
+
...globals.node,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
{ ignores: ['dist', 'coverage'] },
|
|
18
|
+
eslint.configs.recommended,
|
|
19
|
+
{
|
|
20
|
+
files: ['**/*.{js,cjs,mjs}'],
|
|
21
|
+
rules: {
|
|
22
|
+
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
files: ['**/*.ts'],
|
|
27
|
+
extends: [...tseslint.configs.recommendedTypeChecked],
|
|
28
|
+
languageOptions: {
|
|
29
|
+
parserOptions: {
|
|
30
|
+
'project': ['./tsconfig.json'],
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
rules: {
|
|
34
|
+
'no-prototype-builtins': 'off',
|
|
35
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
36
|
+
'@typescript-eslint/no-floating-promises': 'off',
|
|
37
|
+
'@typescript-eslint/no-redundant-type-constituents': 'off',
|
|
38
|
+
'@typescript-eslint/no-require-imports': 'off',
|
|
39
|
+
'@typescript-eslint/no-unsafe-argument': 'off',
|
|
40
|
+
'@typescript-eslint/no-unsafe-assignment': 'off',
|
|
41
|
+
'@typescript-eslint/no-unsafe-call': 'off',
|
|
42
|
+
'@typescript-eslint/no-unsafe-member-access': 'off',
|
|
43
|
+
'@typescript-eslint/no-unsafe-return': 'off',
|
|
44
|
+
'@typescript-eslint/no-unused-vars': ['error', { 'argsIgnorePattern': '^_', 'varsIgnorePattern': '^_' }],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
prettier,
|
|
48
|
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/nest-cli",
|
|
3
|
+
"language": "ts",
|
|
4
|
+
"collection": "@nestjs/schematics",
|
|
5
|
+
"sourceRoot": "src",
|
|
6
|
+
"compilerOptions": {
|
|
7
|
+
"deleteOutDir": true,
|
|
8
|
+
"assets": [{ "include": "config/**/*", "outDir": "dist" }<% if (generateUserManagement) { %>, { "include": "i18n/**/*", "outDir": "dist" }, { "include": "templates/**/*", "outDir": "dist" }<% } %>],
|
|
9
|
+
"watchAssets": true
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// DataSource of the typeorm CLI (the typeorm npm scripts): the database of the application, of the profiles BACKEND_ENV
|
|
2
|
+
// activates. Node.js runs this file as it is (type stripping) and imports the build in dist: the entities and the
|
|
3
|
+
// migrations of src have decorators, which Node.js does not run.
|
|
4
|
+
import { config as loadEnv } from 'dotenv';
|
|
5
|
+
import { DataSource, type DataSourceOptions } from 'typeorm';
|
|
6
|
+
import type * as OrmConfigModule from './src/orm.config.ts';
|
|
7
|
+
<%_ if (databaseTypeMongodb) { _%>
|
|
8
|
+
import type * as ConfigModule from './src/config.ts';
|
|
9
|
+
<%_ } _%>
|
|
10
|
+
|
|
11
|
+
// The local settings of .env, then the development profile of .env.dev, like the development scripts: a variable set in
|
|
12
|
+
// the environment wins, like BACKEND_ENV=prod.
|
|
13
|
+
loadEnv({ path: ['.env', '.env.dev'], quiet: true });
|
|
14
|
+
|
|
15
|
+
const build = './dist';
|
|
16
|
+
const { ormConfig } = (await import(`${build}/orm.config.js`)) as typeof OrmConfigModule;
|
|
17
|
+
<%_ if (databaseTypeMongodb) { _%>
|
|
18
|
+
const { activeProfiles, config } = (await import(`${build}/config.js`)) as typeof ConfigModule;
|
|
19
|
+
|
|
20
|
+
// An embedded database (the in-memory MongoDB server of the test profile) is a new and empty database for each command.
|
|
21
|
+
if (config.get('database.embedded')) {
|
|
22
|
+
throw new Error(`The typeorm scripts need a MongoDB database, not the embedded one of the ${activeProfiles.join(',')} profiles.`);
|
|
23
|
+
}
|
|
24
|
+
<%_ } _%>
|
|
25
|
+
|
|
26
|
+
export default new DataSource({
|
|
27
|
+
...<%- databaseTypeMongodb ? '(await ormConfig())' : 'ormConfig()' %>,
|
|
28
|
+
// Every entity, the built-in ones loaded by autoLoadEntities in the application included.
|
|
29
|
+
entities: [`${import.meta.dirname}/dist/**/*.entity.js`],
|
|
30
|
+
// Every migration, the ones created or generated by the scripts included.
|
|
31
|
+
migrations: [`${import.meta.dirname}/dist/migrations/*.js`],
|
|
32
|
+
// The CLI changes the schema only when a command asks it.
|
|
33
|
+
synchronize: false,
|
|
34
|
+
migrationsRun: false,
|
|
35
|
+
} as DataSourceOptions);
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "<%= dasherizedBaseName %>-server",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"author": "",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"clean": "rimraf dist <%= relativeDir(nodeServerRootDir, temporaryDir) %>db/",
|
|
10
|
+
"build": "nest build",
|
|
11
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
12
|
+
"sonar:scanner": "sonar-scanner",
|
|
13
|
+
"start:dev": "nest start --watch --env-file .env.dev",
|
|
14
|
+
"start:debug": "nest start --debug --watch --env-file .env.dev",
|
|
15
|
+
"start:prod": "node dist/main.js",
|
|
16
|
+
"start": "npm run clean && nest start --watch --env-file .env.dev",
|
|
17
|
+
"lint": "eslint .",
|
|
18
|
+
"lint:fix": "npm run lint -- --fix",
|
|
19
|
+
"pretest": "npm run lint && npm run typecheck",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"test:cov": "vitest run --coverage",
|
|
22
|
+
"test:watch": "vitest",
|
|
23
|
+
"test:debug": "vitest --inspect-brk --no-file-parallelism",
|
|
24
|
+
"test:e2e": "vitest run --config ./vitest.config.e2e.ts --coverage --silent",
|
|
25
|
+
"typecheck": "tsc --noEmit",
|
|
26
|
+
"typeorm": "nest build && typeorm -d ormconfig.ts",
|
|
27
|
+
<%_ if (databaseTypeSql) { _%>
|
|
28
|
+
"typeorm:migration:create": "node typeorm-migration.ts migration:create src/migrations/migration",
|
|
29
|
+
"typeorm:migration:generate": "nest build && node typeorm-migration.ts migration:generate src/migrations/schema -d ormconfig.ts",
|
|
30
|
+
<%_ } else { _%>
|
|
31
|
+
"typeorm:migration:create": "typeorm migration:create src/migrations/migration",
|
|
32
|
+
<%_ } _%>
|
|
33
|
+
"typeorm:migration:run": "npm run typeorm -- migration:run",
|
|
34
|
+
"typeorm:migration:revert": "npm run typeorm -- migration:revert",
|
|
35
|
+
"typeorm:migration:show": "npm run typeorm -- migration:show"<% if (databaseTypeSql) { %>,<% } %>
|
|
36
|
+
<%_ if (databaseTypeSql) { _%>
|
|
37
|
+
"typeorm:schema:log": "npm run typeorm -- schema:log",
|
|
38
|
+
"typeorm:schema:sync": "npm run typeorm -- schema:sync"
|
|
39
|
+
<%_ } _%>
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
<%_ if (generateUserManagement) { _%>
|
|
43
|
+
"@nestjs-modules/mailer": "<%- nodeServerDependencies['@nestjs-modules/mailer'] %>",
|
|
44
|
+
<%_ } _%>
|
|
45
|
+
"<%- nodeProdDatabaseDriver %>": "<%- nodeServerDependencies[nodeProdDatabaseDriver] %>",
|
|
46
|
+
<%_ if (authenticationType === 'oauth2') { _%>
|
|
47
|
+
"@nestjs/axios": "<%- nodeServerDependencies['@nestjs/axios'] %>",
|
|
48
|
+
<%_ } _%>
|
|
49
|
+
<%_ if (authenticationUsesCsrf) { _%>
|
|
50
|
+
"express-session": "<%- nodeServerDependencies['express-session'] %>",
|
|
51
|
+
<%_ } _%>
|
|
52
|
+
"@nestjs/common": "<%- nodeServerDependencies['@nestjs/common'] %>",
|
|
53
|
+
"@nestjs/config": "<%- nodeServerDependencies['@nestjs/config'] %>",
|
|
54
|
+
"@nestjs/core": "<%- nodeServerDependencies['@nestjs/core'] %>",
|
|
55
|
+
<%_ if (authenticationType === 'jwt') { _%>
|
|
56
|
+
"@nestjs/jwt": "<%- nodeServerDependencies['@nestjs/jwt'] %>",
|
|
57
|
+
<%_ } _%>
|
|
58
|
+
"@nestjs/passport": "<%- nodeServerDependencies['@nestjs/passport'] %>",
|
|
59
|
+
"@nestjs/platform-express": "<%- nodeServerDependencies['@nestjs/platform-express'] %>",
|
|
60
|
+
"express": "<%- nodeServerDependencies['express'] %>",
|
|
61
|
+
<%_ if (generateUserManagement) { _%>
|
|
62
|
+
"@nestjs/schedule": "<%- nodeServerDependencies['@nestjs/schedule'] %>",
|
|
63
|
+
<%_ } _%>
|
|
64
|
+
<%_ if (!skipClient) { _%>
|
|
65
|
+
"@nestjs/serve-static": "<%- nodeServerDependencies['@nestjs/serve-static'] %>",
|
|
66
|
+
<%_ } _%>
|
|
67
|
+
"@nestjs/swagger": "<%- nodeServerDependencies['@nestjs/swagger'] %>",
|
|
68
|
+
"@nestjs/terminus": "<%- nodeServerDependencies['@nestjs/terminus'] %>",
|
|
69
|
+
"@nestjs/typeorm": "<%- nodeServerDependencies['@nestjs/typeorm'] %>",
|
|
70
|
+
<%_ if (authenticationType === 'jwt' || generateUserManagement) { _%>
|
|
71
|
+
"bcrypt": "<%- nodeServerDependencies['bcrypt'] %>",
|
|
72
|
+
<%_ } _%>
|
|
73
|
+
"class-transformer": "<%- nodeServerDependencies['class-transformer'] %>",
|
|
74
|
+
"class-validator": "<%- nodeServerDependencies['class-validator'] %>",
|
|
75
|
+
<%_ if (serviceDiscoveryEureka) { _%>
|
|
76
|
+
"cloud-config-client": "<%- nodeServerDependencies['cloud-config-client'] %>",
|
|
77
|
+
<%_ } _%>
|
|
78
|
+
<%_ if (serviceDiscoveryConsul) { _%>
|
|
79
|
+
"consul": "<%- nodeServerDependencies['consul'] %>",
|
|
80
|
+
<%_ } _%>
|
|
81
|
+
"dotenv": "<%- nodeServerDependencies['dotenv'] %>",
|
|
82
|
+
<%_ if (serviceDiscoveryEureka) { _%>
|
|
83
|
+
"@rocketsoftware/eureka-js-client": "<%- nodeServerDependencies['@rocketsoftware/eureka-js-client'] %>",
|
|
84
|
+
<%_ } _%>
|
|
85
|
+
<%_ if (generateUserManagement) { _%>
|
|
86
|
+
"handlebars": "<%- nodeServerDependencies['handlebars'] %>",
|
|
87
|
+
<%_ } _%>
|
|
88
|
+
"js-yaml": "<%- nodeServerDependencies['js-yaml'] %>",
|
|
89
|
+
<%_ if (authenticationType === 'oauth2') { _%>
|
|
90
|
+
"jwks-rsa": "<%- nodeServerDependencies['jwks-rsa'] %>",
|
|
91
|
+
"jwt-decode": "<%- nodeServerDependencies['jwt-decode'] %>",
|
|
92
|
+
<%_ } _%>
|
|
93
|
+
"passport": "<%- nodeServerDependencies['passport'] %>",
|
|
94
|
+
"passport-jwt": "<%- nodeServerDependencies['passport-jwt'] %>",
|
|
95
|
+
<%_ if (authenticationType === 'oauth2') {_%>
|
|
96
|
+
"passport-oauth2": "<%- nodeServerDependencies['passport-oauth2'] %>",
|
|
97
|
+
<%_ } _%>
|
|
98
|
+
"prom-client": "<%- nodeServerDependencies['prom-client'] %>",
|
|
99
|
+
"qs": "<%- nodeServerDependencies['qs'] %>",
|
|
100
|
+
"reflect-metadata": "<%- nodeServerDependencies['reflect-metadata'] %>",
|
|
101
|
+
"rxjs": "<%- nodeServerDependencies['rxjs'] %>",
|
|
102
|
+
"swagger-ui-express": "<%- nodeServerDependencies['swagger-ui-express'] %>",
|
|
103
|
+
"typeorm": "<%- nodeServerDependencies['typeorm'] %>"
|
|
104
|
+
},
|
|
105
|
+
"devDependencies": {
|
|
106
|
+
"@nestjs/cli": "<%- nodeServerDependencies['@nestjs/cli'] %>",
|
|
107
|
+
"@nestjs/schematics": "<%- nodeServerDependencies['@nestjs/schematics'] %>",
|
|
108
|
+
"@nestjs/testing": "<%- nodeServerDependencies['@nestjs/testing'] %>",
|
|
109
|
+
"@types/bcrypt": "<%- nodeServerDependencies['@types/bcrypt'] %>",
|
|
110
|
+
"@types/express": "<%- nodeServerDependencies['@types/express'] %>",
|
|
111
|
+
"@types/express-serve-static-core": "<%- nodeServerDependencies['@types/express-serve-static-core'] %>",
|
|
112
|
+
"@types/superagent": "<%- nodeServerDependencies['@types/superagent'] %>",
|
|
113
|
+
<%_ if (authenticationUsesCsrf) { _%>
|
|
114
|
+
"@types/express-session": "<%- nodeServerDependencies['@types/express-session'] %>",
|
|
115
|
+
<%_ } _%>
|
|
116
|
+
"@types/node": "<%- nodeServerDependencies['@types/node'] %>",
|
|
117
|
+
<%_ if (authenticationType === 'oauth2') { _%>
|
|
118
|
+
"@types/passport": "<%- nodeServerDependencies['@types/passport'] %>",
|
|
119
|
+
<%_ } _%>
|
|
120
|
+
"@types/passport-jwt": "<%- nodeServerDependencies['@types/passport-jwt'] %>",
|
|
121
|
+
<%_ if (authenticationType === 'oauth2') { _%>
|
|
122
|
+
"@types/passport-oauth2": "<%- nodeServerDependencies['@types/passport-oauth2'] %>",
|
|
123
|
+
<%_ } _%>
|
|
124
|
+
"@types/qs": "<%- nodeServerDependencies['@types/qs'] %>",
|
|
125
|
+
"@types/supertest": "<%- nodeServerDependencies['@types/supertest'] %>",
|
|
126
|
+
"@vitest/coverage-v8": "<%- nodeServerDependencies['@vitest/coverage-v8'] %>",
|
|
127
|
+
<%_ if (databaseType !== 'mongodb') { _%>
|
|
128
|
+
"<%- nodeDevDatabaseDriver %>": "<%- nodeServerDependencies[nodeDevDatabaseDriver] %>",
|
|
129
|
+
<%_ } _%>
|
|
130
|
+
"eslint": "<%- nodeServerDependencies['eslint'] %>",
|
|
131
|
+
"eslint-config-prettier": "<%- nodeServerDependencies['eslint-config-prettier'] %>",
|
|
132
|
+
"eslint-plugin-prettier": "<%- nodeServerDependencies['eslint-plugin-prettier'] %>",
|
|
133
|
+
<%_ if (databaseType === 'mongodb') { _%>
|
|
134
|
+
"mongodb-memory-server": "<%- nodeServerDependencies['mongodb-memory-server'] %>",
|
|
135
|
+
<%_ } _%>
|
|
136
|
+
"rimraf": "<%- nodeServerDependencies['rimraf'] %>",
|
|
137
|
+
"sonarqube-scanner": "<%- nodeServerDependencies['sonarqube-scanner'] %>",
|
|
138
|
+
"supertest": "<%- nodeServerDependencies['supertest'] %>",
|
|
139
|
+
"typescript": "<%- nodeServerDependencies['typescript'] %>",
|
|
140
|
+
"vite": "<%- nodeServerDependencies['vite'] %>",
|
|
141
|
+
"vitest": "<%- nodeServerDependencies['vitest'] %>"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# --- properties for sonar ---
|
|
2
|
+
sonar.projectKey=<%= baseName %>-nodejs
|
|
3
|
+
sonar.projectVersion=0.0.1
|
|
4
|
+
sonar.host.url=http://localhost:9001
|
|
5
|
+
sonar.sources=src
|
|
6
|
+
# The specs next to the code and the end-to-end tests of e2e are the tests, not sources.
|
|
7
|
+
sonar.exclusions=src/**/*.spec.ts
|
|
8
|
+
sonar.tests=src,e2e
|
|
9
|
+
sonar.test.inclusions=**/*.spec.ts,**/*.e2e-spec.ts
|
|
10
|
+
sonar.typescript.lcov.reportPaths=coverage/lcov.info
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { trustProxy } from './app.config.ts';
|
|
3
|
+
|
|
4
|
+
describe('trustProxy', () => {
|
|
5
|
+
it('trusts no proxy by default, like the forward-headers-strategy none of Spring Boot', () => {
|
|
6
|
+
expect(trustProxy('none')).toBe(false);
|
|
7
|
+
expect(trustProxy(undefined)).toBe(false);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('trusts the proxies of the local networks with native, like the internal proxies of the RemoteIpValve of Tomcat', () => {
|
|
11
|
+
expect(trustProxy('native')).toBe('loopback, linklocal, uniquelocal');
|
|
12
|
+
});
|
|
13
|
+
});
|