اپلود روی لیارا
This commit is contained in:
parent
25f8bfe69b
commit
6a26ea9b78
|
|
@ -0,0 +1,40 @@
|
||||||
|
# ---- Base Stage ----
|
||||||
|
FROM node:20-slim AS base
|
||||||
|
|
||||||
|
# ---- Build Stage ----
|
||||||
|
FROM base AS build
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
|
||||||
|
# Install ALL dependencies (dev and prod)
|
||||||
|
# This is cached and only re-runs if the lockfile changes.
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Copy the rest of the source code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Build the application
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ---- Production Stage ----
|
||||||
|
# Create the final, lean production image by copying only what's needed.
|
||||||
|
# This stage is very fast as it only contains COPY commands.
|
||||||
|
FROM base AS production
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy the pruned production dependencies, the built app, and package.json
|
||||||
|
COPY --from=build /app/node_modules ./node_modules
|
||||||
|
COPY --from=build /app/dist ./dist
|
||||||
|
COPY --from=build /app/package.json ./package.json
|
||||||
|
|
||||||
|
# Expose the port the app runs on
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# Run the application as a non-root user for better security
|
||||||
|
USER node
|
||||||
|
|
||||||
|
# Command to run the application
|
||||||
|
CMD ["node", "dist/main"]
|
||||||
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
"@nestjs/mongoose": "^11.0.3",
|
"@nestjs/mongoose": "^11.0.3",
|
||||||
"@nestjs/passport": "^11.0.5",
|
"@nestjs/passport": "^11.0.5",
|
||||||
"@nestjs/platform-express": "^11.0.1",
|
"@nestjs/platform-express": "^11.0.1",
|
||||||
|
"@types/passport-google-oauth20": "^2.0.16",
|
||||||
"aws-sdk": "^2.1692.0",
|
"aws-sdk": "^2.1692.0",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.2",
|
"class-validator": "^0.14.2",
|
||||||
|
|
@ -5228,7 +5229,6 @@
|
||||||
"version": "1.19.6",
|
"version": "1.19.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
|
||||||
"integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
|
"integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/connect": "*",
|
"@types/connect": "*",
|
||||||
|
|
@ -5239,7 +5239,6 @@
|
||||||
"version": "3.4.38",
|
"version": "3.4.38",
|
||||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
|
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
|
||||||
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
|
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
|
|
@ -5285,7 +5284,6 @@
|
||||||
"version": "5.0.3",
|
"version": "5.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz",
|
||||||
"integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==",
|
"integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/body-parser": "*",
|
"@types/body-parser": "*",
|
||||||
|
|
@ -5297,7 +5295,6 @@
|
||||||
"version": "5.0.6",
|
"version": "5.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz",
|
||||||
"integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==",
|
"integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
|
|
@ -5327,7 +5324,6 @@
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
|
||||||
"integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
|
"integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/istanbul-lib-coverage": {
|
"node_modules/@types/istanbul-lib-coverage": {
|
||||||
|
|
@ -5395,7 +5391,6 @@
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
||||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
|
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/multer": {
|
"node_modules/@types/multer": {
|
||||||
|
|
@ -5417,25 +5412,62 @@
|
||||||
"undici-types": "~6.21.0"
|
"undici-types": "~6.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/oauth": {
|
||||||
|
"version": "0.9.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.6.tgz",
|
||||||
|
"integrity": "sha512-H9TRCVKBNOhZZmyHLqFt9drPM9l+ShWiqqJijU1B8P3DX3ub84NjxDuy+Hjrz+fEca5Kwip3qPMKNyiLgNJtIA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/passport": {
|
||||||
|
"version": "1.0.17",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.17.tgz",
|
||||||
|
"integrity": "sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/express": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/passport-google-oauth20": {
|
||||||
|
"version": "2.0.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.16.tgz",
|
||||||
|
"integrity": "sha512-ayXK2CJ7uVieqhYOc6k/pIr5pcQxOLB6kBev+QUGS7oEZeTgIs1odDobXRqgfBPvXzl0wXCQHftV5220czZCPA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/express": "*",
|
||||||
|
"@types/passport": "*",
|
||||||
|
"@types/passport-oauth2": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/passport-oauth2": {
|
||||||
|
"version": "1.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.8.0.tgz",
|
||||||
|
"integrity": "sha512-6//z+4orIOy/g3zx17HyQ71GSRK4bs7Sb+zFasRoc2xzlv7ZCJ+vkDBYFci8U6HY+or6Zy7ajf4mz4rK7nsWJQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/express": "*",
|
||||||
|
"@types/oauth": "*",
|
||||||
|
"@types/passport": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/qs": {
|
"node_modules/@types/qs": {
|
||||||
"version": "6.14.0",
|
"version": "6.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
|
||||||
"integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
|
"integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/range-parser": {
|
"node_modules/@types/range-parser": {
|
||||||
"version": "1.2.7",
|
"version": "1.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
||||||
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
|
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/send": {
|
"node_modules/@types/send": {
|
||||||
"version": "0.17.5",
|
"version": "0.17.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz",
|
||||||
"integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==",
|
"integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/mime": "^1",
|
"@types/mime": "^1",
|
||||||
|
|
@ -5446,7 +5478,6 @@
|
||||||
"version": "1.15.8",
|
"version": "1.15.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz",
|
||||||
"integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==",
|
"integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/http-errors": "*",
|
"@types/http-errors": "*",
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
"@nestjs/mongoose": "^11.0.3",
|
"@nestjs/mongoose": "^11.0.3",
|
||||||
"@nestjs/passport": "^11.0.5",
|
"@nestjs/passport": "^11.0.5",
|
||||||
"@nestjs/platform-express": "^11.0.1",
|
"@nestjs/platform-express": "^11.0.1",
|
||||||
|
"@types/passport-google-oauth20": "^2.0.16",
|
||||||
"aws-sdk": "^2.1692.0",
|
"aws-sdk": "^2.1692.0",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.2",
|
"class-validator": "^0.14.2",
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import { DiscountTypeModule } from './discount-type/discount-type.module';
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
CategoryModule,UploadModule,LoginModule,ShopModule,ProductModule,DiscountModule,
|
CategoryModule,UploadModule,LoginModule,ShopModule,ProductModule,DiscountModule,
|
||||||
MongooseModule.forRoot('mongodb://localhost/fartak'),
|
MongooseModule.forRoot('mongodb://root:FcpaOAxvZd2IiqK5Vl5QRMTE@fartakdatabase:27017/my-app?authSource=admin'),
|
||||||
ConfigModule.forRoot({ isGlobal: true }), DiscountTypeModule
|
ConfigModule.forRoot({ isGlobal: true }), DiscountTypeModule
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,37 @@
|
||||||
import { Controller } from '@nestjs/common';
|
import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common';
|
||||||
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
|
import { JwtService } from '@nestjs/jwt';
|
||||||
|
import { Response, Request } from 'express';
|
||||||
|
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
|
constructor(private jwtService: JwtService) {}
|
||||||
|
|
||||||
|
@Get('google')
|
||||||
|
@UseGuards(AuthGuard('google'))
|
||||||
|
async googleAuth() {
|
||||||
|
// Redirects to Google
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('google/redirect')
|
||||||
|
@UseGuards(AuthGuard('google'))
|
||||||
|
async googleRedirect(@Req() req: Request, @Res() res: Response) {
|
||||||
|
const user = req.user as any;
|
||||||
|
|
||||||
|
// You can store user in DB here if needed
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
email: user.email,
|
||||||
|
name: `${user.firstName} ${user.lastName}`,
|
||||||
|
picture: user.picture,
|
||||||
|
};
|
||||||
|
|
||||||
|
const token = this.jwtService.sign(payload);
|
||||||
|
|
||||||
|
// ✅ Option 1: Send token as JSON
|
||||||
|
// res.json({ token });
|
||||||
|
|
||||||
|
// ✅ Option 2: Redirect to frontend with token
|
||||||
|
res.redirect(`http://localhost:4200/login/success?token=${token}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,26 @@
|
||||||
|
// auth/google.strategy.ts
|
||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport';
|
||||||
import { Strategy, VerifyCallback } from 'passport-google-oauth20';
|
import { Strategy, VerifyCallback, StrategyOptions } from 'passport-google-oauth20';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import * as dotenv from 'dotenv';
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
dotenv.config();
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
|
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
|
||||||
constructor() {
|
constructor(private configService: ConfigService) {
|
||||||
super({
|
super({
|
||||||
clientID: process.env.GOOGLE_CLIENT_ID,
|
clientID: configService.get<string>('GOOGLE_CLIENT_ID'),
|
||||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
clientSecret: configService.get<string>('GOOGLE_CLIENT_SECRET'),
|
||||||
callbackURL: 'http://localhost:3000/auth/google/redirect',
|
callbackURL: configService.get<string>('GOOGLE_CALLBACK_URL'),
|
||||||
scope: ['email', 'profile'],
|
scope: ['email', 'profile'],
|
||||||
});
|
} as StrategyOptions); // Fixes the typing error
|
||||||
}
|
}
|
||||||
|
|
||||||
async validate(accessToken: string, refreshToken: string, profile: any, done: VerifyCallback): Promise<any> {
|
async validate(
|
||||||
|
accessToken: string,
|
||||||
|
refreshToken: string,
|
||||||
|
profile: any,
|
||||||
|
done: VerifyCallback,
|
||||||
|
): Promise<any> {
|
||||||
const { name, emails, photos } = profile;
|
const { name, emails, photos } = profile;
|
||||||
|
|
||||||
const user = {
|
const user = {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ export class DiscountTypeService {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async findDiscountType(id:string) :Promise <CreateSellerResponse> {
|
async findDiscountType(id:string) :Promise <CreateSellerResponse> {
|
||||||
|
|
||||||
const category = await this.discountTypeModel.findOne({ID:id})
|
const category = await this.discountTypeModel.findOne({ID:id})
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
// src/redis.client.ts
|
|
||||||
import Redis from 'ioredis';
|
import Redis from 'ioredis';
|
||||||
|
|
||||||
const redis = new Redis({
|
const redis = new Redis(process.env.REDIS_URL || 'redis://:eCwxwRr7YX9q0ynso4uR6HNf@fartakredis:6379/0');
|
||||||
host: 'localhost', // یا IP سرور Redis
|
|
||||||
port: 6379, // پورت پیشفرض Redis
|
|
||||||
});
|
|
||||||
|
|
||||||
export default redis;
|
export default redis;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue