-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(backend): setup and implement rest resources
- Loading branch information
1 parent
4c09641
commit b6d931b
Showing
98 changed files
with
283 additions
and
2,911 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { Controller, Get } from '@nestjs/common'; | ||
|
||
@Controller() | ||
export class AppController { | ||
constructor() {} | ||
|
||
@Get() | ||
async helloWorld(): Promise<string> { | ||
return 'Hello from Snipcode!'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { Injectable, OnModuleInit } from '@nestjs/common'; | ||
import { ConfigService } from '@nestjs/config'; | ||
import { RoleService, UserService } from '@snipcode/domain'; | ||
|
||
import { EnvironmentVariables } from '../../configs/environment'; | ||
|
||
@Injectable() | ||
export class AppService implements OnModuleInit { | ||
constructor( | ||
private readonly configService: ConfigService<EnvironmentVariables, true>, | ||
private readonly userService: UserService, | ||
private readonly roleService: RoleService, | ||
) {} | ||
|
||
async onModuleInit(): Promise<void> { | ||
await this.roleService.loadRoles(); | ||
|
||
const adminRole = await this.roleService.findByName('admin'); | ||
|
||
if (!adminRole) { | ||
throw new Error('[Data Loader]: Role administrator not found'); | ||
} | ||
|
||
const adminPassword = this.configService.get<string>('ADMIN_PASSWORD'); | ||
|
||
await this.userService.loadAdminUser(adminRole, adminPassword); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,10 @@ | ||
import { Module } from '@nestjs/common'; | ||
|
||
import { AuthResolvers } from './graphql/auth.resolvers'; | ||
import { AuthController } from './rest/auth.controller'; | ||
import { GithubService } from './services/github.service'; | ||
|
||
@Module({ | ||
providers: [AuthResolvers], | ||
providers: [AuthResolvers, GithubService, AuthController], | ||
}) | ||
export class AuthFeatureModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { Controller, Get, Logger, Query, Res } from '@nestjs/common'; | ||
import { ConfigService } from '@nestjs/config'; | ||
import { | ||
CreateSessionInput, | ||
CreateUserRootFolderInput, | ||
FolderService, | ||
RoleService, | ||
SessionService, | ||
UserService, | ||
} from '@snipcode/domain'; | ||
import { addDayToDate, errors } from '@snipcode/utils'; | ||
import { Response } from 'express'; | ||
|
||
import { EnvironmentVariables } from '../../../configs/environment'; | ||
import { AUTH_SUCCESS_URL } from '../../../utils/constants'; | ||
import { GithubService } from '../services/github.service'; | ||
|
||
@Controller('auth') | ||
export class AuthController { | ||
private readonly logger = new Logger(AuthController.name); | ||
|
||
constructor( | ||
private readonly configService: ConfigService<EnvironmentVariables, true>, | ||
private readonly githubService: GithubService, | ||
private readonly userService: UserService, | ||
private readonly roleService: RoleService, | ||
private readonly folderService: FolderService, | ||
private readonly sessionService: SessionService, | ||
) {} | ||
|
||
@Get('github/callback') | ||
async authenticateWithGitHub(@Query('code') requestToken: string, @Res() res: Response): Promise<void> { | ||
const sessionLifetime = this.configService.get<number>('SESSION_LIFETIME'); | ||
const webAuthSuccessUrl = this.configService.get<string>('WEB_AUTH_SUCCESS_URL'); | ||
const webAuthErrorUrl = this.configService.get<string>('WEB_AUTH_ERROR_URL'); | ||
|
||
const authResponse = await this.githubService.requestAccessTokenFromCode(requestToken); | ||
|
||
const { access_token } = authResponse.data; | ||
|
||
const userResponse = await this.githubService.retrieveGitHubUserData(access_token); | ||
|
||
const userExist = await this.userService.findByEmail(userResponse.data.email); | ||
|
||
if (userExist) { | ||
const sessionInput = new CreateSessionInput({ | ||
expireDate: addDayToDate(sessionLifetime), | ||
userId: userExist.id, | ||
}); | ||
const session = await this.sessionService.create(sessionInput); | ||
|
||
const updateUserInput = this.githubService.generateUserUpdateInputFromGitHubData(userExist, userResponse.data); | ||
|
||
await this.userService.update(userExist, updateUserInput); | ||
|
||
return res.redirect(AUTH_SUCCESS_URL(webAuthSuccessUrl, session.token)); | ||
} | ||
|
||
const roleUser = await this.roleService.findByName('user'); | ||
|
||
if (!roleUser) { | ||
this.logger.error(`GitHub Authentication: ${errors.ROLE_USER_NOT_FOUND}`); | ||
|
||
return res.redirect(webAuthErrorUrl); | ||
} | ||
|
||
const createUserInput = this.githubService.generateUserRegistrationInputFromGitHubData( | ||
userResponse.data, | ||
roleUser.id, | ||
); | ||
|
||
const createdUser = await this.userService.create(createUserInput); | ||
|
||
const createUserRootFolderInput = new CreateUserRootFolderInput(createdUser.id); | ||
|
||
await this.folderService.createUserRootFolder(createUserRootFolderInput); | ||
|
||
const sessionInput = new CreateSessionInput({ | ||
expireDate: addDayToDate(sessionLifetime), | ||
userId: createdUser.id, | ||
}); | ||
|
||
const session = await this.sessionService.create(sessionInput); | ||
|
||
return res.redirect(AUTH_SUCCESS_URL(webAuthSuccessUrl, session.token)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { ConfigService } from '@nestjs/config'; | ||
import { CreateUserInput, UpdateUserInput, User } from '@snipcode/domain'; | ||
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'; | ||
|
||
import { EnvironmentVariables } from '../../../configs/environment'; | ||
import { GitHubUserResponse } from '../types'; | ||
|
||
const GITHUB_AUTH_URL = 'https://github.com/login/oauth/access_token'; | ||
const GITHUB_API_USER_PROFILE_URL = 'https://api.github.com/user'; | ||
|
||
@Injectable() | ||
export class GithubService { | ||
private httpClient: AxiosInstance = axios.create(); | ||
|
||
constructor(private readonly configService: ConfigService<EnvironmentVariables, true>) {} | ||
|
||
async requestAccessTokenFromCode(code: string) { | ||
const authQueryObject = { | ||
client_id: this.configService.get('GITHUB_CLIENT_ID'), | ||
client_secret: this.configService.get('GITHUB_CLIENT_SECRET'), | ||
code, | ||
}; | ||
const requestConfig: AxiosRequestConfig = { | ||
headers: { | ||
accept: 'application/json', | ||
}, | ||
}; | ||
const requestBody = {}; | ||
|
||
const authQueryString = new URLSearchParams(Object.entries(authQueryObject)).toString(); | ||
|
||
return this.httpClient.post(`${GITHUB_AUTH_URL}?${authQueryString}`, requestBody, requestConfig); | ||
} | ||
|
||
async retrieveGitHubUserData(accessToken: string) { | ||
const requestConfig: AxiosRequestConfig = { | ||
headers: { | ||
Authorization: `token ${accessToken}`, | ||
}, | ||
}; | ||
|
||
return this.httpClient.get<GitHubUserResponse>(GITHUB_API_USER_PROFILE_URL, requestConfig); | ||
} | ||
|
||
generateUserRegistrationInputFromGitHubData = (data: GitHubUserResponse, roleId: string): CreateUserInput => { | ||
const { avatar_url, email, login, name } = data; | ||
|
||
const createUserInput = new CreateUserInput({ | ||
email, | ||
name, | ||
oauthProvider: 'github', | ||
pictureUrl: avatar_url, | ||
roleId, | ||
timezone: null, | ||
username: login, | ||
}); | ||
|
||
createUserInput.isEnabled = true; | ||
|
||
return createUserInput; | ||
}; | ||
|
||
generateUserUpdateInputFromGitHubData = (user: User, data: GitHubUserResponse): UpdateUserInput => { | ||
const { avatar_url, name } = data; | ||
|
||
return new UpdateUserInput({ | ||
name, | ||
oauthProvider: 'github', | ||
pictureUrl: avatar_url, | ||
roleId: user.roleId, | ||
timezone: user.timezone, | ||
}); | ||
}; | ||
} |
File renamed without changes.
28 changes: 28 additions & 0 deletions
28
apps/backend/src/features/snippets/rest/snippet.controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { Controller, Get, Param } from '@nestjs/common'; | ||
import { ConfigService } from '@nestjs/config'; | ||
import { SnippetService } from '@snipcode/domain'; | ||
import { OEmbedResult, generateOembedMetadata } from '@snipcode/embed'; | ||
|
||
import { EnvironmentVariables } from '../../../configs/environment'; | ||
|
||
@Controller('snippets') | ||
export class SnippetController { | ||
constructor( | ||
private readonly configService: ConfigService<EnvironmentVariables, true>, | ||
private readonly snippetService: SnippetService, | ||
) {} | ||
|
||
@Get(':id/oembed') | ||
async generateOembed(@Param('id') id: string): Promise<OEmbedResult> { | ||
const snippet = await this.snippetService.findById(id); | ||
|
||
return generateOembedMetadata({ | ||
snippet: { | ||
id: snippet.id, | ||
name: snippet.name, | ||
}, | ||
snippetRendererURL: this.configService.get('SNIPPET_RENDERER_API_URL'), | ||
webAppURL: this.configService.get('WEB_APP_URL'), | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,9 @@ | ||
import { Module } from '@nestjs/common'; | ||
|
||
import { SnippetResolvers } from './graphql/snippet.resolvers'; | ||
import { SnippetController } from './rest/snippet.controller'; | ||
|
||
@Module({ | ||
providers: [SnippetResolvers], | ||
providers: [SnippetResolvers, SnippetController], | ||
}) | ||
export class SnippetFeatureModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.