Skip to content

Commit 3555828

Browse files
author
Nevo David
committed
feat: first commit
1 parent 74bf5a4 commit 3555828

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+19623
-1807
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

.eslintrc.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"root": true,
3+
"ignorePatterns": ["**/*"],
4+
"plugins": ["@nx"],
5+
"overrides": [
6+
{
7+
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
8+
"rules": {
9+
"@nx/enforce-module-boundaries": [
10+
"error",
11+
{
12+
"enforceBuildableLibDependency": true,
13+
"allow": [],
14+
"depConstraints": [
15+
{
16+
"sourceTag": "*",
17+
"onlyDependOnLibsWithTags": ["*"]
18+
}
19+
]
20+
}
21+
]
22+
}
23+
},
24+
{
25+
"files": ["*.ts", "*.tsx"],
26+
"extends": ["plugin:@nx/typescript"],
27+
"rules": {}
28+
},
29+
{
30+
"files": ["*.js", "*.jsx"],
31+
"extends": ["plugin:@nx/javascript"],
32+
"rules": {}
33+
}
34+
]
35+
}

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
dist
55
tmp
66
/out-tsc
7-
7+
.env
88
# dependencies
99
node_modules
1010

@@ -39,3 +39,6 @@ testem.log
3939
Thumbs.db
4040

4141
.nx/cache
42+
43+
# Next.js
44+
.next

.prettierignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Add files here to ignore them from prettier formatting
2+
/dist
3+
/coverage
4+
/.nx/cache

.prettierrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"singleQuote": true
3+
}

.vscode/extensions.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{
22
"recommendations": [
3-
4-
"nrwl.angular-console"
3+
"nrwl.angular-console",
4+
"esbenp.prettier-vscode",
5+
"dbaeumer.vscode-eslint",
6+
"firsttris.vscode-jest-runner"
57
]
68
}

apps/backend/.eslintrc.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"extends": ["../../.eslintrc.json"],
3+
"ignorePatterns": ["!**/*"],
4+
"overrides": [
5+
{
6+
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7+
"rules": {}
8+
},
9+
{
10+
"files": ["*.ts", "*.tsx"],
11+
"rules": {}
12+
},
13+
{
14+
"files": ["*.js", "*.jsx"],
15+
"rules": {}
16+
}
17+
]
18+
}

apps/backend/jest.config.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* eslint-disable */
2+
export default {
3+
displayName: 'backend',
4+
preset: '../../jest.preset.js',
5+
testEnvironment: 'node',
6+
transform: {
7+
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
8+
},
9+
moduleFileExtensions: ['ts', 'js', 'html'],
10+
coverageDirectory: '../../coverage/apps/backend',
11+
};

apps/backend/project.json

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"name": "backend",
3+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
4+
"sourceRoot": "apps/backend/src",
5+
"projectType": "application",
6+
"targets": {
7+
"build": {
8+
"executor": "@nx/webpack:webpack",
9+
"outputs": ["{options.outputPath}"],
10+
"defaultConfiguration": "production",
11+
"options": {
12+
"target": "node",
13+
"compiler": "tsc",
14+
"outputPath": "dist/apps/backend",
15+
"main": "apps/backend/src/main.ts",
16+
"tsConfig": "apps/backend/tsconfig.app.json",
17+
"assets": ["apps/backend/src/assets"],
18+
"webpackConfig": "apps/backend/webpack.config.js"
19+
},
20+
"configurations": {
21+
"development": {},
22+
"production": {}
23+
}
24+
},
25+
"serve": {
26+
"executor": "@nx/js:node",
27+
"defaultConfiguration": "development",
28+
"options": {
29+
"buildTarget": "backend:build"
30+
},
31+
"configurations": {
32+
"development": {
33+
"buildTarget": "backend:build:development"
34+
},
35+
"production": {
36+
"buildTarget": "backend:build:production"
37+
}
38+
}
39+
},
40+
"lint": {
41+
"executor": "@nx/eslint:lint",
42+
"outputs": ["{options.outputFile}"]
43+
},
44+
"test": {
45+
"executor": "@nx/jest:jest",
46+
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
47+
"options": {
48+
"jestConfig": "apps/backend/jest.config.ts"
49+
}
50+
}
51+
},
52+
"tags": []
53+
}

apps/backend/src/api/api.module.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Module } from '@nestjs/common';
2+
import {AuthController} from "@gitroom/backend/api/routes/auth.controller";
3+
import {AuthService} from "@gitroom/backend/services/auth/auth.service";
4+
@Module({
5+
imports: [],
6+
controllers: [AuthController],
7+
providers: [AuthService],
8+
})
9+
export class ApiModule {}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {Body, Controller, Post} from '@nestjs/common';
2+
import {CreateOrgUserDto} from "@gitroom/nestjs-libraries/dtos/auth/create.org.user.dto";
3+
import {LoginUserDto} from "@gitroom/nestjs-libraries/dtos/auth/login.user.dto";
4+
import {AuthService} from "@gitroom/backend/services/auth/auth.service";
5+
6+
@Controller()
7+
export class AuthController {
8+
constructor(
9+
private _authService: AuthService
10+
) {
11+
}
12+
@Post('/register')
13+
register(
14+
@Body() body: CreateOrgUserDto
15+
) {
16+
return this._authService.routeAuth(body.provider, body);
17+
}
18+
19+
@Post('/login')
20+
login(
21+
@Body() body: LoginUserDto
22+
) {
23+
return this._authService.routeAuth(body.provider, body);
24+
}
25+
}

apps/backend/src/app.module.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Module } from '@nestjs/common';
2+
3+
import {DatabaseModule} from "@gitroom/nestjs-libraries/database/prisma/database.module";
4+
import {RedisModule} from "@gitroom/nestjs-libraries/redis/redis.module";
5+
import {AuthService} from "@gitroom/backend/services/auth/auth.service";
6+
import {ApiModule} from "@gitroom/backend/api/api.module";
7+
8+
@Module({
9+
imports: [DatabaseModule, RedisModule, ApiModule],
10+
controllers: [],
11+
providers: [AuthService],
12+
get exports() {
13+
return [...this.imports, ...this.providers];
14+
}
15+
})
16+
export class AppModule {}

apps/backend/src/assets/.gitkeep

Whitespace-only changes.

apps/backend/src/main.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* This is not a production server yet!
3+
* This is only a minimal backend to get started.
4+
*/
5+
6+
import {Logger, ValidationPipe} from '@nestjs/common';
7+
import { NestFactory } from '@nestjs/core';
8+
import { AppModule } from './app.module';
9+
10+
async function bootstrap() {
11+
const app = await NestFactory.create(AppModule);
12+
app.useGlobalPipes(new ValidationPipe({
13+
transform: true,
14+
}));
15+
const port = process.env.PORT || 3000;
16+
await app.listen(port);
17+
Logger.log(
18+
`🚀 Application is running on: http://localhost:${port}`
19+
);
20+
}
21+
22+
bootstrap();
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import {Injectable} from "@nestjs/common";
2+
import {Provider, User} from '@prisma/client';
3+
import {CreateOrgUserDto} from "@gitroom/nestjs-libraries/dtos/auth/create.org.user.dto";
4+
import {LoginUserDto} from "@gitroom/nestjs-libraries/dtos/auth/login.user.dto";
5+
import {UsersService} from "@gitroom/nestjs-libraries/database/prisma/users/users.service";
6+
import {OrganizationService} from "@gitroom/nestjs-libraries/database/prisma/organizations/organization.service";
7+
import {AuthService as AuthChecker} from "@gitroom/helpers/auth/auth.service";
8+
import {ProvidersFactory} from "@gitroom/backend/services/auth/providers/providers.factory";
9+
10+
@Injectable()
11+
export class AuthService {
12+
constructor(
13+
private _user: UsersService,
14+
private _organization: OrganizationService,
15+
) {
16+
}
17+
async routeAuth(
18+
provider: Provider,
19+
body: CreateOrgUserDto | LoginUserDto
20+
) {
21+
if (provider === Provider.LOCAL) {
22+
const user = await this._user.getUserByEmail(body.email);
23+
if (body instanceof CreateOrgUserDto) {
24+
if (user) {
25+
throw new Error('User already exists');
26+
}
27+
28+
const create = await this._organization.createOrgAndUser(body);
29+
return this.jwt(create.users[0].user);
30+
}
31+
32+
if (!user || !AuthChecker.comparePassword(body.password, user.password)) {
33+
throw new Error('Invalid user');
34+
}
35+
36+
return this.jwt(user);
37+
}
38+
39+
const user = await this.loginOrRegisterProvider(provider, body as LoginUserDto);
40+
return this.jwt(user);
41+
}
42+
43+
private async loginOrRegisterProvider(provider: Provider, body: LoginUserDto) {
44+
const providerInstance = ProvidersFactory.loadProviders(provider);
45+
const providerUser = await providerInstance.getUser(body.providerToken);
46+
if (!providerUser) {
47+
throw new Error('Invalid provider token');
48+
}
49+
50+
const user = await this._user.getUserByProvider(providerUser.id, provider);
51+
if (user) {
52+
return user;
53+
}
54+
55+
const create = await this._organization.createOrgAndUser({
56+
company: '',
57+
email: providerUser.email,
58+
password: '',
59+
provider,
60+
providerId: providerUser.id
61+
});
62+
63+
return create.users[0].user;
64+
}
65+
66+
private async jwt(user: User) {
67+
return AuthChecker.signJWT(user);
68+
}
69+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface ProvidersInterface {
2+
getUser(providerToken: string): Promise<{email: string, id: string}> | false;
3+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {ProvidersInterface} from "@gitroom/backend/services/auth/providers.interface";
2+
3+
export class GithubProvider implements ProvidersInterface {
4+
async getUser(providerToken: string): Promise<{email: string, id: string}> {
5+
const data = await (await fetch('https://api.github.com/user', {
6+
headers: {
7+
Authorization: `token ${providerToken}`
8+
}
9+
})).json();
10+
return {
11+
email: data.email,
12+
id: data.id,
13+
};
14+
}
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {Provider} from "@prisma/client";
2+
import {GithubProvider} from "@gitroom/backend/services/auth/providers/github.provider";
3+
import {ProvidersInterface} from "@gitroom/backend/services/auth/providers.interface";
4+
5+
export class ProvidersFactory {
6+
static loadProviders(provider: Provider): ProvidersInterface {
7+
switch (provider) {
8+
case Provider.GITHUB:
9+
return new GithubProvider();
10+
}
11+
}
12+
}

apps/backend/tsconfig.app.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "../../dist/out-tsc",
5+
"module": "commonjs",
6+
"types": ["node"],
7+
"emitDecoratorMetadata": true,
8+
"target": "es2021"
9+
},
10+
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
11+
"include": ["src/**/*.ts"]
12+
}

apps/backend/tsconfig.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"files": [],
4+
"include": [],
5+
"references": [
6+
{
7+
"path": "./tsconfig.app.json"
8+
},
9+
{
10+
"path": "./tsconfig.spec.json"
11+
}
12+
],
13+
"compilerOptions": {
14+
"esModuleInterop": true
15+
}
16+
}

apps/backend/tsconfig.spec.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "../../dist/out-tsc",
5+
"module": "commonjs",
6+
"types": ["jest", "node"]
7+
},
8+
"include": [
9+
"jest.config.ts",
10+
"src/**/*.test.ts",
11+
"src/**/*.spec.ts",
12+
"src/**/*.d.ts"
13+
]
14+
}

0 commit comments

Comments
 (0)