Skip to content

Commit

Permalink
Type fix on server is complete
Browse files Browse the repository at this point in the history
  • Loading branch information
pinocchio-life-like committed Mar 7, 2024
1 parent a33f516 commit ca60968
Show file tree
Hide file tree
Showing 34 changed files with 283 additions and 89 deletions.
1 change: 1 addition & 0 deletions apps/expo/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ module.exports = {
ecmaVersion: 'latest',
sourceType: 'module',
project: './tsconfig.json',
tsconfigRootDir: __dirname,
},
plugins: ['react', 'react-native', '@typescript-eslint', 'prettier'],
rules: {
Expand Down
1 change: 1 addition & 0 deletions server/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ module.exports = {

parserOptions: {
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
},
},
],
Expand Down
2 changes: 2 additions & 0 deletions server/src/controllers/auth/updatePassword.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export const updatePassword = async (req, res, next) => {

if (!isMatch) throw new Error('Incorrect password');

if (!JWT_SECRET) throw new Error('JWT_SECRET is not defined');

const salt = await bcrypt.genSalt(parseInt(JWT_SECRET));

newPassword = await bcrypt.hash(newPassword, salt);
Expand Down
5 changes: 5 additions & 0 deletions server/src/controllers/favorite/getUserFavorites.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ export function getUserFavoritesRoute() {
.query(async (opts) => {
const { userId } = opts.input;
const user = await User.findById({ _id: userId }).populate('favorites');

if (!user) {
throw new Error('User not found');
}

return user.favorites;
});
}
4 changes: 4 additions & 0 deletions server/src/controllers/getOsm/getEnhancedPhotonDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ export const getEnhancedPhotonDetails = async (req, res, next) => {

const nominatimUrl = `https://nominatim.openstreetmap.org/lookup?format=json&osm_ids=${type[0]}${id}&addressdetails=1`;

if (!overpassUrl) {
throw new Error('OSM_URI is not defined');
}

const overpassPromise = axios.post(overpassUrl, overpassQuery, {
headers: { 'Content-Type': 'text/plain' },
});
Expand Down
15 changes: 15 additions & 0 deletions server/src/controllers/passwordReset/handlePasswordReset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@ import { responseHandler } from '../../helpers/responseHandler';
import { z } from 'zod';
import { publicProcedure } from '../../trpc';

if (!SEND_GRID_API_KEY) {
throw new Error('SEND_GRID_API_KEY is not defined');
}

sgMail.setApiKey(SEND_GRID_API_KEY);

// Verify a password reset token and return the user's email address
const verifyPasswordResetToken = (token) => {
if (!JWT_SECRET) {
throw new Error('JWT_SECRET is not defined');
}
const secret = JWT_SECRET;
try {
const decoded: any = jwt.verify(token, secret);
Expand All @@ -35,6 +42,10 @@ export const handlePasswordReset = async (req, res) => {
throw new Error('No user found with this email address');
}

if (!user.passwordResetTokenExpiration) {
throw new Error('Password reset token expiration is not defined');
}

if (Date.now() > user.passwordResetTokenExpiration.getTime()) {
throw new Error('Password reset token has expired');
}
Expand Down Expand Up @@ -70,6 +81,10 @@ export function handlePasswordResetRoute() {
return { error: 'No user found with this email address' };
}

if (!user.passwordResetTokenExpiration) {
throw new Error('Password reset token expiration is not defined');
}

if (Date.now() > user.passwordResetTokenExpiration.getTime()) {
return { error: 'Password reset token has expired' };
}
Expand Down
19 changes: 18 additions & 1 deletion server/src/controllers/passwordReset/requestPasswordReset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,30 @@ import { responseHandler } from '../../helpers/responseHandler';
import { publicProcedure } from '../../trpc';
import * as validator from '../../middleware/validators/index';
import { z } from 'zod';

if (!SEND_GRID_API_KEY) {
throw new Error('SEND_GRID_API_KEY is not defined');
}

sgMail.setApiKey(SEND_GRID_API_KEY);

// Generate a password reset token that includes the user's email address
const generatePasswordResetToken = (email) => {
if (!JWT_SECRET) {
throw new Error('JWT_SECRET is not defined');
}

const payload = { email };
const secret = JWT_SECRET;
const expiresIn = '1h';
return jwt.sign(payload, secret, { expiresIn });
};

const sendPasswordResetEmail = async (email, resetUrl) => {
if (!STMP_EMAIL) {
throw new Error('STMP_EMAIL is not defined');
}

const mailOptions = {
to: email,
from: {
Expand Down Expand Up @@ -75,6 +88,10 @@ export const requestPasswordResetEmailAndToken = async (req, res) => {
},
);

if (!CLIENT_URL) {
throw new Error('CLIENT_URL is not defined');
}

const resetUrl = `${CLIENT_URL}/password-reset?token=${resetToken}`;
await sendPasswordResetEmail(email, resetUrl);

Expand Down Expand Up @@ -109,7 +126,7 @@ export function requestPasswordResetEmailAndTokenRoute() {
//* returning resetToken for Test environment
return {
message: 'Password reset email sent successfully',
resetToken: (process.env.NODE_ENV = 'test' && resetToken),
resetToken: process.env.NODE_ENV === 'test' && resetToken,
};
});
}
Expand Down
19 changes: 17 additions & 2 deletions server/src/controllers/user/googleSignin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ import {
import utilsService from '../../utils/utils.service';
import { UserAlreadyExistsError } from '../../helpers/errors';

interface GoogleUserInfo {
id?: string | null;
email?: string | null;
name?: string | null;
}

interface AlreadySigninInfo {
googleId?: string | null;
email?: string | null;
name?: string | null;
password?: any;
generateAuthToken?: any;
token: any;
}

const oauth2Client = new google.auth.OAuth2(
GOOGLE_CLIENT_ID,
GOOGLE_CLIENT_SECRET,
Expand All @@ -36,9 +51,9 @@ const getGoogleUserInfo = async (code) => {
export const googleSignin = async (req, res, next) => {
try {
const code = req.query.code;
const userInfo = await getGoogleUserInfo(code);
const userInfo: GoogleUserInfo = await getGoogleUserInfo(code);

const alreadyGoogleSignin = await User.findOne({
const alreadyGoogleSignin: AlreadySigninInfo | null = await User.findOne({
email: userInfo.email,
name: userInfo.name,
password: utilsService.randomPasswordGenerator(8),
Expand Down
6 changes: 6 additions & 0 deletions server/src/controllers/user/userSignUp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import * as validator from '../../middleware/validators/index';
export const userSignup = async (req, res) => {
const { email } = req.body;
await (User as any).alreadyLogin(email);
if (!JWT_SECRET) {
throw new Error('JWT_SECRET is not defined');
}
const salt = await bcrypt.genSalt(parseInt(JWT_SECRET));
req.body.password = await bcrypt.hash(req.body.password, salt);
const user = new User(req.body);
Expand All @@ -26,6 +29,9 @@ export function signUpRoute() {
return publicProcedure.input(validator.userSignUp).mutation(async (opts) => {
const { email, password } = opts.input;
await (User as any).alreadyLogin(email);
if (!JWT_SECRET) {
throw new Error('JWT_SECRET is not defined');
}
const salt = await bcrypt.genSalt(parseInt(JWT_SECRET));
opts.input.password = await bcrypt.hash(password, salt);
const user = new User(opts.input);
Expand Down
4 changes: 4 additions & 0 deletions server/src/helpers/buildMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ export function buildMessage(
if (options.customMessage) return options.customMessage;

const entityConfig = ENTITIES[entityKey];
if (!entityConfig) {
throw new Error(`No entity configuration found for key "${entityKey}"`);
}

const baseEntity = options.isPlural
? entityConfig.plural
: entityConfig.singular;
Expand Down
7 changes: 6 additions & 1 deletion server/src/models/osm/relationModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ RelationSchema.method('toJSON', async function () {
// object.id = _id.toString();
// Asynchronously populate the members (you may need to add your own logic to populate based on type)
for (const member of object.members) {
member.refId = await mongoose.model(member.type).findById(member.refId);
if (member.type) {
const refId = await mongoose.model(member.type).findById(member.refId);
if (refId) {
member.refId = refId;
}
}
}
return object;
});
Expand Down
7 changes: 5 additions & 2 deletions server/src/models/userModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,11 @@ UserSchema.pre<IUser>('save', async function (next) {
generatedUsername = `${generatedUsername}${counter}`;
counter++;
}

user.username = generatedUsername;
if (generatedUsername) {
user.username = generatedUsername;
} else {
throw new Error('generatedUsername is not defined');
}
}

next();
Expand Down
13 changes: 10 additions & 3 deletions server/src/services/favorite/getUserFavoritesService.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import User from '../../models/userModel';
import Pack from '../../models/packModel';
import type { Document as MongooseDocument } from 'mongoose';
import type { ObjectId } from 'mongodb';
import { UserNotFoundError } from '../../helpers/errors';

type UserType = MongooseDocument & {
favorites: ObjectId[];
};

export const getUserFavoritesService = async (userId, next) => {
const user = await User.findById({ _id: userId }).populate('favorites');
const user: UserType | null = await User.findById({ _id: userId }).populate(
'favorites',
);
if (!user) next(UserNotFoundError);
return user.favorites;
return user?.favorites;
};
20 changes: 16 additions & 4 deletions server/src/services/item/addGlobalItemToPackService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import Item from '../../models/itemModel';
import Pack from '../../models/packModel';

import type { Document as MongooseDocument } from 'mongoose';
import type { ObjectId } from 'mongodb';

/**
* Adds a global item to the pack service.
*
Expand All @@ -9,13 +12,22 @@ import Pack from '../../models/packModel';
* @param {string} ownerId - The ID of the owner.
* @return {Promise<object>} - A promise that resolves to the added item.
*/

type ItemType = MongooseDocument & {
name: string;
category?: ObjectId;
};

export const addGlobalItemToPackService = async (packId, itemId, ownerId) => {
const item = await Item.findById(itemId).populate('category', 'name');
const item: ItemType | null = await Item.findById(itemId).populate(

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query object depends on a
user-provided value
.
'category',
'name',
);

await Pack.updateOne({ _id: packId }, { $addToSet: { items: item._id } });
await Pack.updateOne({ _id: packId }, { $addToSet: { items: item?._id } });

await Item.findByIdAndUpdate(
item._id,
item?._id,
{
$addToSet: {
owners: ownerId,
Expand All @@ -25,7 +37,7 @@ export const addGlobalItemToPackService = async (packId, itemId, ownerId) => {
);

await Item.findByIdAndUpdate(
item._id,
item?._id,
{
$addToSet: {
packs: packId,
Expand Down
34 changes: 26 additions & 8 deletions server/src/services/item/addItemGlobalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import Item from '../../models/itemModel';
import Pack from '../../models/packModel';
import { ItemCategoryModel } from '../../models/itemCategory';
import { ItemCategoryEnum } from '../../utils/itemCategory';

import type { Document as MongooseDocument } from 'mongoose';
import type { ObjectId } from 'mongodb';
/**
* Adds an item to the global service.
*
Expand All @@ -13,15 +14,32 @@ import { ItemCategoryEnum } from '../../utils/itemCategory';
* @param {string} type - The category of the item.
* @return {Promise<Object>} The newly created item.
*/

type ItemType = MongooseDocument & {
createdAt: Date;
updatedAt: Date;
weight: number;
name: string;
quantity: number;
unit: string;
global: boolean;
category?: ObjectId;
};

type CategoryType = MongooseDocument & {
name: string;
_id: ObjectId;
};

export const addItemGlobalService = async (
name,
weight,
quantity,
unit,
type,
) => {
let category = null;
let newItem = null;
let category: CategoryType | null = null;
let newItem: ItemType | null = null;

switch (type) {
case ItemCategoryEnum.FOOD: {
Expand All @@ -34,11 +52,11 @@ export const addItemGlobalService = async (
weight,
quantity,
unit,
category: category._id,
category: category?._id,
global: true,
});

newItem = await Item.findById(newItem.id).populate('category', 'name');
newItem = await Item.findById(newItem?.id).populate('category', 'name');

break;
}
Expand All @@ -52,11 +70,11 @@ export const addItemGlobalService = async (
weight,
quantity: 1,
unit,
category: category._id,
category: category?._id,
global: true,
});

newItem = await Item.findById(newItem.id).populate('category', 'name');
newItem = await Item.findById(newItem?.id).populate('category', 'name');

break;
}
Expand All @@ -70,7 +88,7 @@ export const addItemGlobalService = async (
weight,
quantity,
unit,
category: category._id,
category: category?._id,
global: true,
});

Expand Down
Loading

0 comments on commit ca60968

Please sign in to comment.