Skip to content

Commit 77495f9

Browse files
committed
chore: auth.controller corrected
2 parents 599ecc8 + 0cce023 commit 77495f9

75 files changed

Lines changed: 2185 additions & 943 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

backend/package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,29 @@
99
},
1010
"dependencies": {
1111
"@aws-sdk/client-s3": "^3.962.0",
12+
"bcrypt": "^6.0.0",
13+
"cors": "^2.8.5",
1214
"dotenv": "^17.2.3",
1315
"express": "^5.2.1",
1416
"form-data": "^4.0.5",
17+
"jsonwebtoken": "^9.0.3",
1518
"mailgun.js": "^12.4.1",
1619
"multer": "^2.0.2",
1720
"pg": "^8.16.3",
1821
"pino": "^10.1.0",
1922
"pino-http": "^11.0.0",
2023
"reflect-metadata": "^0.2.2",
24+
"twilio": "^5.11.1",
2125
"typeorm": "^0.3.28"
2226
},
2327
"devDependencies": {
2428
"@commitlint/cli": "^20.2.0",
2529
"@commitlint/config-conventional": "^20.2.0",
2630
"@eslint/js": "^9.39.2",
31+
"@types/bcrypt": "^6.0.0",
32+
"@types/cors": "^2.8.19",
2733
"@types/express": "^5.0.6",
34+
"@types/jsonwebtoken": "^9.0.10",
2835
"@types/multer": "^2.0.0",
2936
"@types/node": "^25.0.3",
3037
"@types/pg": "^8.16.0",

backend/src/Services/authToken.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { appDataSouce } from '../data-source';
2+
import { RefreshTokenEntity } from '../entities/refreshToken';
3+
import { User } from '../entities/User';
4+
import { generateRefreshToken, hashRefreshToken } from './refreshToken';
5+
const REFRESH_TOKEN_DAYS = 30;
6+
7+
export const createRefreshTokenSession = async (user: User) => {
8+
const refreshToken = generateRefreshToken();
9+
console.log('Raw refresh token generated');
10+
11+
const tokenHash = hashRefreshToken(refreshToken);
12+
console.log('Token hashed');
13+
14+
const expiresAt = new Date();
15+
16+
expiresAt.setDate(expiresAt.getDate() + REFRESH_TOKEN_DAYS);
17+
18+
const repo = appDataSouce.getRepository(RefreshTokenEntity);
19+
console.log('Got refresh token repository');
20+
21+
await repo.save({
22+
tokenHash,
23+
user,
24+
expiresAt,
25+
});
26+
console.log('Refresh token saved');
27+
return refreshToken;
28+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import jwt from 'jsonwebtoken';
2+
3+
export const signAccessToken = (payload: { userId: string }) => {
4+
return jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET!, {
5+
expiresIn: '15m',
6+
});
7+
};
8+
export const verifyAccessToken = (token: string) => {
9+
return jwt.verify(token, process.env.ACCESS_TOKEN_SECRET!);
10+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import crypto from 'crypto';
2+
export const generateRefreshToken = (): string => {
3+
return crypto.randomBytes(64).toString();
4+
};
5+
export const hashRefreshToken = (token: string) => {
6+
return crypto.createHash('sha256').update(token).digest('hex');
7+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Twilio from 'twilio';
2+
import { logger } from '../utils/logger';
3+
const accountSid = process.env.TWILIO_ACCOUNT_SID!;
4+
const authToken = process.env.TWILIO_AUTH_TOKEN!;
5+
const fromNumber = process.env.TWILIO_FROM_NUMBER!;
6+
const client = Twilio(accountSid, authToken);
7+
export const sendOtpSms = async (phoneNumber: string, otp: string) => {
8+
try {
9+
await client.messages.create({
10+
body: `otp is ${otp}`,
11+
from: fromNumber,
12+
to: phoneNumber,
13+
});
14+
} catch (err) {
15+
logger.error({ err }, 'failed to send otp');
16+
throw new Error('failed to send');
17+
}
18+
};

backend/src/app.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import express from 'express';
2+
import cors from 'cors';
23
import { pinoHttp } from 'pino-http';
34
import { logger } from './utils/logger';
45
import { notFound } from './middleware/notFound';
@@ -8,6 +9,7 @@ import authRouter from './modules/auth/auth.routes';
89
import userRouter from './modules/user/user.routes';
910

1011
const app = express();
12+
app.use(cors());
1113
app.use(express.json());
1214
app.use(
1315
pinoHttp({ logger, autoLogging: { ignore: (req) => req.url === 'health' } }),

backend/src/data-source.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dotenv/config';
22
import { DataSource } from 'typeorm';
33
import { User } from './entities/User';
44
import { Otp } from './entities/opt';
5+
import { RefreshTokenEntity } from './entities/refreshToken';
56
if (!process.env.DATABASE_URL) {
67
throw new Error('DATABASE_URL is not defined');
78
}
@@ -11,6 +12,6 @@ export const appDataSource = new DataSource({
1112
ssl: {
1213
rejectUnauthorized: false,
1314
},
14-
entities: [User, Otp],
15+
entities: [User, Otp, RefreshTokenEntity],
1516
synchronize: true,
1617
});

backend/src/entities/User.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ export class User {
1010
@PrimaryGeneratedColumn('uuid')
1111
id!: string;
1212

13-
@Column({ unique: true })
13+
@Column({ unique: true, nullable: true })
1414
email!: string;
1515

16+
@Column({ unique: true, nullable: true })
17+
phoneNumber!: string;
18+
1619
@Column()
1720
name!: string;
1821

@@ -28,6 +31,12 @@ export class User {
2831
@Column({ nullable: true })
2932
profileImageUrl?: string;
3033

34+
@Column({ nullable: true })
35+
passwordHash?: string;
36+
37+
@Column({ default: false })
38+
isPhoneVerified!: boolean;
39+
3140
@CreateDateColumn()
3241
createdAt!: Date;
3342
}

backend/src/entities/opt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export class Otp {
1010
@PrimaryGeneratedColumn('uuid')
1111
id!: string;
1212
@Column()
13-
email!: string;
13+
phoneNumber!: string;
1414
@Column()
1515
otp!: string;
1616
@Column({ type: 'timestamp' })
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {
2+
Entity,
3+
PrimaryGeneratedColumn,
4+
Column,
5+
CreateDateColumn,
6+
ManyToOne,
7+
} from 'typeorm';
8+
import { User } from './User';
9+
@Entity()
10+
export class RefreshTokenEntity {
11+
@PrimaryGeneratedColumn('uuid')
12+
id!: string;
13+
14+
@Column()
15+
tokenHash!: string;
16+
17+
@Column()
18+
expiresAt!: Date;
19+
20+
@Column({ default: false })
21+
revoked!: boolean;
22+
23+
@ManyToOne(() => User, { onDelete: 'CASCADE' })
24+
user!: User;
25+
26+
@CreateDateColumn()
27+
createdAt!: Date;
28+
}

0 commit comments

Comments
 (0)