Skip to content

Commit cb42dfb

Browse files
committed
changed code according to eslint
1 parent dbbf103 commit cb42dfb

File tree

9 files changed

+104
-94
lines changed

9 files changed

+104
-94
lines changed

server/src/db/index.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import { createConnection } from "typeorm";
1+
import { createConnection } from 'typeorm';
22

3-
export default async function establishConnection() {
3+
export default async function establishConnection(): Promise<void> {
44
let reconnectionCount = 0;
5-
const establishDbConnection = async () => {
5+
const establishDbConnection = async (): Promise<void> => {
66
if (reconnectionCount > 5) {
7-
console.log("Failed connection to db after 5 total attempts.");
7+
console.log('Failed connection to db after 5 total attempts.');
88
return;
99
}
1010
try {
1111
await createConnection();
12-
console.log("Established Typeorm connection to postgres");
12+
console.log('Established Typeorm connection to postgres');
1313
} catch (err) {
1414
console.log(
1515
`Failed connecting to db. attempts left:${5 - reconnectionCount}`

server/src/entity/User/User.ts

+27-28
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { Entity, PrimaryGeneratedColumn, Column, BaseEntity } from "typeorm";
2-
import isValidEmail from "../../helpers/is-valid-email";
3-
import { ObjectType, Field, Int } from "type-graphql";
1+
import { Entity, PrimaryGeneratedColumn, Column, BaseEntity } from 'typeorm';
2+
import isValidEmail from '../../helpers/is-valid-email';
3+
import { ObjectType, Field, Int } from 'type-graphql';
44

55
@ObjectType() // for gql
6-
@Entity("users")
6+
@Entity('users')
77
export class User extends BaseEntity {
88
@Field(() => Int) // for gql
99
@PrimaryGeneratedColumn()
@@ -16,14 +16,14 @@ export class User extends BaseEntity {
1616
lastName?: string;
1717

1818
@Field()
19-
@Column("text")
19+
@Column('text')
2020
email: string;
2121

2222
@Field()
23-
@Column("text", { nullable: true })
23+
@Column('text', { nullable: true })
2424
username?: string;
2525

26-
@Column("text")
26+
@Column('text')
2727
password: string;
2828

2929
constructor(email: string, password: string, username?: string) {
@@ -34,45 +34,44 @@ export class User extends BaseEntity {
3434
}
3535
}
3636

37-
export function validateUser(userInfo: User): Promise<User> {
38-
return new Promise(async (resolve, reject) => {
37+
export function validateUser(
38+
userInfo: User
39+
): Promise<User | Record<string, unknown>> {
40+
return new Promise((resolve, reject) => {
3941
const { password, email } = userInfo;
4042
if (!password || !email) {
41-
reject({ emailOrPassword: "Email and password required." });
43+
reject({ emailOrPassword: 'Email and password required.' });
4244
}
4345

44-
let validPassword;
45-
try {
46-
validPassword = await validatePassword(password);
47-
} catch (err) {
48-
// err is of format {field: "errorMsg"}
49-
return reject(err);
50-
}
51-
let validEmail;
52-
try {
53-
validEmail = await validateEmail(email);
54-
} catch (err) {
55-
return reject(err);
56-
}
46+
(async () => {
47+
// dont use async as promise executor, e.g. async (resolve, reject) => ...
48+
await validatePassword(password).catch((err) => reject(err));
49+
50+
await validateEmail(email).catch((err) => reject(err));
51+
})();
5752

5853
return resolve(userInfo);
5954
});
6055
}
6156

62-
function validatePassword(password: string) {
57+
function validatePassword(
58+
password: string
59+
): Promise<string | Record<string, unknown>> {
6360
return new Promise((resolve, reject) => {
6461
if (!password || password.length < 6) {
65-
console.log("password error");
66-
reject({ password: "Password must be at least 6 characters long." });
62+
console.log('password error');
63+
reject({ password: 'Password must be at least 6 characters long.' });
6764
}
6865
resolve(password);
6966
});
7067
}
7168

72-
function validateEmail(email: string) {
69+
function validateEmail(
70+
email: string
71+
): Promise<string | Record<string, unknown>> {
7372
return new Promise((resolve, reject) => {
7473
if (!email || !isValidEmail(email)) {
75-
reject({ email: "Invalid email" });
74+
reject({ email: 'Invalid email' });
7675
}
7776
resolve(email);
7877
});

server/src/entity/User/makeUserManager.ts

+14-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
import { User } from "./User";
2-
export default function makeUserManager() {
1+
import { User } from './User';
2+
export default function makeUserManager(): Readonly<{
3+
insert: (user: User) => Promise<void>;
4+
findByEmail: (email: string) => Promise<User | null>;
5+
}> {
36
return Object.freeze({
47
insert,
58
findByEmail,
@@ -9,16 +12,20 @@ export default function makeUserManager() {
912
// update,
1013
});
1114

12-
async function insert(user: User) {
13-
User.insert({ ...user });
15+
async function insert(user: User): Promise<void> {
16+
try {
17+
User.insert({ ...user });
18+
} catch (err) {
19+
console.log(err);
20+
}
1421
}
15-
async function findByEmail(email: string) {
22+
async function findByEmail(email: string): Promise<User | null> {
1623
let response;
1724
try {
1825
const res = await User.findOne({ where: { email } });
1926
response = res;
20-
} catch (e) {
21-
console.log(e);
27+
} catch (err) {
28+
console.log(err);
2229
}
2330
return response || null;
2431
}

server/src/helpers/auth.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,37 @@
1-
import { User } from "../entity/User/User";
2-
import { sign, verify } from "jsonwebtoken";
3-
import { MyContext } from "../types/MyContext";
1+
import { User } from '../entity/User/User';
2+
import { sign, verify } from 'jsonwebtoken';
3+
import { MyContext } from '../types/MyContext';
44

55
const jwtSecret = process.env.JWT_SECRET as string;
66

7-
export const createRefreshToken = (user: User) => {
7+
export const createRefreshToken = (user: User): string | null => {
88
let signedString = null;
99
try {
1010
signedString = sign(
1111
{ userId: user.id, email: user.email },
1212
process.env.JWT_REFRESH_SECRET as string,
13-
{ expiresIn: "14d" }
13+
{ expiresIn: '14d' }
1414
);
1515
} catch (err) {
1616
console.log(err);
1717
}
1818
return signedString;
1919
};
2020

21-
export const createAccessToken = (user: User) => {
21+
export const createAccessToken = (user: User): string => {
2222
console.log(jwtSecret);
2323
return sign({ userId: user.id, email: user.email }, jwtSecret, {
24-
expiresIn: "15m",
24+
expiresIn: '15m',
2525
});
2626
};
2727
export const verifyToken = (
2828
jwtToken: string
29-
): MyContext["jwtPayload"] | null => {
29+
): MyContext['jwtPayload'] | null => {
3030
let payload = null;
3131
try {
3232
payload = verify(jwtToken, jwtSecret);
3333
} catch (err) {
3434
return null;
3535
}
36-
return payload as MyContext["jwtPayload"];
36+
return payload as MyContext['jwtPayload'];
3737
};

server/src/helpers/errors/errors.ts

+12-10
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,27 @@ import {
22
UserInputError,
33
ApolloError,
44
AuthenticationError,
5-
} from "apollo-server-express";
5+
} from 'apollo-server-express';
66

7-
export const makeAuthenticationError = () => {
8-
return new AuthenticationError("Not authorized. Login required.");
7+
export const makeAuthenticationError = (): AuthenticationError => {
8+
return new AuthenticationError('Not authorized. Login required.');
99
};
1010

11-
export const makeLoginError = () => {
12-
const validationErrors = { input: "Password and Email not matching" };
13-
return new UserInputError("Login failed.", { validationErrors });
11+
export const makeLoginError = (): UserInputError => {
12+
const validationErrors = { input: 'Password and Email not matching' };
13+
return new UserInputError('Login failed.', { validationErrors });
1414
};
1515

16-
export const serverError = new ApolloError("Internal server error.");
16+
export const serverError = new ApolloError('Internal server error.');
1717

18-
export const makeUserInputError = (errorFields?: {}) => {
18+
export const makeUserInputError = (
19+
errorFields?: Record<string, unknown>
20+
): UserInputError => {
1921
const validationErrors = errorFields ? { ...errorFields } : null;
2022
if (errorFields) {
21-
return new UserInputError("Bad User input.", { validationErrors });
23+
return new UserInputError('Bad User input.', { validationErrors });
2224
}
23-
return new UserInputError("Bad User input.");
25+
return new UserInputError('Bad User input.');
2426
};
2527

2628
export class UniqueConstraintError extends Error {

server/src/helpers/is-valid-email.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export default function isValidEmail(email: string) {
1+
export default function isValidEmail(email: string): boolean {
22
const valid = new RegExp(/^[^@\s]+@[^@\s]+\.[^@\s]+$/);
33
return valid.test(email);
44
}

server/src/index.ts

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
import "reflect-metadata";
2-
require("dotenv-safe").config();
3-
4-
import establishDbConnection from "./db";
5-
import { ApolloServer } from "apollo-server-express";
6-
import { buildSchema } from "type-graphql";
7-
import express from "express";
8-
import { UserResolver } from "./resolvers/UserResolver";
9-
import cors from "cors";
1+
import 'reflect-metadata';
2+
import dotenv from 'dotenv';
3+
dotenv.config();
4+
import establishDbConnection from './db';
5+
import { ApolloServer } from 'apollo-server-express';
6+
import { buildSchema } from 'type-graphql';
7+
import express from 'express';
8+
import { UserResolver } from './resolvers/UserResolver';
9+
import cors from 'cors';
1010

1111
(async () => {
1212
await establishDbConnection();
1313

1414
const app = express();
1515

16-
app.set("trust proxy", 1);
16+
app.set('trust proxy', 1);
1717
// for cookie forwarding since server sits behind the nginx proxy
1818

1919
app.use(cors());
2020

21-
app.get("/state/pulse", (_req, res) => res.send({ alive: true }));
22-
app.get("/");
21+
app.get('/state/pulse', (_req, res) => res.send({ alive: true }));
22+
app.get('/');
2323

2424
const apolloServer = new ApolloServer({
2525
schema: await buildSchema({
@@ -31,6 +31,6 @@ import cors from "cors";
3131
apolloServer.applyMiddleware({ app, cors: false });
3232

3333
app.listen(8080, () => {
34-
console.log("express server started");
34+
console.log('express server started');
3535
});
3636
})();

server/src/resolvers/UserResolver.ts

+21-19
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
import { validateUser, User } from "../entity/User/User";
1+
import { validateUser, User } from '../entity/User/User';
22
import {
33
Resolver,
44
Query,
55
Mutation,
66
Arg,
77
Ctx,
88
UseMiddleware,
9-
} from "type-graphql";
10-
import argon2, { hash } from "argon2";
11-
import makeUserManager from "../entity/User/makeUserManager";
12-
import { LoginResponse } from "../entity/User/responses";
13-
import { MyContext } from "../types/MyContext";
14-
import { createRefreshToken, createAccessToken } from "../helpers/auth";
9+
} from 'type-graphql';
10+
import argon2 from 'argon2';
11+
import makeUserManager from '../entity/User/makeUserManager';
12+
import { LoginResponse } from '../entity/User/responses';
13+
import { MyContext } from '../types/MyContext';
14+
import { createRefreshToken, createAccessToken } from '../helpers/auth';
1515
import {
1616
makeLoginError,
1717
serverError,
1818
makeUserInputError,
19-
} from "../helpers/errors/errors";
20-
import { isAuth } from "../middleware/isAuth";
19+
} from '../helpers/errors/errors';
20+
import { isAuth } from '../middleware/isAuth';
2121

2222
// require("dotenv-safe").config();
2323

@@ -27,28 +27,30 @@ const UserManager = makeUserManager();
2727
export class UserResolver {
2828
@Query(() => User, { nullable: true })
2929
@UseMiddleware(isAuth)
30-
async user(@Ctx() { jwtPayload }: MyContext) {
31-
const user = await UserManager.findByEmail(jwtPayload!.email);
30+
async user(@Ctx() { jwtPayload }: MyContext): Promise<User | null> {
31+
if (!jwtPayload) return null;
32+
const user = await UserManager.findByEmail(jwtPayload.email);
3233
if (!user) return null;
3334
return user;
3435
}
3536

3637
@Mutation(() => Boolean)
3738
async register(
38-
@Arg("email") email: string,
39-
@Arg("password") password: string
40-
) {
39+
@Arg('email') email: string,
40+
@Arg('password') password: string
41+
): Promise<boolean> {
4142
const user = await validateUser(new User(email, password)).catch((err) => {
4243
throw makeUserInputError(err);
4344
});
4445

4546
const existingUser = await UserManager.findByEmail(email).catch((err) => {
47+
console.log(err);
4648
throw serverError;
4749
});
4850

4951
if (existingUser) {
5052
throw makeUserInputError({
51-
email: "Account with this Email already exists",
53+
email: 'Account with this Email already exists',
5254
});
5355
}
5456

@@ -64,9 +66,9 @@ export class UserResolver {
6466

6567
@Mutation(() => LoginResponse)
6668
async login(
67-
@Arg("email") email: string,
68-
@Arg("password") password: string,
69-
@Ctx() { req, res }: MyContext
69+
@Arg('email') email: string,
70+
@Arg('password') password: string,
71+
@Ctx() { res }: MyContext
7072
): Promise<LoginResponse> {
7173
let user = null;
7274

@@ -86,7 +88,7 @@ export class UserResolver {
8688
try {
8789
if (await argon2.verify(user.password, password)) {
8890
const token = createAccessToken(user);
89-
res.cookie("jt", createRefreshToken(user), { httpOnly: true });
91+
res.cookie('jt', createRefreshToken(user), { httpOnly: true });
9092
return { accessToken: token };
9193
} else {
9294
throw makeLoginError();

server/src/types/MyContext.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Request, Response } from "express";
2-
import { JwtPayload } from "./JwtPayload";
1+
import { Request, Response } from 'express';
2+
import { JwtPayload } from './JwtPayload';
33
export type MyContext = {
44
req: Request;
55
res: Response;

0 commit comments

Comments
 (0)