merge project/eslint-rules
This commit is contained in:
parent
18927d3074
commit
6be2af972c
@ -1,10 +1,11 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
// This tells ESLint to load the config from the package `eslint-config-custom`
|
|
||||||
extends: ["custom/common"],
|
|
||||||
settings: {
|
settings: {
|
||||||
next: {
|
next: {
|
||||||
rootDir: ["apps/*/"],
|
rootDir: ['apps/*/'],
|
||||||
|
},
|
||||||
|
react: {
|
||||||
|
version: 'detect',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
23
.vscode/settings.json
vendored
23
.vscode/settings.json
vendored
@ -8,5 +8,26 @@
|
|||||||
"**/Thumbs.db": true,
|
"**/Thumbs.db": true,
|
||||||
"**/node_modules": true
|
"**/node_modules": true
|
||||||
},
|
},
|
||||||
"explorerExclude.backup": {}
|
"explorerExclude.backup": null,
|
||||||
|
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll": true,
|
||||||
|
"source.fixAll.eslint": true,
|
||||||
|
"source.removeUnusedImports": true
|
||||||
|
},
|
||||||
|
"workbench.editor.labelFormat": "short",
|
||||||
|
"eslint.workingDirectories": [
|
||||||
|
{ "directory": "apps/web", "changeProcessCWD": true }
|
||||||
|
],
|
||||||
|
"eslint.validate": [
|
||||||
|
"javascript",
|
||||||
|
"javascriptreact",
|
||||||
|
"json",
|
||||||
|
"typescript",
|
||||||
|
"typescriptreact",
|
||||||
|
"yaml"
|
||||||
|
],
|
||||||
|
"eslint.lintTask.enable": true
|
||||||
}
|
}
|
||||||
4
apps/api/.env
Normal file
4
apps/api/.env
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
SECRET=secret
|
||||||
|
TOKEN_TTL=3600
|
||||||
|
CACHE_TTL=3600
|
||||||
|
COOKIE_TOKEN_NAME=token
|
||||||
@ -1,61 +1,12 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
parser: '@typescript-eslint/parser',
|
root: true,
|
||||||
|
extends: [
|
||||||
|
'@vchikalkin/eslint-config-awesome/typescript/config',
|
||||||
|
'@vchikalkin/eslint-config-awesome/typescript/rules',
|
||||||
|
],
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
project: 'tsconfig.json',
|
project: './tsconfig.json',
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
},
|
},
|
||||||
plugins: ['@typescript-eslint/eslint-plugin', 'prettier', 'unicorn'],
|
|
||||||
extends: [
|
|
||||||
'prettier',
|
|
||||||
'airbnb-base',
|
|
||||||
'airbnb-typescript/base',
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'plugin:unicorn/recommended',
|
|
||||||
],
|
|
||||||
root: true,
|
|
||||||
env: {
|
|
||||||
node: true,
|
|
||||||
jest: true,
|
|
||||||
},
|
|
||||||
ignorePatterns: ['.eslintrc.js'],
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/interface-name-prefix': 'off',
|
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
|
|
||||||
'linebreak-style': ['error', 'windows'],
|
|
||||||
'comma-dangle': 'off',
|
|
||||||
'@typescript-eslint/comma-dangle': ['off'],
|
|
||||||
|
|
||||||
'import/extensions': 'off',
|
|
||||||
'object-curly-newline': [
|
|
||||||
'warn',
|
|
||||||
{
|
|
||||||
ObjectExpression: 'always',
|
|
||||||
ObjectPattern: { multiline: true },
|
|
||||||
ImportDeclaration: 'never',
|
|
||||||
ExportDeclaration: { multiline: true, minProperties: 3 },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'lines-between-class-members': 'off',
|
|
||||||
'@typescript-eslint/lines-between-class-members': ['off'],
|
|
||||||
indent: 'off',
|
|
||||||
'@typescript-eslint/indent': ['off'],
|
|
||||||
|
|
||||||
'newline-before-return': 'warn',
|
|
||||||
'@typescript-eslint/consistent-type-imports': 'error',
|
|
||||||
// Airbnb prefers forEach
|
|
||||||
'unicorn/no-array-for-each': 'off',
|
|
||||||
'unicorn/prevent-abbreviations': 'off',
|
|
||||||
'unicorn/no-null': 'off',
|
|
||||||
'unicorn/prefer-node-protocol': 'off',
|
|
||||||
'unicorn/no-array-reduce': 'off',
|
|
||||||
'unicorn/prefer-module': 'off',
|
|
||||||
'unicorn/text-encoding-identifier-case': 'off',
|
|
||||||
'import/no-unresolved': 'warn',
|
|
||||||
'import/prefer-default-export': 'off',
|
|
||||||
'class-methods-use-this': 'off',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -18,7 +18,8 @@
|
|||||||
"test:watch": "jest --watch",
|
"test:watch": "jest --watch",
|
||||||
"test:cov": "jest --coverage",
|
"test:cov": "jest --coverage",
|
||||||
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
||||||
"test:e2e": "jest --config ./test/jest-e2e.json"
|
"test:e2e": "jest --config ./test/jest-e2e.json",
|
||||||
|
"lint:fix": "eslint --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/cookie": "^8.0.0",
|
"@fastify/cookie": "^8.0.0",
|
||||||
@ -46,15 +47,8 @@
|
|||||||
"@types/ldap-authentication": "^2.2.0",
|
"@types/ldap-authentication": "^2.2.0",
|
||||||
"@types/node": "^16.0.0",
|
"@types/node": "^16.0.0",
|
||||||
"@types/supertest": "^2.0.11",
|
"@types/supertest": "^2.0.11",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
"@vchikalkin/eslint-config-awesome": "^1.1.1",
|
||||||
"@typescript-eslint/parser": "^5.0.0",
|
"eslint": "^8.46.0",
|
||||||
"eslint": "^8.28.0",
|
|
||||||
"eslint-config-airbnb-base": "^15.0.0",
|
|
||||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
|
||||||
"eslint-config-prettier": "^8.3.0",
|
|
||||||
"eslint-plugin-import": "^2.26.0",
|
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
|
||||||
"eslint-plugin-unicorn": "^43.0.2",
|
|
||||||
"jest": "28.1.2",
|
"jest": "28.1.2",
|
||||||
"prettier": "^2.3.2",
|
"prettier": "^2.3.2",
|
||||||
"source-map-support": "^0.5.20",
|
"source-map-support": "^0.5.20",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import type { TestingModule } from '@nestjs/testing';
|
|
||||||
import { Test } from '@nestjs/testing';
|
|
||||||
import { AppController } from './app.controller';
|
import { AppController } from './app.controller';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
|
import type { TestingModule } from '@nestjs/testing';
|
||||||
|
import { Test } from '@nestjs/testing';
|
||||||
|
|
||||||
describe('AppController', () => {
|
describe('AppController', () => {
|
||||||
let appController: AppController;
|
let appController: AppController;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Controller, Get } from '@nestjs/common';
|
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
|
import { Controller, Get } from '@nestjs/common';
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
export class AppController {
|
export class AppController {
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
import { Global, Module } from '@nestjs/common';
|
|
||||||
import { ConfigModule } from '@nestjs/config';
|
|
||||||
import { JwtModule } from '@nestjs/jwt';
|
|
||||||
import { AppController } from './app.controller';
|
import { AppController } from './app.controller';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
import { AuthModule } from './auth/auth.module';
|
import { AuthModule } from './auth/auth.module';
|
||||||
import { UsersModule } from './users/users.module';
|
|
||||||
import { LdapModule } from './ldap/ldap.module';
|
import { LdapModule } from './ldap/ldap.module';
|
||||||
|
import { UsersModule } from './users/users.module';
|
||||||
|
import { Global, Module } from '@nestjs/common';
|
||||||
|
import { ConfigModule } from '@nestjs/config';
|
||||||
|
import { JwtModule } from '@nestjs/jwt';
|
||||||
|
|
||||||
@Global()
|
@Global()
|
||||||
@Module({
|
@Module({
|
||||||
|
controllers: [AppController],
|
||||||
|
exports: [JwtModule],
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot({
|
ConfigModule.forRoot({
|
||||||
isGlobal: true,
|
isGlobal: true,
|
||||||
@ -23,8 +25,7 @@ import { LdapModule } from './ldap/ldap.module';
|
|||||||
UsersModule,
|
UsersModule,
|
||||||
LdapModule,
|
LdapModule,
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
|
||||||
providers: [AppService],
|
providers: [AppService],
|
||||||
exports: [JwtModule],
|
|
||||||
})
|
})
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import type { TestingModule } from '@nestjs/testing';
|
|
||||||
import { Test } from '@nestjs/testing';
|
|
||||||
import { AuthController } from './auth.controller';
|
import { AuthController } from './auth.controller';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
|
import type { TestingModule } from '@nestjs/testing';
|
||||||
|
import { Test } from '@nestjs/testing';
|
||||||
|
|
||||||
describe('AuthController', () => {
|
describe('AuthController', () => {
|
||||||
let controller: AuthController;
|
let controller: AuthController;
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
/* eslint-disable class-methods-use-this */
|
/* eslint-disable class-methods-use-this */
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import { Body, Controller, Get, HttpException, HttpStatus, Post, Req, Res } from '@nestjs/common';
|
|
||||||
import { FastifyReply, FastifyRequest } from 'fastify';
|
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { COOKIE_TOKEN_NAME } from './lib/constants';
|
import { COOKIE_TOKEN_NAME } from './lib/constants';
|
||||||
import { Credentials } from './types/request';
|
import { Credentials } from './types/request';
|
||||||
|
import { Body, Controller, Get, HttpException, HttpStatus, Post, Req, Res } from '@nestjs/common';
|
||||||
|
import { FastifyReply, FastifyRequest } from 'fastify';
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
import { Module } from '@nestjs/common';
|
|
||||||
import { LdapModule } from '../ldap/ldap.module';
|
import { LdapModule } from '../ldap/ldap.module';
|
||||||
import { UsersModule } from '../users/users.module';
|
import { UsersModule } from '../users/users.module';
|
||||||
import { AuthController } from './auth.controller';
|
import { AuthController } from './auth.controller';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [UsersModule, LdapModule],
|
|
||||||
controllers: [AuthController],
|
controllers: [AuthController],
|
||||||
|
imports: [UsersModule, LdapModule],
|
||||||
providers: [AuthService],
|
providers: [AuthService],
|
||||||
})
|
})
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
||||||
export class AuthModule {}
|
export class AuthModule {}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
|
import { AuthService } from './auth.service';
|
||||||
import type { TestingModule } from '@nestjs/testing';
|
import type { TestingModule } from '@nestjs/testing';
|
||||||
import { Test } from '@nestjs/testing';
|
import { Test } from '@nestjs/testing';
|
||||||
import { AuthService } from './auth.service';
|
|
||||||
|
|
||||||
describe('AuthService', () => {
|
describe('AuthService', () => {
|
||||||
let service: AuthService;
|
let service: AuthService;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import { JwtService } from '@nestjs/jwt';
|
|
||||||
import { LdapService } from '../ldap/ldap.service';
|
import { LdapService } from '../ldap/ldap.service';
|
||||||
import { UsersCache } from '../users/users.cache';
|
import { UsersCache } from '../users/users.cache';
|
||||||
import type { DecodedToken, TokenPayload } from './types/jwt';
|
import type { DecodedToken, TokenPayload } from './types/jwt';
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { JwtService } from '@nestjs/jwt';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
@ -19,8 +19,8 @@ export class AuthService {
|
|||||||
await this.usersCache.addUser(username, user);
|
await this.usersCache.addUser(username, user);
|
||||||
|
|
||||||
const payload: TokenPayload = {
|
const payload: TokenPayload = {
|
||||||
username,
|
|
||||||
domain: process.env.LDAP_DOMAIN,
|
domain: process.env.LDAP_DOMAIN,
|
||||||
|
username,
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.jwtService.sign(payload);
|
return this.jwtService.sign(payload);
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import { Module } from '@nestjs/common';
|
|
||||||
import { LdapService } from './ldap.service';
|
import { LdapService } from './ldap.service';
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
providers: [LdapService],
|
|
||||||
exports: [LdapService],
|
exports: [LdapService],
|
||||||
|
providers: [LdapService],
|
||||||
})
|
})
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
||||||
export class LdapModule {}
|
export class LdapModule {}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
|
import { LdapService } from './ldap.service';
|
||||||
import type { TestingModule } from '@nestjs/testing';
|
import type { TestingModule } from '@nestjs/testing';
|
||||||
import { Test } from '@nestjs/testing';
|
import { Test } from '@nestjs/testing';
|
||||||
import { LdapService } from './ldap.service';
|
|
||||||
|
|
||||||
describe('LdapService', () => {
|
describe('LdapService', () => {
|
||||||
let service: LdapService;
|
let service: LdapService;
|
||||||
|
|||||||
@ -1,22 +1,22 @@
|
|||||||
|
import type { User } from '../types/user';
|
||||||
|
import type { LdapUser } from './types/user';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import type { AuthenticationOptions } from 'ldap-authentication';
|
import type { AuthenticationOptions } from 'ldap-authentication';
|
||||||
import { authenticate } from 'ldap-authentication';
|
import { authenticate } from 'ldap-authentication';
|
||||||
import type { User } from '../types/user';
|
|
||||||
import type { LdapUser } from './types/user';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LdapService {
|
export class LdapService {
|
||||||
async authenticate(login: string, password?: string) {
|
async authenticate(login: string, password?: string) {
|
||||||
const options: AuthenticationOptions = {
|
const options: AuthenticationOptions = {
|
||||||
|
adminDn: process.env.LDAP_BIND_DN,
|
||||||
|
adminPassword: process.env.LDAP_BIND_CREDENTIALS,
|
||||||
ldapOpts: {
|
ldapOpts: {
|
||||||
url: process.env.LDAP_URL,
|
url: process.env.LDAP_URL,
|
||||||
},
|
},
|
||||||
adminDn: process.env.LDAP_BIND_DN,
|
|
||||||
adminPassword: process.env.LDAP_BIND_CREDENTIALS,
|
|
||||||
userSearchBase: process.env.LDAP_BASE,
|
|
||||||
usernameAttribute: process.env.LDAP_ATTRIBUTE,
|
|
||||||
username: login,
|
|
||||||
userPassword: password,
|
userPassword: password,
|
||||||
|
userSearchBase: process.env.LDAP_BASE,
|
||||||
|
username: login,
|
||||||
|
usernameAttribute: process.env.LDAP_ATTRIBUTE,
|
||||||
verifyUserExists: password === undefined,
|
verifyUserExists: password === undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,13 +29,13 @@ export class LdapService {
|
|||||||
}: LdapUser = await authenticate(options);
|
}: LdapUser = await authenticate(options);
|
||||||
|
|
||||||
const user: User = {
|
const user: User = {
|
||||||
username,
|
|
||||||
domain: process.env.LDAP_DOMAIN,
|
|
||||||
displayName,
|
|
||||||
department,
|
department,
|
||||||
position: title,
|
displayName,
|
||||||
mail,
|
domain: process.env.LDAP_DOMAIN,
|
||||||
domainName: `${process.env.LDAP_DOMAIN}\\${username}`,
|
domainName: `${process.env.LDAP_DOMAIN}\\${username}`,
|
||||||
|
mail,
|
||||||
|
position: title,
|
||||||
|
username,
|
||||||
};
|
};
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
|
|||||||
@ -1,63 +1,63 @@
|
|||||||
export type LdapUser = {
|
export type LdapUser = {
|
||||||
dn: string;
|
accountExpires: string;
|
||||||
controls: any[];
|
|
||||||
objectClass: string[];
|
|
||||||
cn: string;
|
|
||||||
sn: string;
|
|
||||||
c: string;
|
|
||||||
title: string;
|
|
||||||
physicalDeliveryOfficeName: string;
|
|
||||||
givenName: string;
|
|
||||||
distinguishedName: string;
|
|
||||||
instanceType: string;
|
|
||||||
whenCreated: string;
|
|
||||||
whenChanged: string;
|
|
||||||
displayName: string;
|
|
||||||
uSNCreated: string;
|
|
||||||
memberOf: string[];
|
|
||||||
uSNChanged: string;
|
|
||||||
co: string;
|
|
||||||
department: string;
|
|
||||||
proxyAddresses: string[];
|
|
||||||
name: string;
|
|
||||||
objectGUID: string;
|
|
||||||
userAccountControl: string;
|
|
||||||
badPwdCount: string;
|
|
||||||
codePage: string;
|
|
||||||
countryCode: string;
|
|
||||||
employeeID: string;
|
|
||||||
badPasswordTime: string;
|
badPasswordTime: string;
|
||||||
|
badPwdCount: string;
|
||||||
|
c: string;
|
||||||
|
cn: string;
|
||||||
|
co: string;
|
||||||
|
codePage: string;
|
||||||
|
controls: unknown[];
|
||||||
|
countryCode: string;
|
||||||
|
dSCorePropagationData: string[];
|
||||||
|
department: string;
|
||||||
|
displayName: string;
|
||||||
|
distinguishedName: string;
|
||||||
|
dn: string;
|
||||||
|
employeeID: string;
|
||||||
|
extensionAttribute1: string;
|
||||||
|
extensionAttribute13: string;
|
||||||
|
extensionAttribute2: string;
|
||||||
|
givenName: string;
|
||||||
|
instanceType: string;
|
||||||
lastLogoff: string;
|
lastLogoff: string;
|
||||||
lastLogon: string;
|
lastLogon: string;
|
||||||
pwdLastSet: string;
|
lastLogonTimestamp: string;
|
||||||
primaryGroupID: string;
|
legacyExchangeDN: string;
|
||||||
objectSid: string;
|
lockoutTime: string;
|
||||||
accountExpires: string;
|
|
||||||
logonCount: string;
|
logonCount: string;
|
||||||
|
'mS-DS-ConsistencyGuid': string;
|
||||||
|
mail: string;
|
||||||
|
mailNickname: string;
|
||||||
|
memberOf: string[];
|
||||||
|
middleName: string;
|
||||||
|
'msDS-KeyCredentialLink': string;
|
||||||
|
msExchMailboxGuid: string;
|
||||||
|
msExchPoliciesIncluded: string[];
|
||||||
|
msExchRecipientDisplayType: string;
|
||||||
|
msExchRecipientTypeDetails: string;
|
||||||
|
msExchRemoteRecipientType: string;
|
||||||
|
msExchUMDtmfMap: string[];
|
||||||
|
msExchVersion: string;
|
||||||
|
name: string;
|
||||||
|
objectCategory: string;
|
||||||
|
objectClass: string[];
|
||||||
|
objectGUID: string;
|
||||||
|
objectSid: string;
|
||||||
|
physicalDeliveryOfficeName: string;
|
||||||
|
preferredLanguage: string;
|
||||||
|
primaryGroupID: string;
|
||||||
|
proxyAddresses: string[];
|
||||||
|
pwdLastSet: string;
|
||||||
sAMAccountName: string;
|
sAMAccountName: string;
|
||||||
sAMAccountType: string;
|
sAMAccountType: string;
|
||||||
showInAddressBook: string[];
|
showInAddressBook: string[];
|
||||||
legacyExchangeDN: string;
|
sn: string;
|
||||||
userPrincipalName: string;
|
|
||||||
lockoutTime: string;
|
|
||||||
objectCategory: string;
|
|
||||||
dSCorePropagationData: string[];
|
|
||||||
'mS-DS-ConsistencyGuid': string;
|
|
||||||
lastLogonTimestamp: string;
|
|
||||||
'msDS-KeyCredentialLink': string;
|
|
||||||
mail: string;
|
|
||||||
middleName: string;
|
|
||||||
preferredLanguage: string;
|
|
||||||
extensionAttribute2: string;
|
|
||||||
msExchVersion: string;
|
|
||||||
msExchRecipientDisplayType: string;
|
|
||||||
msExchRecipientTypeDetails: string;
|
|
||||||
extensionAttribute1: string;
|
|
||||||
msExchMailboxGuid: string;
|
|
||||||
targetAddress: string;
|
targetAddress: string;
|
||||||
msExchPoliciesIncluded: string[];
|
title: string;
|
||||||
extensionAttribute13: string;
|
uSNChanged: string;
|
||||||
mailNickname: string;
|
uSNCreated: string;
|
||||||
msExchRemoteRecipientType: string;
|
userAccountControl: string;
|
||||||
msExchUMDtmfMap: string[];
|
userPrincipalName: string;
|
||||||
|
whenChanged: string;
|
||||||
|
whenCreated: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
/* eslint-disable unicorn/prefer-top-level-await */
|
/* eslint-disable unicorn/prefer-top-level-await */
|
||||||
import fastifyCookie from '@fastify/cookie';
|
import { AppModule } from './app.module';
|
||||||
|
import { fastifyCookie } from '@fastify/cookie';
|
||||||
import { NestFactory } from '@nestjs/core';
|
import { NestFactory } from '@nestjs/core';
|
||||||
import type { NestFastifyApplication } from '@nestjs/platform-fastify';
|
import type { NestFastifyApplication } from '@nestjs/platform-fastify';
|
||||||
import { FastifyAdapter } from '@nestjs/platform-fastify';
|
import { FastifyAdapter } from '@nestjs/platform-fastify';
|
||||||
import { AppModule } from './app.module';
|
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create<NestFastifyApplication>(
|
const app = await NestFactory.create<NestFastifyApplication>(
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
export type User = {
|
export type User = {
|
||||||
displayName: string;
|
|
||||||
username: string;
|
|
||||||
department: string;
|
department: string;
|
||||||
position: string;
|
displayName: string;
|
||||||
mail: string;
|
|
||||||
domain: string;
|
domain: string;
|
||||||
domainName: string;
|
domainName: string;
|
||||||
|
mail: string;
|
||||||
|
position: string;
|
||||||
|
username: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
|
import type { User } from '../types/user';
|
||||||
import { CACHE_MANAGER, Inject, Injectable } from '@nestjs/common';
|
import { CACHE_MANAGER, Inject, Injectable } from '@nestjs/common';
|
||||||
import { Cache } from 'cache-manager';
|
import { Cache } from 'cache-manager';
|
||||||
import type { User } from '../types/user';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UsersCache {
|
export class UsersCache {
|
||||||
constructor(@Inject(CACHE_MANAGER) private readonly cacheManager: Cache) {}
|
constructor(@Inject(CACHE_MANAGER) private readonly cacheManager: Cache) {}
|
||||||
async getUser(username: string) {
|
async getUser(username: string) {
|
||||||
const user = (await this.cacheManager.get(username)) as User;
|
return (await this.cacheManager.get(username)) as User;
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async addUser(username: string, user: User) {
|
async addUser(username: string, user: User) {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import type { TestingModule } from '@nestjs/testing';
|
|
||||||
import { Test } from '@nestjs/testing';
|
|
||||||
import { UsersController } from './users.controller';
|
import { UsersController } from './users.controller';
|
||||||
import { UsersService } from './users.service';
|
import { UsersService } from './users.service';
|
||||||
|
import type { TestingModule } from '@nestjs/testing';
|
||||||
|
import { Test } from '@nestjs/testing';
|
||||||
|
|
||||||
describe('UsersController', () => {
|
describe('UsersController', () => {
|
||||||
let controller: UsersController;
|
let controller: UsersController;
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
/* eslint-disable class-methods-use-this */
|
/* eslint-disable class-methods-use-this */
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import { Controller, Get, Req, Res } from '@nestjs/common';
|
|
||||||
import { FastifyReply, FastifyRequest } from 'fastify';
|
|
||||||
import { COOKIE_TOKEN_NAME } from '../auth/lib/constants';
|
import { COOKIE_TOKEN_NAME } from '../auth/lib/constants';
|
||||||
import { UsersService } from './users.service';
|
import { UsersService } from './users.service';
|
||||||
|
import { Controller, Get, Req, Res } from '@nestjs/common';
|
||||||
|
import { FastifyReply, FastifyRequest } from 'fastify';
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
export class UsersController {
|
export class UsersController {
|
||||||
|
|||||||
@ -1,23 +1,24 @@
|
|||||||
import { CacheModule, Module } from '@nestjs/common';
|
|
||||||
import * as redisStore from 'cache-manager-ioredis';
|
|
||||||
import type { RedisOptions } from 'ioredis';
|
|
||||||
import { LdapModule } from '../ldap/ldap.module';
|
import { LdapModule } from '../ldap/ldap.module';
|
||||||
import { UsersCache } from './users.cache';
|
import { UsersCache } from './users.cache';
|
||||||
import { UsersController } from './users.controller';
|
import { UsersController } from './users.controller';
|
||||||
import { UsersService } from './users.service';
|
import { UsersService } from './users.service';
|
||||||
|
import { CacheModule, Module } from '@nestjs/common';
|
||||||
|
import * as redisStore from 'cache-manager-ioredis';
|
||||||
|
import type { RedisOptions } from 'ioredis';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
controllers: [UsersController],
|
||||||
|
exports: [UsersCache],
|
||||||
imports: [
|
imports: [
|
||||||
CacheModule.register<RedisOptions>({
|
CacheModule.register<RedisOptions>({
|
||||||
store: redisStore,
|
|
||||||
host: process.env.REDIS_HOST,
|
host: process.env.REDIS_HOST,
|
||||||
port: Number.parseInt(process.env.REDIS_PORT, 10) || 6379,
|
port: Number.parseInt(process.env.REDIS_PORT, 10) || 6379,
|
||||||
|
store: redisStore,
|
||||||
ttl: Number.parseInt(process.env.CACHE_TTL, 10),
|
ttl: Number.parseInt(process.env.CACHE_TTL, 10),
|
||||||
}),
|
}),
|
||||||
LdapModule,
|
LdapModule,
|
||||||
],
|
],
|
||||||
controllers: [UsersController],
|
|
||||||
providers: [UsersService, UsersCache],
|
providers: [UsersService, UsersCache],
|
||||||
exports: [UsersCache],
|
|
||||||
})
|
})
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
||||||
export class UsersModule {}
|
export class UsersModule {}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
|
import { UsersService } from './users.service';
|
||||||
import type { TestingModule } from '@nestjs/testing';
|
import type { TestingModule } from '@nestjs/testing';
|
||||||
import { Test } from '@nestjs/testing';
|
import { Test } from '@nestjs/testing';
|
||||||
import { UsersService } from './users.service';
|
|
||||||
|
|
||||||
describe('UsersService', () => {
|
describe('UsersService', () => {
|
||||||
let service: UsersService;
|
let service: UsersService;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
|
import type { DecodedToken } from '../auth/types/jwt';
|
||||||
|
import { LdapService } from '../ldap/ldap.service';
|
||||||
|
import { UsersCache } from './users.cache';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { JwtService } from '@nestjs/jwt';
|
import { JwtService } from '@nestjs/jwt';
|
||||||
import { LdapService } from '../ldap/ldap.service';
|
|
||||||
import type { DecodedToken } from '../auth/types/jwt';
|
|
||||||
import { UsersCache } from './users.cache';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UsersService {
|
export class UsersService {
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
|
import { AppModule } from '../src/app.module';
|
||||||
|
import type { INestApplication } from '@nestjs/common';
|
||||||
import type { TestingModule } from '@nestjs/testing';
|
import type { TestingModule } from '@nestjs/testing';
|
||||||
import { Test } from '@nestjs/testing';
|
import { Test } from '@nestjs/testing';
|
||||||
import type { INestApplication } from '@nestjs/common';
|
|
||||||
import * as request from 'supertest';
|
import * as request from 'supertest';
|
||||||
import { AppModule } from '../src/app.module';
|
|
||||||
|
|
||||||
describe('AppController (e2e)', () => {
|
describe('AppController (e2e)', () => {
|
||||||
let app: INestApplication;
|
let app: INestApplication;
|
||||||
@ -16,8 +16,5 @@ describe('AppController (e2e)', () => {
|
|||||||
await app.init();
|
await app.init();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('/ (GET)', () => request(app.getHttpServer())
|
it('/ (GET)', () => request(app.getHttpServer()).get('/').expect(200).expect('Hello World!'));
|
||||||
.get('/')
|
|
||||||
.expect(200)
|
|
||||||
.expect('Hello World!'));
|
|
||||||
});
|
});
|
||||||
|
|||||||
10
apps/web/.eslintrc.js
Normal file
10
apps/web/.eslintrc.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module.exports = {
|
||||||
|
extends: [
|
||||||
|
'@vchikalkin/eslint-config-awesome/next-typescript/config',
|
||||||
|
'@vchikalkin/eslint-config-awesome/next-typescript/rules',
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
project: './tsconfig.json',
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "next/core-web-vitals"
|
|
||||||
}
|
|
||||||
@ -1,18 +1,18 @@
|
|||||||
import Input from 'elements/Input';
|
|
||||||
import Button from 'elements/Button';
|
|
||||||
import styles from './Form.module.scss';
|
import styles from './Form.module.scss';
|
||||||
import { H3 } from 'elements/H';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import Error from 'elements/Error';
|
|
||||||
import getConfig from 'next/config';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import Button from 'elements/Button';
|
||||||
|
import Error from 'elements/Error';
|
||||||
|
import { H3 } from 'elements/H';
|
||||||
|
import Input from 'elements/Input';
|
||||||
|
import getConfig from 'next/config';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
const { publicRuntimeConfig: config } = getConfig();
|
const { publicRuntimeConfig: config } = getConfig();
|
||||||
|
|
||||||
export default function Form() {
|
export default function Form() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [hasError, setError] = useState(false);
|
const [hasError, setHasError] = useState(false);
|
||||||
const error = hasError ? <Error>Неверный логин или пароль</Error> : null;
|
const error = hasError ? <Error>Неверный логин или пароль</Error> : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -31,7 +31,7 @@ export default function Form() {
|
|||||||
router.reload();
|
router.reload();
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
setError(true);
|
setHasError(true);
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Form from './Form';
|
import Form from './Form';
|
||||||
import Logo from 'elements/Logo';
|
|
||||||
import styles from './Login.module.scss';
|
import styles from './Login.module.scss';
|
||||||
|
import Logo from 'elements/Logo';
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react/button-has-type */
|
||||||
import styles from './Button.module.css';
|
import styles from './Button.module.css';
|
||||||
|
|
||||||
type ButtonProps = JSX.IntrinsicElements['button'];
|
type ButtonProps = JSX.IntrinsicElements['button'];
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import logo from 'public/assets/images/logo-primary.svg';
|
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
|
import logo from 'public/assets/images/logo-primary.svg';
|
||||||
|
|
||||||
export default function Logo() {
|
export default function Logo() {
|
||||||
return <Image src={logo} alt="logo" width={154} />;
|
return <Image src={logo} alt="logo" width={154} />;
|
||||||
|
|||||||
@ -6,7 +6,8 @@
|
|||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint"
|
"lint": "next lint",
|
||||||
|
"lint:fix": "next lint -- --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/montserrat": "^4.5.13",
|
"@fontsource/montserrat": "^4.5.13",
|
||||||
@ -14,13 +15,15 @@
|
|||||||
"@types/react": "18.0.25",
|
"@types/react": "18.0.25",
|
||||||
"@types/react-dom": "18.0.9",
|
"@types/react-dom": "18.0.9",
|
||||||
"axios": "^1.2.1",
|
"axios": "^1.2.1",
|
||||||
"eslint": "8.28.0",
|
|
||||||
"eslint-config-next": "13.0.5",
|
|
||||||
"next": "13.0.5",
|
"next": "13.0.5",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"sass": "^1.56.1",
|
"sass": "^1.56.1",
|
||||||
"typescript": "4.9.3"
|
"typescript": "4.9.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vchikalkin/eslint-config-awesome": "^1.1.1",
|
||||||
|
"eslint": "^8.46.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import type { AppProps } from 'next/app';
|
/* eslint-disable react/no-unknown-property */
|
||||||
import 'normalize.css';
|
import 'normalize.css';
|
||||||
import Head from 'next/head';
|
|
||||||
import '@fontsource/montserrat/400.css';
|
import '@fontsource/montserrat/400.css';
|
||||||
import '@fontsource/montserrat/600.css';
|
import '@fontsource/montserrat/600.css';
|
||||||
import '@fontsource/montserrat/700.css';
|
import '@fontsource/montserrat/700.css';
|
||||||
|
import type { AppProps } from 'next/app';
|
||||||
|
import Head from 'next/head';
|
||||||
|
|
||||||
export default function App({ Component, pageProps }: AppProps) {
|
export default function App({ Component, pageProps }: AppProps) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Head from 'next/head';
|
|
||||||
import Login from 'components/Login';
|
import Login from 'components/Login';
|
||||||
import getConfig from 'next/config';
|
import getConfig from 'next/config';
|
||||||
|
import Head from 'next/head';
|
||||||
|
|
||||||
const { publicRuntimeConfig: config } = getConfig();
|
const { publicRuntimeConfig: config } = getConfig();
|
||||||
|
|
||||||
|
|||||||
@ -3,13 +3,14 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"apps/*",
|
"apps/*"
|
||||||
"packages/*"
|
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "turbo run build",
|
"build": "turbo run build",
|
||||||
"dev": "turbo run dev --parallel",
|
"dev": "turbo run dev --parallel",
|
||||||
"lint": "turbo run lint",
|
"lint": "turbo run lint",
|
||||||
|
"lint:fix": "turbo run lint:fix",
|
||||||
|
"clean": "turbo run clean",
|
||||||
"format": "prettier --write \"**/*.{ts,tsx,md}\""
|
"format": "prettier --write \"**/*.{ts,tsx,md}\""
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
14
turbo.json
14
turbo.json
@ -2,13 +2,23 @@
|
|||||||
"$schema": "https://turbo.build/schema.json",
|
"$schema": "https://turbo.build/schema.json",
|
||||||
"pipeline": {
|
"pipeline": {
|
||||||
"build": {
|
"build": {
|
||||||
"dependsOn": ["^build"],
|
"outputs": ["dist/**", ".next/**", "public/dist/**"],
|
||||||
"outputs": ["dist/**", ".next/**"]
|
"dependsOn": ["^build"]
|
||||||
},
|
},
|
||||||
"lint": {
|
"lint": {
|
||||||
|
"dependsOn": ["^build"],
|
||||||
|
"cache": false,
|
||||||
|
"outputs": []
|
||||||
|
},
|
||||||
|
"lint:fix": {
|
||||||
|
"dependsOn": ["^build"],
|
||||||
"outputs": []
|
"outputs": []
|
||||||
},
|
},
|
||||||
"dev": {
|
"dev": {
|
||||||
|
"cache": false,
|
||||||
|
"persistent": true
|
||||||
|
},
|
||||||
|
"clean": {
|
||||||
"cache": false
|
"cache": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user