Clean UserController and Database 🎨

pull/19/head
Emre KARTAL 2 years ago
parent ee937b8c3e
commit ca8d8a2bd0

@ -21,6 +21,7 @@ DerivedData
*.xcuserstate
project.xcworkspace
**/.xcode.env.local
**/src/config.ts
# Gradle
/build/

@ -26,9 +26,11 @@
"@types/mongoose": "^5.11.97",
"axios": "^1.2.6",
"bcrypt": "^5.1.0",
"build": "^0.1.4",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"joi": "^17.8.1",
"jsonwebtoken": "^9.0.0",
"mongoose": "^6.9.0"

@ -1,67 +1,55 @@
import express, { Application } from 'express';
import cors from 'cors';
import { MONGO_PASSWORD } from './config';
import cookieParser from 'cookie-parser';
import bodyParser from 'body-parser';
import Controller from './controller/interfaces/IController';
import Controller from './controllers/interfaces/IController';
import mongoose from 'mongoose';
class App {
public express: Application;
public port: number;
public dataBase: null;
public server: any;
constructor(controllers: Controller[], port: number) {
this.express = express();
this.port = port;
this.dataBase = null;
this.initialiseDatabase();
this.initialiseMiddleware();
this.initialiseControllers(controllers);
this.initDatabase();
this.initMiddleware();
this.initControllers(controllers);
}
private initialiseMiddleware(): void {
private initMiddleware(): void {
this.express.use(cors());
this.express.use(cookieParser());
this.express.use(express.json());
this.express.use(express.urlencoded({ extended: false }));
this.express.use(bodyParser.json());
this.express.use(bodyParser.urlencoded({
extended: true
}));
}
private initialiseControllers(controllers: Controller[]): void {
private initControllers(controllers: Controller[]): void {
controllers.forEach((controller: Controller) => {
this.express.use('/api', controller.router);
this.express.get('/toto', (req, res) => {
res.send('Hello World!');
})
});
}
public listen(): void {
const server = this.express.listen(this.port, () => {
this.express.listen(this.port, () => {
console.log(`[server] : App listening on the port ${this.port}`);
});
}
private initialiseDatabase(): void {
const MONGO_URL = "mongodb+srv://fladDevDb:ZslYlNRWIOUU7i6o@fladcluster.b29tytu.mongodb.net/?retryWrites=true&w=majority"
private initDatabase(): void {
const MONGO_URL = `mongodb+srv://FladDev:${MONGO_PASSWORD}@flad.mliekr2.mongodb.net/?retryWrites=true&w=majority`;
mongoose.connect(MONGO_URL)
.then(() => console.log("Connect to MongoDB database successfully"))
.catch(error => console.log("Error connecting : " + error));
}
}
export default App;

@ -1,24 +1,22 @@
import Controller from './interfaces/IController';
import IController from './interfaces/IController';
import { Router, Request, Response, NextFunction } from 'express';
import HttpException from '../exception/HttpException';
import axios from 'axios';
import qs from 'qs';
class SpotifyController implements Controller {
class SpotifyController implements IController {
public path = '/spotify';
public router = Router();
constructor() {
console.log("useeeee");
this.initialiseRoutes();
}
initialiseRoutes() {
this.router.get(`${this.path}/exchange`,this.login);
this.router.get(`${this.path}/callback`,this.getAccessToken);
this.router.get(`${this.path}/refresh`,this.getRefreshToken);
this.router.get(`${this.path}/spot`, this.getSpot);
}

@ -1,254 +0,0 @@
import { Router, Request, Response, NextFunction, RequestHandler } from 'express';
import Controller from './interfaces/IController';
import HttpException from '../exception/HttpException';
// import LocationService from '../../service/LocationService';
import IUser from '../models/User';
import UserService from '../services/UserService';
import validator from '../database/User/UserValidation'
import validationMiddleware from '../middlewares/validation/ValidatorMiddleware';
import authenticator from '../middlewares/authMiddleware'
import LocationService from '../services/LocationService';
class UserController implements Controller {
public path = '/users';
public router = Router();
private userService = new UserService();
private locationService = new LocationService();
constructor() {
this.initialiseRoutes();
}
private initialiseRoutes(): void {
this.router.post(
`${this.path}/register`,
validationMiddleware(validator.register),
this.register
);
this.router.post(
`${this.path}/login`,
validationMiddleware(validator.login),
this.login
);
this.router.get(`${this.path}`, authenticator, this.getUser);
this.router.get(`${this.path}/nextTo`, authenticator, this.getUserNext);
// //create
// this.router.post(`${this.path}`,this.createUser);
// // // get One
// this.router.get (`${this.path}/:userId`, this.getUserById);
// // // get All
// this.router.get (`${this.path}`, this.getAllUsers);
// //update One
// this.router.put (`${this.path}/:userId`, this.updateUser);
// //Delete One
// this.router.delete (`${this.path}/:userId`, this.deleteUser);
}
// private createUser = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// console.log(req.body);
// const reqBody:CreateTaskReqBody = Object.assign({}, req.body);
// checkIfIsValidCreateTaskReqBody(reqBody);
// await this.userService.createUserById(reqBody.fin
// );
// res.status(200).send({ status: "Success", msg: "Success add" });
// } catch (error) {
// next(new HttpException(400, 'Cannot create post'));
// }
// };
// private readonly getUserById: RequestHandler = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// const id = req.params.taskId;
// const userId = req.params.userId;
// const data = await this.userService.getUserById(id, userId);
// res.status(201).send(data);
// }
// catch(error){
// next(new HttpException(400, 'Cannot create post'));
// }
// }
// private readonly getAllUsers: RequestHandler = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// const userId = req.params.userId;
// const tasks = await this.userService.getUsers(userId);
// const responseList = tasks.map(task => new TaskResumedRes(task));
// res.status(201).send(responseList);
// }
// catch(error){
// next(new HttpException(400, 'Cannot get user task'));
// }
// }
// private deleteUser = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// const id = req.params.taskId;
// const userId = req.params.userId;
// await this.userService.DeleteUser(id, userId);
// return res.status(200).send({ status: "Success", msg: "Data Removed" });
// } catch (error) {
// next(new HttpException(400, 'Cannot create post'));
// }
// };
// private updateUser = async (
// req: Request,
// res: Response,
// next: NextFunction
// ): Promise<Response | void> => {
// try {
// const taskId = req.params.taskId;
// const userId = req.params.userId;
// const reqBody:CreateTaskReqBody = Object.assign({}, req.body);
// const updatedTask = await this.userService.UpdateTask(
// // req.auth!.uid,
// taskId,
// userId,
// // firebase.auth().currentUser.getIdToken()
// reqBody.nom,
// reqBody.description,
// reqBody.logo,
// reqBody.duration,
// reqBody.done,
// // reqBody.tags,
// reqBody.repepat,
// reqBody.deb,
// reqBody.fin
// );
// // res.send('Success add');
// // res.status(201).json({ task });
// res.status(204).send(`Update a new contact: ${updatedTask}`);
// } catch (error) {
// console.log(error);
// next(new HttpException(403, 'Cannot create post'));
// }
// };
private register = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
try {
// the FladId should be created by the Userservice
const { name, email, password , idFlad, idSpotify } = req.body;
console.log(name, email, password, idFlad, idSpotify);
const token = await this.userService.register(
name,
email,
password,
idFlad,
idSpotify
);
res.status(201).json({ token });
} catch (error : any) {
next(new HttpException(400, error.message));
}
};
private login = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
try {
const { email, password } = req.body;
const token = await this.userService.login(email, password);
res.status(200).json({ token });
} catch (error : any) {
next(new HttpException(400, error.message));
}
};
private getUser = (
req: Request,
res: Response,
next: NextFunction
): Response | void => {
if (!req.user) {
return next(new HttpException(404, 'No logged in user'));
}
res.status(200).send({ data: req.user });
};
private getUserNext = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
try {
const longitude = Number(req.query.longitude);
const latitude = Number(req.query.latitude);
//verify::val_int(){
console.log('woooooooooooooo' + req);
if (isNaN(longitude) || isNaN(latitude)) {
console.log('============' + longitude)
console.log('============' + latitude)
console.log('Impossible de convertir la chaîne en nombre');
}
//}
const userId = req.user.idFlad;
const musicId = String(req.query.currentMusic);
console.log('============' + longitude)
console.log('============' + latitude)
console.log('daaaaaaaaaaaaaaaaaaaaaa' + musicId);
const data = await this.locationService.getNearUser(userId,musicId,latitude,longitude);
console.log(data);
res.status(201).send(data);
}
catch(error : any){
next(new HttpException(400, 'Cannot create get netUser'));
}
}
}
export default UserController;
declare global {
namespace Express {
export interface Request {
user: IUser;
}
}
}

@ -0,0 +1,111 @@
import { Router, Request, Response, NextFunction, RequestHandler } from 'express';
import IController from './interfaces/IController';
import HttpException from '../exception/HttpException';
import User from '../models/User';
import UserService from '../services/UserService';
import validator from '../middlewares/UserValidation'
import validationMiddleware from '../middlewares/validationMiddleware';
import authenticator from '../middlewares/authMiddleware'
import LocationService from '../services/LocationService';
class UserController implements IController {
public path = '/users';
public router = Router();
private userService = new UserService();
private locationService = new LocationService();
constructor() {
this.initRoutes();
}
private initRoutes(): void {
this.router.post(
`${this.path}/register`,
validationMiddleware(validator.register),
this.register
);
this.router.post(
`${this.path}/login`,
validationMiddleware(validator.login),
this.login
);
this.router.get(`${this.path}`, authenticator, this.getUser);
this.router.get(`${this.path}/nextTo`, authenticator, this.getUserNext);
}
private register = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
try {
const { name, email, password, idSpotify } = req.body;
const token = await this.userService.register(
name,
email,
password,
idSpotify
);
res.status(201).json({ token });
} catch (error: any) {
next(new HttpException(400, error.message));
}
};
private login = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
try {
const { email, password } = req.body;
const token = await this.userService.login(email, password);
res.status(200).json({ token });
} catch (error: any) {
next(new HttpException(400, error.message));
}
};
private getUser = (
req: Request,
res: Response,
next: NextFunction
): Response | void => {
if (!req.user) {
return next(new HttpException(404, 'No logged in user'));
}
res.status(200).send({ data: req.user });
};
private getUserNext = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> => {
try {
const longitude = Number(req.query.longitude);
const latitude = Number(req.query.latitude);
if (isNaN(longitude) || isNaN(latitude)) {
console.log('Unable to convert string to number');
throw new Error('Unable to convert string to number');
}
const userId = req.user.id;
const musicId = String(req.query.currentMusic);
const data = await this.locationService.getNearUser(userId, musicId, latitude, longitude);
res.status(201).send(data);
}
catch (error: any) {
next(new HttpException(400, 'Cannot create get netUser: ' + error.message));
}
}
}
export default UserController;
declare global {
namespace Express {
export interface Request {
user: User;
}
}
}

@ -1,8 +0,0 @@
import { Schema } from 'mongoose';
interface IToken extends Object {
id: Schema.Types.ObjectId;
expiresIn: number;
}
export default IToken;

@ -1,8 +1,8 @@
import { Schema, model, Document } from 'mongoose';
import { Schema, model } from 'mongoose';
import { Location } from '../models/Location';
const locationSchema = new Schema({
idFlad: {
userId: {
type: String,
required: true,
unique: true,
@ -18,18 +18,9 @@ const locationSchema = new Schema({
longitude: {
type: Number,
required: true,
},
}
},
{ timestamps: true }
);
export default model<ILocation>('Location', locationSchema);
export interface ILocation extends Document {
idFlad: string;
musicId: string;
latitude: number;
longitude: number;
}
export default model<Location>('Location', locationSchema);

@ -1,8 +0,0 @@
import { Schema, model } from 'mongoose';
const notificationSchema = new Schema({
type: {type: String, required: true},
content: {type: String, required: true}
});
export default {Notification: model("nofitication", notificationSchema)}

@ -1,13 +1,8 @@
import IUser from "../models/User";
import User from "../models/User";
import { Schema, model } from 'mongoose';
import bcrypt from 'bcrypt';
const userSchema = new Schema({
idFlad: {
type: String,
required: true,
unique: true
},
idSpotify: {
type: String,
required: true,
@ -32,11 +27,10 @@ const userSchema = new Schema({
{ timestamps: true }
);
userSchema.pre<IUser>('save', async function (next) {
userSchema.pre<User>('save', async function (next) {
if (!this.isModified('password')) {
return next();
}
const hash = await bcrypt.hash(this.password, 8);
this.password = hash;
next();
@ -48,4 +42,4 @@ userSchema.methods.isValidPassword = async function (
return await bcrypt.compare(password, this.password);
};
export default model<IUser>('User', userSchema);
export default model<User>('User', userSchema);

@ -1,6 +1,6 @@
import App from "./app";
import SpotifyController from "./controller/spotify.controller";
import UserController from "./controller/user.controller";
import SpotifyController from "./controllers/spotifyController";
import UserController from "./controllers/userController";
import dotenv from 'dotenv'
dotenv.config();

@ -2,13 +2,9 @@ import Joi from 'joi';
const register = Joi.object({
name: Joi.string().max(30).required(),
email: Joi.string().email().required(),
password: Joi.string().min(6).required(),
// can add an field like confimPassword and cheked that the password is equal to the confirmPassword
idSpotify: Joi.string(),
idFlad : Joi.string(),
});
const login = Joi.object({

@ -1,11 +1,11 @@
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import IToken from '../database/IToken';
import Token from '../models/Token';
import UserSchema from '../database/UserSchema';
import token from '../models/Token';
import token from '../services/TokenService';
import HttpException from '../exception/HttpException';
async function authenticatedMiddleware(
async function authMiddleware(
req: Request,
res: Response,
next: NextFunction
@ -13,17 +13,17 @@ async function authenticatedMiddleware(
const bearer = req.headers.authorization;
if (!bearer || !bearer.startsWith('Bearer ')) {
return next(new HttpException(401, 'Unauthorised'));
return next(new HttpException(401, 'Unauthorized'));
}
const accessToken = bearer.split('Bearer')[1].trim();
try {
const payload: IToken | jwt.JsonWebTokenError = await token.verifyToken(
const payload: Token | jwt.JsonWebTokenError = await token.verifyToken(
accessToken
);
if (payload instanceof jwt.JsonWebTokenError) {
return next(new HttpException(401, 'Unauthorised'));
return next(new HttpException(401, 'Unauthorized'));
}
const user = await UserSchema.findById(payload.id)
@ -31,15 +31,15 @@ async function authenticatedMiddleware(
.exec();
if (!user) {
return next(new HttpException(401, 'Unauthorised'));
return next(new HttpException(401, 'Unauthorized'));
}
req.user = user;
return next();
} catch (error) {
return next(new HttpException(401, 'Unauthorised'));
return next(new HttpException(401, 'Unauthorized'));
}
}
export default authenticatedMiddleware;
export default authMiddleware;

@ -1,59 +1,21 @@
export interface Position {
/**
* Creation timestamp for coords
*/
timestamp: number;
/**
* The GPS coordinates along with the accuracy of the data
*/
coords: {
/**
* Latitude in decimal degrees
*/
latitude: number;
/**
* longitude in decimal degrees
*/
longitude: number;
};
}
export class PlacePosition implements Position {
timestamp: number;
coords: {
latitude: number;
longitude: number;
};
constructor(timestamp: number,latitude : number ,longitude: number){
this.timestamp = timestamp;
this.coords = {latitude, longitude};
}
}
import { Document } from 'mongoose';
export class UserLocation {
uuid: string;
userId: string;
musicId : string;
latitude : number;
longitude: number;
musicId : string;
constructor(uuid: string, musicId : string,latitude: number, longitude: number){
this.uuid = uuid;
constructor(userId: string, musicId : string,latitude: number, longitude: number){
this.userId = userId;
this.musicId = musicId;
this.latitude = latitude;
this.longitude = longitude;
}
}
export class Place{
position: Position;
address: Address;
constructor(address: Address,position: Position){
this.position = position;
this.address = address;
}
}
export type Address = {
street : string;
city : string;
state : string;
zip : string;
export class Location extends Document {
userId: string;
musicId: string;
latitude: number;
longitude: number;
}

@ -1,27 +1,6 @@
import jwt from 'jsonwebtoken';
import IUser from './User';
import IToken from '../database/IToken';
import { Schema } from 'mongoose';
export const createToken = (user: IUser): string => {
return jwt.sign({ id: user._id }, "foo" as jwt.Secret, {
expiresIn: '100d',
});
};
export const verifyToken = async (
token: string
): Promise<jwt.VerifyErrors | IToken> => {
return new Promise((resolve, reject) => {
jwt.verify(
token,
"foo" as jwt.Secret,
(err, payload) => {
if (err) return reject(err);
resolve(payload as IToken);
}
);
});
};
export default { createToken, verifyToken };
export default interface Token extends Object {
id: Schema.Types.ObjectId;
expiresIn: number;
}

@ -1,6 +1,6 @@
import { Document } from 'mongoose';
export default interface IUserModel extends Document {
export default interface User extends Document {
email: string;
name: string;
password: string;

@ -1,94 +1,44 @@
// import db from '../database';
import { Place, PlacePosition, Position, UserLocation } from '../models/Location';
import axios from 'axios';
import { UserLocation } from '../models/Location';
import LocationSchema from "../database/LocationSchema";
class LocationService {
private locationCollection = LocationSchema;
// private API_KEY : string = "AIzaSyBFCEAtmhZ8jvw84UTQvX3Aqpr66GVqB_A";
public async getNearUser(idFlad : string, musicId : string,latitude : number, longitude : number)
{
await this.locationCollection.findOneAndUpdate(
{ idFlad },
{ idFlad, musicId, latitude, longitude },
private locations = LocationSchema;
public async getNearUser(userId: string, musicId: string, latitude: number, longitude: number) {
await this.locations.findOneAndUpdate(
{ userId },
{ userId, musicId, latitude, longitude },
{ upsert: true }
);
const snapshot = await this.locationCollection.find({ idFlad: { $ne: idFlad } });
if (snapshot.length === 0) {
const snapshot = await this.locations.find({ userId: { $ne: userId } });
if (!snapshot.length) {
console.log('No matching documents.');
return;
}
let dbUsersList:UserLocation[] = [];
let usersLocation: UserLocation[] = [];
snapshot.forEach(doc => {
dbUsersList.push(new UserLocation(doc.idFlad,doc.musicId,doc.latitude,doc.longitude));
console.log(doc.idFlad, '=>', doc);
usersLocation.push(new UserLocation(doc.userId, doc.musicId, doc.latitude, doc.longitude));
});
// missing the curent music
let listUser: string[] = [];
const listUser2: Record<string, string> = {};
dbUsersList.forEach(user => {
console.log(user);
const dist = this.distanceBetween(latitude , longitude , user.latitude, user.longitude);
console.log(user.uuid,dist);
if (dist <= 100) {
listUser.push(user.uuid);
listUser2[user.uuid] = user.musicId;
const listUser: Record<string, string> = {};
usersLocation.forEach(user => {
const distance = this.distanceBetween(latitude, longitude, user.latitude, user.longitude);
if (distance <= 100) {
listUser[user.userId] = user.musicId;
}
});
return{ listUser, listUser2};
// $listUser[] = {userID,idMusic};
return { listUser };
}
public getCenter (points: Position[]) {
if (Array.isArray(points) === false || points.length === 0) {
return false;
}
const numberOfPoints = points.length;
const sum = points.reduce(
(acc, point) => {
const pointLat = this.toRad(point.coords.latitude);
const pointLon = this.toRad(point.coords.longitude);
return {
X: acc.X + Math.cos(pointLat) * Math.cos(pointLon),
Y: acc.Y + Math.cos(pointLat) * Math.sin(pointLon),
Z: acc.Z + Math.sin(pointLat),
};
},
{ X: 0, Y: 0, Z: 0 }
);
const X = sum.X / numberOfPoints;
const Y = sum.Y / numberOfPoints;
const Z = sum.Z / numberOfPoints;
return {
longitude: this.toDeg(Math.atan2(Y, X)),
latitude: this.toDeg(Math.atan2(Z, Math.sqrt(X * X + Y * Y))),
};
};
public toRad = (value: number) => (value * Math.PI) / 180;
public toDeg = (value: number) => (value * 180) / Math.PI;
// sa c'est un utils du coup mettre dans une calss utils
// resulta en km
private distanceBetween (lat1 : number, lon1 : number, lat2: number, lon2 : number) : number {
private distanceBetween(lat1: number, lon1: number, lat2: number, lon2: number): number {
if ((lat1 == lat2) && (lon1 == lon2)) {
return 0;
}
else {
var radlat1 = Math.PI * lat1/180;
var radlat2 = Math.PI * lat2/180;
var theta = lon1-lon2;
var radtheta = Math.PI * theta/180;
var radlat1 = Math.PI * lat1 / 180;
var radlat2 = Math.PI * lat2 / 180;
var theta = lon1 - lon2;
var radtheta = Math.PI * theta / 180;
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
if (dist > 1) {
@ -96,44 +46,13 @@ class LocationService {
}
dist = Math.acos(dist);
dist = dist * 180/Math.PI;
dist = dist * 180 / Math.PI;
dist = dist * 60 * 1.1515;
dist = dist * 1.609344;
return dist;
}
}
private distanceBetweenPosition(first : Position, second : Position) : number {
return this.distanceBetween (first.coords.latitude, first.coords.longitude, second.coords.latitude, second.coords.longitude)
}
// give a array of position sorted by distance and return the first
private findNearest(main : Position, list : Position[]){
const nearest = this.orderByDistance(main, list)[0]
return nearest;
}
//distanceFn: DistanceFn = getDistance est param sa serrait cool de lui passer un fonction
private orderByDistance (mainPos: Position,coords: Position[]){
return coords
.slice()
.sort((a, b) => this.distanceBetweenPosition(mainPos, a) - this.distanceBetweenPosition(mainPos, b));
};
// getCenter(coords)
}
export default LocationService;

@ -0,0 +1,26 @@
import jwt from 'jsonwebtoken';
import User from '../models/User';
import Token from '../models/Token';
export const createToken = (user: User): string => {
return jwt.sign({ id: user._id }, "dave" as jwt.Secret, {
expiresIn: '1d',
});
};
export const verifyToken = async (
token: string
): Promise<jwt.VerifyErrors | Token> => {
return new Promise((resolve, reject) => {
jwt.verify(
token,
"dave" as jwt.Secret,
(err, payload) => {
if (err) return reject(err);
resolve(payload as Token);
}
);
});
};
export default { createToken, verifyToken };

@ -1,5 +1,5 @@
import UserSchema from "../database/UserSchema";
import token from "../models/Token";
import token from "./TokenService";
class UserService {
private user = UserSchema;
@ -8,7 +8,6 @@ class UserService {
name: string,
email: string,
password: string,
idFlad: string,
idSpotify: string
): Promise<string | Error> {
try {
@ -16,43 +15,27 @@ class UserService {
name,
email,
password,
idFlad,
idSpotify
});
const accessToken = token.createToken(user);
return accessToken;
return token.createToken(user);
} catch (error: any) {
throw new Error(error.message);
}
}
/**
* Attempt to login a user
*/
public async login(
email: string,
password: string
): Promise<string | Error> {
try {
// should maybe creat a method base on id and other information for better security
// need to view with Emre
const user = await this.user.findOne({ email });
// const user = await this.user.findById(idFlad);
if (!user) {
throw new Error('Unable to find user with that email address');
throw new Error('Wrong credentials given');
}
if (await user.isValidPassword(password)) {
return token.createToken(user);
} else {
throw new Error('Wrong credentials given');
}
} catch (error) {
throw new Error('Unable to create user');
}
}
}

Loading…
Cancel
Save