From 7e79c9b32ececf665e1fecd08061f219f94820ee Mon Sep 17 00:00:00 2001 From: Nuno Caseiro <90208434+nunocaseiro@users.noreply.github.com> Date: Tue, 8 Feb 2022 17:29:56 +0000 Subject: [PATCH] chore: docker compose and docker files for each app (#77) --- .all-contributorsrc | 2 +- .env.example | 62 ++++++++++--- README.md | 20 ++-- backend/.dockerignore | 2 + backend/.env.example | 29 +++--- backend/Dockerfile | 30 ++++++ backend/src/auth/auth.module.ts | 7 +- backend/src/auth/auth.service.ts | 30 +++--- backend/src/constants/jwt.ts | 29 ++---- .../models/users/tests/users.service.spec.ts | 4 +- backend/src/models/users/users.service.ts | 3 +- docker-compose.yaml | 44 ++++++++- frontend/.dockerignore | 2 + frontend/.env.example | 17 ++-- frontend/Dockerfile | 56 +++++++++++ frontend/api/authService.tsx | 4 +- frontend/components/auth/LoginForm.tsx | 16 ++-- frontend/errors/errorMessages.ts | 9 +- frontend/next.config.js | 3 + frontend/package-lock.json | 92 ++++++++++++++----- frontend/utils/fetchData.tsx | 18 +++- 21 files changed, 349 insertions(+), 130 deletions(-) create mode 100644 backend/.dockerignore create mode 100644 backend/Dockerfile create mode 100644 frontend/.dockerignore create mode 100644 frontend/Dockerfile diff --git a/.all-contributorsrc b/.all-contributorsrc index 7501b21f0..94bf54229 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7,7 +7,7 @@ "contributors": [ ], "contributorsPerLine": 7, - "projectName": "oss-template", + "projectName": "divide-and-conquer", "projectOwner": "xgeekshq", "repoType": "github", "repoHost": "https://github.com", diff --git a/.env.example b/.env.example index 0c7aba50b..117fa8b6f 100644 --- a/.env.example +++ b/.env.example @@ -1,17 +1,55 @@ -# database host value -DB_HOST=localhost - -# admin username +#admin db user DB_ROOT_USER=admin -# admin password -DB_ROOT_PASSWORD=password +#admin db password +DB_ROOT_PASSWORD=123456 + +#db user +DB_USER=backend + +#db password +DB_PASSWORD=dc2021backend + +#db name +DB_NAME=dc + +#docker database container name +DB_HOST=mongo + +#----------- + +#db port +DB_PORT=27017 + +#backend port +BACKEND_PORT=3200 + +#secret to sign access token in backend +JWT_ACCESS_TOKEN_SECRET=backenddc2021 + +#access token expiration time in seconds +JWT_ACCESS_TOKEN_EXPIRATION_TIME=900 + +#secret to sign refresh token in backend +JWT_REFRESH_TOKEN_SECRET=backenddc2021refresh + +#refresh token expiration time in days +JWT_REFRESH_TOKEN_EXPIRATION_TIME=1 + +#backend url exposed to the browser +NEXT_PUBLIC_BACKEND_URL=http://localhost:3200 + +#backend url in server side +BACKEND_URL=http://backend:3200 + +#auth url +NEXTAUTH_URL=http://localhost:3000 -# user with lower privileges -DB_USER=dcuser +#auth url exposed to the browser +NEXT_PUBLIC_NEXTAUTH_URL=http://localhost:3000 -# password for the user -DB_PASSWORD=password +#secret to encode jwt in frontend +SECRET=56e9169e3383d4a73fef9e0b4a3ff4e2 -# database name -DB_NAME=dc \ No newline at end of file +#jwt expiration time exposed to the browser +NEXT_PUBLIC_EXPIRATION_TIME=900 \ No newline at end of file diff --git a/README.md b/README.md index 11b0d337b..6ad0aba15 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,8 @@ - [Database](#database) - [Backend](#backend) - [Frontend](#frontend) - - [Usage](#usage) +- [🏃 How to Run - with docker](#--how-to-run---with-docker) +- [Usage](#usage) - [📝 License](#-license) - [Contributors ✨](#contributors-) @@ -37,7 +38,7 @@ Check out our [**Contributing Guide**](.github/CONTRIBUTING.md) for information ## 🏃 How to Run - Dev mode To run the project you will need the requirements listed below and configure the env files as described in the example. -In the near future all applications will be dockerized. +In the next section [**How to run - with docker**](#--how-to-run---with-docker) you can find instructions on how to run the entire project with docker. ### Requirements @@ -46,14 +47,15 @@ In the near future all applications will be dockerized. 3. Env files ### Env files -An .env file must be in the project root folder where the docker compose file is located and the others in each app folder (frontend and backend). -This files are already provisioned as an example (`.env.example`) in the respective folders and you can use and edit them. -The frontend .env file have the parameter named *SECRET* that is required by next-auth on the frontend and to generate it just run the following command `openssl rand -base64 32` in the shell then paste it in the .env file. +An `.env` file must be present in each app folder (frontend and backend) and it's also needed the `.env` in the root folder of the project in order to create the database. +This files are already provisioned as an example (`.env.example`) in the respective folders and you can use and edit them. In order to use the example, please remove the suffix `.example` from the file name. + +The frontend `.env` file have the parameter named *SECRET* that is required by next-auth on the frontend and to generate it just run the following command `openssl rand -base64 32` in the shell then paste it in the `.env` file. ### Database -Since the database is the only app that is containerized, to run it step into the project root folder and run `docker-compose up -d`. +Since the database is the only app required to run in dev mode. You need to build it running the follow command `docker-compose up -d mongo` in the project's root folder. The mongo image is downloaded, built and the database is created with the name that is passed as described in the env file parameter called *DB_NAME*. After the container is built, the init script that's inside the database folder runs in order to create a user to manage and connect to the database from the backend. ### Backend @@ -64,7 +66,11 @@ To run this application for the first time run `npm i` inside the backend folder To run this application for the first time run `npm i` inside the frontend folder. Once you have installed the dependencies, simply run: `npm run dev` -### Usage +## 🏃 How to Run - with docker + +In order to run the whole project with docker you need to prepare the `.env.example` file that is present in the root folder of the project and from there run the following command: `docker-compose up -d` + +## Usage The backend will run on `http://localhost:BACKEND_PORT` and the frontend on `http://localhost:3000`. Be aware the frontend root page ("/") is the landing page and has not yet been built so you must manually enter one of the following routes: diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 000000000..8f9d79913 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,2 @@ +node_modules/* +dist/* \ No newline at end of file diff --git a/backend/.env.example b/backend/.env.example index 6b2494f2b..128d576af 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -1,29 +1,30 @@ -# database host value + +#docker database container name DB_HOST=localhost -# user with lower privileges -DB_USER=dcuser +#db user +DB_USER=backend -# password for the user -DB_PASSWORD=password +#db password +DB_PASSWORD=dc2021backend -# database name +#db name DB_NAME=dc -# database port +#db port DB_PORT=27017 -# backend port +#backend poxrt BACKEND_PORT=3200 -# a strong secret to sign the access tokens -JWT_ACCESS_TOKEN_SECRET=a_strong_secret +#secret to sign access token in backend +JWT_ACCESS_TOKEN_SECRET=backenddc2021 -# expiration time of refresh token in seconds +#access token expiration time in seconds JWT_ACCESS_TOKEN_EXPIRATION_TIME=900 -# a strong secret to sign the refresh tokens -JWT_REFRESH_TOKEN_SECRET=another_strong_secret +#secret to sign refresh token in backend +JWT_REFRESH_TOKEN_SECRET=backenddc2021refresh -# expiration time of refresh token in days +#refresh token expiration time in days JWT_REFRESH_TOKEN_EXPIRATION_TIME=1 \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 000000000..795829bf4 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,30 @@ +FROM node:17-alpine as builder + +ENV NODE_ENV build + +WORKDIR /home/node + +COPY . /home/node + +RUN npm ci \ + && npm run build \ + && npm prune --production + +# --- + +FROM node:17-alpine + +ENV NODE_ENV production + +EXPOSE 3200 + +ENV PORT 3200 + +USER node +WORKDIR /home/node + +COPY --from=builder /home/node/package*.json /home/node/ +COPY --from=builder /home/node/node_modules/ /home/node/node_modules/ +COPY --from=builder /home/node/dist/ /home/node/dist/ + +CMD ["node", "dist/src/main.js"] \ No newline at end of file diff --git a/backend/src/auth/auth.module.ts b/backend/src/auth/auth.module.ts index 486e14eb8..7c4de6c61 100644 --- a/backend/src/auth/auth.module.ts +++ b/backend/src/auth/auth.module.ts @@ -9,7 +9,6 @@ import LocalStrategy from './strategy/local.strategy'; import JwtStrategy from './strategy/jwt.strategy'; import JwtRefreshTokenStrategy from './strategy/refresh.strategy'; import { - describeJWT, JWT_ACCESS_TOKEN_SECRET, JWT_ACCESS_TOKEN_EXPIRATION_TIME, } from '../constants/jwt'; @@ -23,11 +22,9 @@ import { imports: [ConfigModule], inject: [ConfigService], useFactory: async (configService: ConfigService) => ({ - secret: configService.get(describeJWT(JWT_ACCESS_TOKEN_SECRET)), + secret: configService.get(JWT_ACCESS_TOKEN_SECRET), signOptions: { - expiresIn: `${configService.get( - describeJWT(JWT_ACCESS_TOKEN_EXPIRATION_TIME), - )}s`, + expiresIn: `${configService.get(JWT_ACCESS_TOKEN_EXPIRATION_TIME)}s`, }, }), }), diff --git a/backend/src/auth/auth.service.ts b/backend/src/auth/auth.service.ts index bd1dd4c18..7206768ef 100644 --- a/backend/src/auth/auth.service.ts +++ b/backend/src/auth/auth.service.ts @@ -11,9 +11,12 @@ import { JWT_ACCESS_TOKEN_SECRET, JWT_REFRESH_TOKEN_EXPIRATION_TIME, JWT_REFRESH_TOKEN_SECRET, - describeJWT, } from '../constants/jwt'; -import { INVALID_CREDENTIALS, EMAIL_EXISTS } from '../constants/httpExceptions'; +import { + INVALID_CREDENTIALS, + EMAIL_EXISTS, + USER_NOT_FOUND, +} from '../constants/httpExceptions'; @Injectable() export default class AuthService { @@ -25,8 +28,7 @@ export default class AuthService { public async getAuthenticatedUser(email: string, plainTextPassword: string) { const user = await this.usersService.getByEmail(email); - if (!user.password) - throw new HttpException(INVALID_CREDENTIALS, HttpStatus.BAD_REQUEST); + if (!user) throw new HttpException(USER_NOT_FOUND, HttpStatus.NOT_FOUND); await this.verifyPassword(plainTextPassword, user.password); return user; } @@ -37,7 +39,7 @@ export default class AuthService { ) { const isPasswordMatching = await compare(plainTextPassword, hashedPassword); if (!isPasswordMatching) { - throw new HttpException(INVALID_CREDENTIALS, HttpStatus.BAD_REQUEST); + throw new HttpException(INVALID_CREDENTIALS, HttpStatus.UNAUTHORIZED); } } @@ -71,15 +73,11 @@ export default class AuthService { public getJwtAccessToken(userId: string) { const payload: TokenPayload = { userId }; const token = this.jwtService.sign(payload, { - secret: this.configService.get(describeJWT(JWT_ACCESS_TOKEN_SECRET)), - expiresIn: `${this.configService.get( - describeJWT(JWT_ACCESS_TOKEN_EXPIRATION_TIME), - )}s`, + secret: this.configService.get(JWT_ACCESS_TOKEN_SECRET), + expiresIn: `${this.configService.get(JWT_ACCESS_TOKEN_EXPIRATION_TIME)}s`, }); return { - expiresIn: this.configService.get( - describeJWT(JWT_ACCESS_TOKEN_EXPIRATION_TIME), - ), + expiresIn: this.configService.get(JWT_ACCESS_TOKEN_EXPIRATION_TIME), token, }; } @@ -88,15 +86,13 @@ export default class AuthService { const payload: TokenPayload = { userId }; const token = this.jwtService.sign(payload, { - secret: this.configService.get(describeJWT(JWT_REFRESH_TOKEN_SECRET)), + secret: this.configService.get(JWT_REFRESH_TOKEN_SECRET), expiresIn: `${this.configService.get( - describeJWT(JWT_REFRESH_TOKEN_EXPIRATION_TIME), + JWT_REFRESH_TOKEN_EXPIRATION_TIME, )}d`, }); return { - expiresIn: this.configService.get( - describeJWT(JWT_REFRESH_TOKEN_EXPIRATION_TIME), - ), + expiresIn: this.configService.get(JWT_REFRESH_TOKEN_EXPIRATION_TIME), token, }; } diff --git a/backend/src/constants/jwt.ts b/backend/src/constants/jwt.ts index 8762a70e5..72ea353e5 100644 --- a/backend/src/constants/jwt.ts +++ b/backend/src/constants/jwt.ts @@ -1,24 +1,7 @@ -export const JWT_REFRESH_TOKEN_SECRET = Symbol('refresh token secret'); -export const JWT_REFRESH_TOKEN_EXPIRATION_TIME = Symbol( - 'refresh token expiration time', -); +export const JWT_REFRESH_TOKEN_SECRET = 'JWT_REFRESH_TOKEN_SECRET'; +export const JWT_REFRESH_TOKEN_EXPIRATION_TIME = + 'JWT_REFRESH_TOKEN_EXPIRATION_TIME'; -export const JWT_ACCESS_TOKEN_SECRET = Symbol('access token secret'); -export const JWT_ACCESS_TOKEN_EXPIRATION_TIME = Symbol( - 'access token expiration time', -); - -export function describeJWT(key: symbol): string { - switch (key) { - case JWT_REFRESH_TOKEN_SECRET: - return 'JWT_REFRESH_TOKEN_SECRET'; - case JWT_REFRESH_TOKEN_EXPIRATION_TIME: - return 'JWT_REFRESH_TOKEN_EXPIRATION_TIME'; - case JWT_ACCESS_TOKEN_SECRET: - return 'JWT_ACCESS_TOKEN_SECRET'; - case JWT_ACCESS_TOKEN_EXPIRATION_TIME: - return 'JWT_ACCESS_TOKEN_EXPIRATION_TIME'; - default: - return 'ERROR'; - } -} +export const JWT_ACCESS_TOKEN_SECRET = 'JWT_ACCESS_TOKEN_SECRET'; +export const JWT_ACCESS_TOKEN_EXPIRATION_TIME = + 'JWT_ACCESS_TOKEN_EXPIRATION_TIME'; diff --git a/backend/src/models/users/tests/users.service.spec.ts b/backend/src/models/users/tests/users.service.spec.ts index e754fb6e4..29aac6a76 100644 --- a/backend/src/models/users/tests/users.service.spec.ts +++ b/backend/src/models/users/tests/users.service.spec.ts @@ -49,9 +49,7 @@ describe('UsersService', () => { findOne.mockReturnValue(undefined); }); it('should throw an error', async () => { - await expect( - usersService.getByEmail('test@test.com'), - ).rejects.toThrow(); + expect(await usersService.getByEmail('test@test.com')).toEqual(false); }); }); }); diff --git a/backend/src/models/users/users.service.ts b/backend/src/models/users/users.service.ts index 8373bb689..7258ca85f 100644 --- a/backend/src/models/users/users.service.ts +++ b/backend/src/models/users/users.service.ts @@ -5,7 +5,6 @@ import User, { UserDocument } from './schemas/user.schema'; import CreateUserDto from './dto/createUser.dto'; import { compare, encrypt } from '../../utils/bcrypt'; import { - EMAIL_NOT_EXISTS, USER_NOT_FOUND, TOKENS_NOT_MATCHING, DELETE_FAILED, @@ -18,7 +17,7 @@ export default class UsersService { async getByEmail(email: string) { const user = await this.userModel.findOne({ email }); if (user) return user; - throw new HttpException(EMAIL_NOT_EXISTS, HttpStatus.NOT_FOUND); + return false; } async getById(_id: string) { diff --git a/docker-compose.yaml b/docker-compose.yaml index 7dbc412d7..72de1399c 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,6 +1,46 @@ version: "3.9" services: + backend: + build: + context: backend + image: dc-backend + ports: + - "3200:3200" + environment: + DB_USER: ${DB_USER:-backend} + DB_PASSWORD: ${DB_PASSWORD:-password} + DB_NAME: ${DB_NAME:-dc} + DB_HOST: ${DB_HOST:-mongo} + DB_PORT: ${DB_PORT:-27017} + BACKEND_PORT: ${BACKEND_PORT:-3200} + JWT_ACCESS_TOKEN_SECRET: ${JWT_ACCESS_TOKEN_SECRET:-backenddc2022} + JWT_ACCESS_TOKEN_EXPIRATION_TIME: ${JWT_ACCESS_TOKEN_EXPIRATION_TIME:-900} + JWT_REFRESH_TOKEN_SECRET: ${JWT_REFRESH_TOKEN_SECRET:-backenddc2022refresh} + JWT_REFRESH_TOKEN_EXPIRATION_TIME: ${JWT_REFRESH_TOKEN_EXPIRATION_TIME:-1} + restart: unless-stopped + depends_on: + - mongo + frontend: + build: + context: frontend + dockerfile: Dockerfile + args: + - NEXT_PUBLIC_BACKEND_URL=${NEXT_PUBLIC_BACKEND_URL:-http://localhost:3200} + - NEXT_PUBLIC_NEXTAUTH_URL=${NEXT_PUBLIC_NEXTAUTH_URL:-http://localhost:3000} + image: dc-frontend + ports: + - "3000:3000" + environment: + NEXT_PUBLIC_BACKEND_URL: ${NEXT_PUBLIC_BACKEND_URL:-http://localhost:3200} + BACKEND_URL: ${BACKEND_URL:-http://backend:3200} + NEXTAUTH_URL: ${NEXTAUTH_URL:-http://localhost:3000} + NEXT_PUBLIC_NEXTAUTH_URL: ${NEXT_PUBLIC_NEXTAUTH_URL:-http://localhost:3000} + SECRET: ${SECRET:-56e9169e3383d4a73fef9e0b4a3ff4e2} + NEXT_PUBLIC_EXPIRATION_TIME: ${NEXT_PUBLIC_EXPIRATION_TIME:-900} + restart: unless-stopped + depends_on: + - backend mongo: image: mongo restart: always @@ -10,8 +50,8 @@ services: volumes: - ./database/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro environment: - MONGO_INITDB_ROOT_USERNAME: ${DB_ROOT_USER:-root} + MONGO_INITDB_ROOT_USERNAME: ${DB_ROOT_USER:-admin} MONGO_INITDB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-password} MONGO_INITDB_DATABASE: ${DB_NAME:-dc} MONGO_BACKEND_USER: ${DB_USER:-backend} - MONGO_BACKEND_PASSWORD: ${DB_PASSWORD:-password} + MONGO_BACKEND_PASSWORD: ${DB_PASSWORD:-password} \ No newline at end of file diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 000000000..8f9d79913 --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,2 @@ +node_modules/* +dist/* \ No newline at end of file diff --git a/frontend/.env.example b/frontend/.env.example index 71e8f6c79..65baef5c2 100644 --- a/frontend/.env.example +++ b/frontend/.env.example @@ -1,14 +1,17 @@ -# backend url exposed to the browser +#backend url exposed to the browser NEXT_PUBLIC_BACKEND_URL=http://localhost:3200 -# backend internal url -BACKEND_URL=http://backend:3200 +#backend url - server side +BACKEND_URL=http://localhost:3200 -# auth url +#auth url - server side NEXTAUTH_URL=http://localhost:3000 -# auth url exposed to the browser +#auth url exposed to the browser NEXT_PUBLIC_NEXTAUTH_URL=http://localhost:3000 -#secret to sign jwt tokens -SECRET=56e9169e3383d4a73fef9e0b4a3ff4e2 \ No newline at end of file +#secret to encode jwt in frontend +SECRET=56e9169e3383d4a73fef9e0b4a3ff4e2 + +#jwt expiration time exposed to the browser +NEXT_PUBLIC_EXPIRATION_TIME=900 \ No newline at end of file diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 000000000..b9213d083 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,56 @@ +# Install dependencies only when needed +FROM node:17-alpine AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat +WORKDIR /app +COPY package.json ./ +RUN npm install --frozen-lockfile + +# If using npm with a `package-lock.json` comment out above and use below instead +# COPY package.json package-lock.json / +# RUN npm install + +# Rebuild the source code only when needed +FROM node:17-alpine AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +ARG NEXT_PUBLIC_BACKEND_URL +ENV NEXT_PUBLIC_BACKEND_URL=${NEXT_PUBLIC_BACKEND_URL} +ARG NEXT_PUBLIC_NEXTAUTH_URL +ENV NEXT_PUBLIC_NEXTAUTH_URL=${NEXT_PUBLIC_NEXTAUTH_URL} + +RUN npm run build + +# Production image, copy all the files and run next +FROM node:16-alpine AS runner +WORKDIR /app + +#ENV NODE_ENV production + +RUN addgroup -g 1001 -S nodejs +RUN adduser -S nextjs -u 1001 + +# You only need to copy next.config.js if you are NOT using the default configuration +# COPY --from=builder /app/next.config.js ./ +COPY --from=builder /app/public ./public +COPY --from=builder /app/package.json ./package.json + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT 3000 + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry. +# ENV NEXT_TELEMETRY_DISABLED 1 + +CMD ["node", "server.js"] \ No newline at end of file diff --git a/frontend/api/authService.tsx b/frontend/api/authService.tsx index 2514725b2..316f95280 100644 --- a/frontend/api/authService.tsx +++ b/frontend/api/authService.tsx @@ -7,9 +7,9 @@ export const postUser = (newUser: User): Promise => { }; export const login = (credentials: LoginUser): Promise => { - return fetchData("/auth/login", { method: "POST", data: credentials }); + return fetchData("/auth/login", { method: "POST", data: credentials, serverSide: true }); }; export const refreshToken = (token: string): Promise => { - return fetchData("/auth/refresh", { token }); + return fetchData("/auth/refresh", { token, serverSide: true }); }; diff --git a/frontend/components/auth/LoginForm.tsx b/frontend/components/auth/LoginForm.tsx index 91e39ac7a..20cd03e2e 100644 --- a/frontend/components/auth/LoginForm.tsx +++ b/frontend/components/auth/LoginForm.tsx @@ -11,7 +11,7 @@ import { TabsContent } from "../Primitives/Tab"; import Text from "../Primitives/Text"; import Button from "../Primitives/Button"; import AuthFieldSet from "./FieldSet/AuthFieldSet"; -import ErrorMessages from "../../errors/errorMessages"; +import ErrorMessages, { errorCodes } from "../../errors/errorMessages"; import SchemaLoginForm from "../../schema/schemaLoginForm"; import { DASHBOARD_ROUTE } from "../../utils/routes"; @@ -25,7 +25,7 @@ const StyledButton = styled(Button, { mt: "$8", width: "100%" }); const StyledForm = styled("form", { width: "100%" }); const LoginForm: React.FC = () => { - const [loginError, setLoginError] = useState(false); + const [loginErrorCode, setLoginErrorCode] = useState(0); const methods = useForm({ resolver: zodResolver(SchemaLoginForm), }); @@ -40,10 +40,10 @@ const LoginForm: React.FC = () => { if (!result?.error) { router.push(DASHBOARD_ROUTE); } else { - setLoginError(true); + setLoginErrorCode(errorCodes(result.error)); } } catch (error) { - setLoginError(true); + setLoginErrorCode(errorCodes(error as unknown as string)); } }; @@ -56,9 +56,13 @@ const LoginForm: React.FC = () => { onLogin(credentials); })} > - {loginError ? ( + {loginErrorCode > 0 ? ( - {ErrorMessages.INVALID_CREDENTIALS} + + {loginErrorCode === 401 + ? ErrorMessages.INVALID_CREDENTIALS + : ErrorMessages.USER_NOT_FOUND} + ) : null} diff --git a/frontend/errors/errorMessages.ts b/frontend/errors/errorMessages.ts index 697c2689b..0e0a7292c 100644 --- a/frontend/errors/errorMessages.ts +++ b/frontend/errors/errorMessages.ts @@ -4,9 +4,12 @@ interface ErrorsI { const ErrorMessages: ErrorsI = { DEFAULT: "An error occurred. Please check your internet connection.", - EMAIL_EXISTS: - "Registration failed. Please check if you are already registered, otherwise contact support for more info", - INVALID_CREDENTIALS: "Login failed. Please, make sure you entered the right credentials.", + EMAIL_EXISTS: "Registration failed. This email is already registered. Please try to login", + INVALID_CREDENTIALS: "Login failed. Please, make sure you entered the right credentials", + USER_NOT_FOUND: "Login failed. Please, make sure you are already registered", }; +export const errorCodes = (message: string): number => + Number(message.slice(message.length - 3, message.length)); + export default ErrorMessages; diff --git a/frontend/next.config.js b/frontend/next.config.js index 5735f7b15..586a3ffd8 100644 --- a/frontend/next.config.js +++ b/frontend/next.config.js @@ -2,4 +2,7 @@ module.exports = { reactStrictMode: true, swcMinify: false, + experimental: { + outputStandalone: true, + }, }; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 623be1fd7..04d83c3a7 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -2829,6 +2829,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -2837,6 +2838,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -3479,6 +3481,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -3545,6 +3548,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", + "dev": true, "dependencies": { "string-width": "^4.2.0" }, @@ -3657,6 +3661,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -3664,7 +3669,8 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "node_modules/colorette": { "version": "2.0.16", @@ -3676,6 +3682,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, "optional": true, "engines": { "node": ">=0.1.90" @@ -4360,6 +4367,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, "engines": { "node": ">=0.8.0" } @@ -5763,7 +5771,8 @@ "node_modules/graceful-fs": { "version": "4.2.9", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true }, "node_modules/harmony-reflect": { "version": "1.6.2", @@ -5801,6 +5810,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, "engines": { "node": ">=4" } @@ -6029,6 +6039,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, "engines": { "node": ">=0.8.19" } @@ -6060,6 +6071,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, "engines": { "node": ">=10" } @@ -6346,7 +6358,8 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true }, "node_modules/is-unicode-supported": { "version": "0.1.0", @@ -6375,7 +6388,8 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "node_modules/isstream": { "version": "0.1.2", @@ -12926,6 +12940,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, "bin": { "semver": "bin/semver.js" } @@ -12968,7 +12983,8 @@ "node_modules/signal-exit": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true }, "node_modules/sisteransi": { "version": "1.0.5", @@ -13277,6 +13293,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -13289,12 +13306,14 @@ "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/string-width/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "engines": { "node": ">=8" } @@ -13348,6 +13367,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -13421,6 +13441,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -13518,7 +13539,8 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true }, "node_modules/throat": { "version": "6.0.1", @@ -13777,6 +13799,7 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, "dependencies": { "is-typedarray": "^1.0.0" } @@ -14071,6 +14094,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -14165,6 +14189,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -16425,12 +16450,14 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -16899,6 +16926,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -16950,6 +16978,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", + "dev": true, "requires": { "colors": "1.4.0", "string-width": "^4.2.0" @@ -17028,6 +17057,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "requires": { "color-name": "1.1.3" } @@ -17035,7 +17065,8 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "colorette": { "version": "2.0.16", @@ -17047,6 +17078,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, "optional": true }, "combined-stream": { @@ -17594,7 +17626,8 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, "escodegen": { "version": "2.0.0", @@ -18637,7 +18670,8 @@ "graceful-fs": { "version": "4.2.9", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true }, "harmony-reflect": { "version": "1.6.2", @@ -18668,7 +18702,8 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true }, "has-symbols": { "version": "1.0.2", @@ -18825,7 +18860,8 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true }, "indent-string": { "version": "4.0.0", @@ -18850,7 +18886,8 @@ "ini": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==" + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true }, "internal-slot": { "version": "1.0.3", @@ -19038,7 +19075,8 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true }, "is-unicode-supported": { "version": "0.1.0", @@ -19058,7 +19096,8 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "isstream": { "version": "0.1.2", @@ -23751,7 +23790,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true }, "shebang-command": { "version": "2.0.0", @@ -23782,7 +23822,8 @@ "signal-exit": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true }, "sisteransi": { "version": "1.0.5", @@ -24014,6 +24055,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -24023,12 +24065,14 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true } } }, @@ -24072,6 +24116,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -24114,6 +24159,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -24186,7 +24232,8 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true }, "throat": { "version": "6.0.1", @@ -24373,6 +24420,7 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, "requires": { "is-typedarray": "^1.0.0" } @@ -24608,6 +24656,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "requires": { "isexe": "^2.0.0" } @@ -24677,6 +24726,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, "requires": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", diff --git a/frontend/utils/fetchData.tsx b/frontend/utils/fetchData.tsx index c78b7fead..641efd113 100644 --- a/frontend/utils/fetchData.tsx +++ b/frontend/utils/fetchData.tsx @@ -1,6 +1,6 @@ import axios, { AxiosRequestConfig } from "axios"; import { getSession } from "next-auth/react"; -import { NEXT_PUBLIC_BACKEND_URL } from "./constants"; +import { BACKEND_URL, NEXT_PUBLIC_BACKEND_URL } from "./constants"; export const instance = axios.create({ baseURL: NEXT_PUBLIC_BACKEND_URL, @@ -9,7 +9,7 @@ export const instance = axios.create({ }, }); -const nonNeededToken = ["/auth/login", "/auth/refresh"]; +const nonNeededToken = ["/auth/login", "/auth/refresh", "/auth/registerAzure"]; instance.interceptors.request.use(async (config) => { const { url, headers } = config; @@ -22,14 +22,20 @@ instance.interceptors.request.use(async (config) => { return config; }); -export const fetchInstance = axios.create(); +export const serverSideInstance = axios.create({ + baseURL: BACKEND_URL, + headers: { + "Content-Type": "application/json", + }, +}); type Options = { token?: string; + serverSide?: boolean; } & AxiosRequestConfig; const fetchData = async (url: string, options?: Options): Promise => { - const { method = "GET", token } = options ?? {}; + const { method = "GET", token, serverSide } = options ?? {}; const instanceOptions: AxiosRequestConfig = { url, method, @@ -43,7 +49,9 @@ const fetchData = async (url: string, options?: Options): Promise => { }; } - const { data } = await instance(instanceOptions); + const { data } = !serverSide + ? await instance(instanceOptions) + : await serverSideInstance(instanceOptions); return data; };