Skip to content

Commit

Permalink
fix(front-end): add csrf request to all request (#137)
Browse files Browse the repository at this point in the history
* fix(server-response): a quick update of server response and fix adminjs problems

* chore: update auth.service.ts

* update 8 files

* chore: update 3 files and delete 1 file

* chore: update 16 files and delete 1 file

* update server.utils.ts and schema.gql

* update server.utils.ts

* Merge branch 'master' into quick-patch

* Update branch (#134)

* update package.json, pnpm-lock.yaml and schema.gql

* Merge remote-tracking branch 'origin/master' into quick-patch

* Apply automatic changes

* update app.middleware.ts and schema.gql

* Merge branch 'quick-patch' of https://github.com/524H0003/Project_W into quick-patch
  • Loading branch information
TakahashiNguyen authored Feb 17, 2025
1 parent 17259f3 commit e1c9def
Show file tree
Hide file tree
Showing 20 changed files with 326 additions and 301 deletions.
14 changes: 14 additions & 0 deletions cypress/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import ms from 'smtp-tester';

module.exports = (on, config) => {
// starts the SMTP server at localhost:7777
const port = 7777;
const mailServer = ms.init(port);
console.log('mail server at port %d', port);

// process all emails
mailServer.bind((addr, id, email) => {
console.log('--- email ---');
console.log(addr, id, email);
});
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"react": "^19.0.0",
"react-dom": "^19.0.0",
"rxjs": "^7.8.1",
"smtp-tester": "^2.1.0",
"start-server-and-test": "^2.0.10",
"typeorm": "^0.3.20",
"typeorm-extension": "^3.6.3",
Expand Down
150 changes: 91 additions & 59 deletions page/src/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import axios from 'axios';
import {
funcs,
IEmployeeHook,
IEmployeeSignUp,
IEnterpriseAssign,
IEntityId,
IEventInfo,
IFacultyAssign,
IResponse,
IUserAuthentication,
IUserInfo,
IUserRecieve,
Expand All @@ -16,67 +18,100 @@ const API_URL = '/api/v1';

export const alert = reactive<IAlert>({ message: '', type: 'none' }),
state = reactive<AuthState>({ user: null, token: null });

interface AuthState {
user: null | IUserInfo | string;
token: null | IUserRecieve;
}

export async function authRequest(
export async function action(
type: 'login' | 'signup' | 'logout' | 'change-password' | 'request-signature',
user?: Required<IUserAuthentication>,
) {
const response = await axios.post(`${API_URL}/${type}`, user);
state.user = response.data.user;
saveTokens(response.data.session);
return response.data.user;
}

export async function hookRequest(signature: string, password: string) {
const response = await axios.post(`${API_URL}/change-password/${signature}`, {
password,
});
return response.data;
}

export async function assignEvent(input: IEventInfo) {
const response = await axios.post(`${API_URL}/event/assign`, input);
return response.data;
}

export async function updateEvent(input: IEventInfo & IEntityId) {
const response = await axios.post(`${API_URL}/event/update`, input);
return response.data;
}

export async function assignEnterprise(input: IEnterpriseAssign) {
const response = await axios.post(`${API_URL}/enterprise/assign`, input);
return response.data;
}

export async function assignFaculty(input: IFacultyAssign) {
const response = await axios.post(`${API_URL}/faculty/assign`, input);
return response.data;
}

export async function assignEnterpriseUser(input: IEmployeeSignUp) {
const response = await axios.post(`${API_URL}/employee/signup`, input);
return response.data;
}

export async function requestConsole() {
const response = await axios.post(`${API_URL}/console`);
return response.data;
}
input: Required<IUserAuthentication>,
): Promise<IResponse>;
export async function action(
type: 'EventUpdate',
input: IEventInfo & IEntityId,
): Promise<IResponse>;
export async function action(
type: 'EventAssign',
input: IEventInfo,
): Promise<IResponse>;
export async function action(
type: 'EnterpriseAssign',
input: IEnterpriseAssign,
): Promise<IResponse>;
export async function action(
type: 'FacultyAssign',
input: IFacultyAssign,
): Promise<IResponse>;
export async function action(
type: 'EmployeeSignUp',
input: IEmployeeSignUp,
): Promise<IResponse>;
export async function action(
type: 'EmployeeHook',
input: IEmployeeHook,
): Promise<IResponse>;
export async function action(
type:
| 'login'
| 'signup'
| 'logout'
| 'change-password'
| 'request-signature'
| 'EmployeeHook'
| 'EventAssign'
| 'EventUpdate'
| 'EnterpriseAssign'
| 'FacultyAssign'
| 'EmployeeSignUp',
input:
| IEmployeeHook
| IEmployeeSignUp
| IEventInfo
| (IEventInfo & IEntityId)
| IEnterpriseAssign
| IFacultyAssign
| Required<IUserAuthentication>,
): Promise<IResponse> {
let url = API_URL;

switch (type) {
case 'EventAssign':
url += '/event/assign';
break;

case 'EventUpdate':
url += '/event/update';
break;

case 'EnterpriseAssign':
url += '/enterprise/assign';
break;

case 'FacultyAssign':
url += '/faculty/assign';
break;

case 'EmployeeSignUp':
url += '/employee/signup';
break;

case 'EmployeeHook':
url += '/employee/hook';
break;

default:
url += '/' + type;
break;
}

export async function requestFromEmployee(input: IEmployeeHook) {
const response = await axios.post(`${API_URL}/employee/hook`, input);
return response.data;
}
const { token } = (await axios.get(`${API_URL}/csrf-token`)).data,
{ data } = await axios.post(url, input, {
headers: { 'csrf-token': token },
});

function saveTokens(input: IUserRecieve) {
state.token = input;
localStorage.setItem('acsTkn', state.token!.accessToken);
localStorage.setItem('rfsTkn', state.token!.refreshToken);
return data;
}

export type IObject =
Expand All @@ -93,16 +128,13 @@ export interface IAlert {
object?: IObject;
}

export async function apiErrorHandler<T extends { message: string }>(
func: Promise<T>,
) {
export async function apiErrorHandler(response: Promise<IResponse>) {
alert.message = '';
alert.type = 'processing';

try {
const response = await func;
switch (response.message) {
case 'Sent_Signature_Email':
switch ((await response).message) {
case funcs.err('Success', 'Signature', 'Sent'):
alert.message =
'An email has sent to your email address, please check inbox and spam';
alert.type = 'error';
Expand Down
6 changes: 2 additions & 4 deletions page/src/router/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { createRouter, createWebHistory } from 'vue-router';
import LoginView from '@/views/LoginView.vue';
import NotFoundView from '@/views/NotFoundView.vue';
import HookView from '@/views/HookView.vue';
import ChangePasswordView from '@/views/ChangePassword.vue';
import EnterpriseAssignView from '@/views/EnterpriseAssignView.vue';
import EmployeeSignUpView from '@/views/EmployeeSignUpView.vue';
import FacultyAssignView from '@/views/FacultyAssignView.vue';
import EventAssignView from '@/views/EventAssignView.vue';
import EventUpdateView from '@/views/EventUpdateView.vue';
import AdminRequestSignatureView from '@/views/AdminRequestSignatureView.vue';
import FrontPageView from '@/views/FrontPageView.vue';

const router = createRouter({
Expand All @@ -16,11 +15,10 @@ const router = createRouter({
{ path: '/login', component: LoginView },
{ path: '/enterprise/assign', component: EnterpriseAssignView },
{ path: '/employee/signup', component: EmployeeSignUpView },
{ path: '/hook/:signature', component: HookView },
{ path: '/change-password/:signature', component: ChangePasswordView },
{ path: '/faculty/assign', component: FacultyAssignView },
{ path: '/event/assign', component: EventAssignView },
{ path: '/event/update', component: EventUpdateView },
{ path: '/request-signature', component: AdminRequestSignatureView },
{ path: '/', component: FrontPageView },
{ path: '/:pathMatch(.*)*', component: NotFoundView },
],
Expand Down
16 changes: 0 additions & 16 deletions page/src/views/AdminRequestSignatureView.vue

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<!-- eslint-disable @typescript-eslint/no-unused-vars -->
<template>
<FormContainerComp
btn-label="Confirm"
:btn-handle="handleHook"
:btn-handle="handleRequest"
:alert="alert"
name="Change password"
>
Expand All @@ -26,19 +27,14 @@
</template>

<script setup lang="ts">
import { apiErrorHandler, hookRequest, alert } from '@/auth.service';
import { action, alert, apiErrorHandler } from '@/auth.service';
import FormContainerComp from '@/components/FormContainerComp.vue';
import FormTextInputComp from '@/components/FormTextInputComp.vue';
import { IUserAuthentication } from 'project-w-backend';
import { reactive } from 'vue';
import { useRoute } from 'vue-router';

const route = useRoute(),
input = reactive<IUserAuthentication>({
const input = reactive<IUserAuthentication>({
password: '',
}),
handleHook = () =>
apiErrorHandler(
hookRequest(route.params.signature as string, input.password),
);
handleRequest = () => apiErrorHandler(action('change-password', input));
</script>
15 changes: 5 additions & 10 deletions page/src/views/EmployeeSignUpView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,15 @@
v-model="input.signature"
:alert="alert"
object="signature"
:sub-btn-click="request"
:sub-btn-click="signatureRequest"
>
Request signature
</FormTextInputComp>
</FormContainerComp>
</template>

<script setup lang="ts">
import {
alert,
apiErrorHandler,
assignEnterpriseUser,
requestFromEmployee,
} from '@/auth.service';
import { action, alert, apiErrorHandler } from '@/auth.service';
import FormContainerComp from '@/components/FormContainerComp.vue';
import FormSelectInputComp from '@/components/FormSelectInputComp.vue';
import FormTextInputComp from '@/components/FormTextInputComp.vue';
Expand All @@ -91,10 +86,10 @@ const input = reactive<IEmployeeSignUp & ISignature>({
name: '',
position: EmployeePosition['Other'],
}),
handleSignUp = () => apiErrorHandler(assignEnterpriseUser(input)),
request = () =>
handleSignUp = () => apiErrorHandler(action('EmployeeSignUp', input)),
signatureRequest = () =>
apiErrorHandler(
requestFromEmployee({
action('EmployeeHook', {
...inputRequest,
email: input.email,
name: input.name,
Expand Down
22 changes: 2 additions & 20 deletions page/src/views/EnterpriseAssignView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,11 @@
v-model="input.description"
type="text"
/>
<FormTextInputComp
name="Signature"
placeholder="Please send request to console"
icon="signature"
type="text"
v-model="input.signature"
:alert="alert"
object="signature"
:sub-btn-click="request"
>
Request signature from console
</FormTextInputComp>
</FormContainerComp>
</template>

<script setup lang="ts">
import {
alert,
apiErrorHandler,
assignEnterprise,
requestConsole,
} from '@/auth.service';
import { action, alert, apiErrorHandler } from '@/auth.service';
import FormContainerComp from '@/components/FormContainerComp.vue';
import FormTextInputComp from '@/components/FormTextInputComp.vue';
import { reactive } from 'vue';
Expand All @@ -67,6 +50,5 @@ const input = reactive<IEnterpriseAssign & ISignature>({
name: '',
email: '',
}),
handleAssign = () => apiErrorHandler(assignEnterprise(input)),
request = () => apiErrorHandler(requestConsole());
handleAssign = () => apiErrorHandler(action('EnterpriseAssign', input));
</script>
4 changes: 2 additions & 2 deletions page/src/views/EventAssignView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
</template>

<script setup lang="ts">
import { alert, apiErrorHandler, assignEvent } from '@/auth.service';
import { action, alert, apiErrorHandler } from '@/auth.service';
import FormContainerComp from '@/components/FormContainerComp.vue';
import FormDateInputComp from '@/components/FormDateInputComp.vue';
import FormSelectInputComp from '@/components/FormSelectInputComp.vue';
Expand All @@ -81,7 +81,7 @@ const input = reactive<IEventInfo>({
}),
handleAssign = () => {
apiErrorHandler(
assignEvent({
action('EventAssign', {
...input,
positionsAvailable: input.maxParticipants,
}),
Expand Down
4 changes: 2 additions & 2 deletions page/src/views/EventUpdateView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
</template>

<script setup lang="ts">
import { alert, apiErrorHandler, updateEvent } from '@/auth.service';
import { action, alert, apiErrorHandler } from '@/auth.service';
import FormContainerComp from '@/components/FormContainerComp.vue';
import FormDateInputComp from '@/components/FormDateInputComp.vue';
import FormSelectInputComp from '@/components/FormSelectInputComp.vue';
Expand All @@ -96,6 +96,6 @@ const input = reactive<IEventInfo>({
additionalFields: {},
}),
handleAssign = () => {
apiErrorHandler(updateEvent({ ...input }));
apiErrorHandler(action('EventUpdate', input));
};
</script>
Loading

0 comments on commit e1c9def

Please sign in to comment.