diff --git a/server/package-lock.json b/server/package-lock.json index 47edce5c6f..25f8103787 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -32,6 +32,7 @@ "dotenv": "^16.0.3", "fast-json-patch": "^3.1.1", "mongodb": "^4.12.1", + "ms": "^2.1.3", "nanoid": "^3.3.4", "passport": "^0.6.0", "passport-jwt": "^4.0.0", @@ -7835,6 +7836,12 @@ } } }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "node_modules/decache": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/decache/-/decache-4.6.1.tgz", @@ -11765,9 +11772,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/multer": { "version": "1.4.4-lts.1", @@ -13291,11 +13298,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -21231,6 +21233,14 @@ "dev": true, "requires": { "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, "decache": { @@ -24207,9 +24217,9 @@ } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "multer": { "version": "1.4.4-lts.1", @@ -25332,11 +25342,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, diff --git a/server/package.json b/server/package.json index ac687c6ed8..04c12ad455 100644 --- a/server/package.json +++ b/server/package.json @@ -46,6 +46,7 @@ "dotenv": "^16.0.3", "fast-json-patch": "^3.1.1", "mongodb": "^4.12.1", + "ms": "^2.1.3", "nanoid": "^3.3.4", "passport": "^0.6.0", "passport-jwt": "^4.0.0", diff --git a/server/src/applications/applications.controller.ts b/server/src/applications/applications.controller.ts index 6fb52e23d2..856946088a 100644 --- a/server/src/applications/applications.controller.ts +++ b/server/src/applications/applications.controller.ts @@ -24,6 +24,7 @@ import { CreateApplicationDto } from './dto/create-application.dto' import { UpdateApplicationDto } from './dto/update-application.dto' import { ApplicationsService } from './applications.service' import { ApplicationCoreService } from 'src/core/application.cr.service' +import { ServerConfig } from 'src/constants' @ApiTags('Application') @Controller('applications') @@ -83,14 +84,17 @@ export class ApplicationsController { // get sub resources const resources = await this.appService.getSubResources(appid) - const data = await this.appService.findOne(appid) - const sts = await this.appService.getApplicationSTS(appid, resources.oss) + const data = await this.appService.findOne(appid, { configuration: true }) + const sts = await this.appService.getOssSTS(appid, resources.oss) const credentials = { + endpoint: ServerConfig.OSS_ENDPOINT, accessKeyId: sts.Credentials?.AccessKeyId, secretAccessKey: sts.Credentials?.SecretAccessKey, sessionToken: sts.Credentials?.SessionToken, expiration: sts.Credentials?.Expiration, } + + const debug_token = await this.appService.getDebugFunctionToken(appid) const res = { ...data, gateway: resources.gateway, @@ -99,6 +103,7 @@ export class ApplicationsController { ...resources.oss, credentials, }, + function_debug_token: debug_token, } return ResponseUtil.ok(res) diff --git a/server/src/applications/applications.module.ts b/server/src/applications/applications.module.ts index 4dbadc0461..f51a544550 100644 --- a/server/src/applications/applications.module.ts +++ b/server/src/applications/applications.module.ts @@ -6,6 +6,7 @@ import { ApplicationsService } from './applications.service' import { PrismaService } from '../prisma.service' import { ApplicationTaskService } from './application-task.service' import { InstanceService } from 'src/instance/instance.service' +import { JwtService } from '@nestjs/jwt' @Module({ imports: [CoreModule], @@ -15,6 +16,7 @@ import { InstanceService } from 'src/instance/instance.service' PrismaService, ApplicationTaskService, InstanceService, + JwtService, ], exports: [ApplicationsService], }) diff --git a/server/src/applications/applications.service.ts b/server/src/applications/applications.service.ts index 93b7b905a3..6a2db199c6 100644 --- a/server/src/applications/applications.service.ts +++ b/server/src/applications/applications.service.ts @@ -11,6 +11,8 @@ import { OSSUserCoreService } from 'src/core/oss-user.cr.service' import { APPLICATION_SECRET_KEY, ServerConfig } from 'src/constants' import { GenerateAlphaNumericPassword } from 'src/common/random' import { OSSUser } from 'src/core/api/oss-user.cr' +import * as assert from 'node:assert' +import { JwtService } from '@nestjs/jwt' @Injectable() export class ApplicationsService { @@ -20,6 +22,7 @@ export class ApplicationsService { private readonly databaseCore: DatabaseCoreService, private readonly gatewayCore: GatewayCoreService, private readonly ossCore: OSSUserCoreService, + private readonly jwtService: JwtService, ) {} async create(userid: string, dto: CreateApplicationDto) { @@ -160,7 +163,7 @@ export class ApplicationsService { * @param app * @returns */ - public getSTSClient(oss: OSSUser) { + private getSTSClient(oss: OSSUser) { return new STSClient({ endpoint: ServerConfig.OSS_ENDPOINT, credentials: { @@ -172,12 +175,12 @@ export class ApplicationsService { } /** - * Generate application full-granted STS + * Generate application full-granted OSS STS * @param bucket * @param duration_seconds * @returns */ - public async getApplicationSTS( + public async getOssSTS( appid: string, user: OSSUser, duration_seconds?: number, @@ -209,4 +212,25 @@ export class ApplicationsService { } return JSON.stringify(policy) } + + async getDebugFunctionToken(appid: string) { + const conf = await this.prisma.applicationConfiguration.findUnique({ + where: { appid }, + }) + + // get secret from envs + const secret = conf?.environments.find( + (env) => env.name === APPLICATION_SECRET_KEY, + ) + assert(secret?.value, 'application secret not found') + + // generate token + const exp = Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7 // 7 days + + const token = this.jwtService.sign( + { appid, type: 'debug', exp }, + { secret: secret.value }, + ) + return token + } } diff --git a/server/src/main.ts b/server/src/main.ts index be8eb646ad..56ff77c9f2 100644 --- a/server/src/main.ts +++ b/server/src/main.ts @@ -30,9 +30,8 @@ async function bootstrap() { .setTitle('Open API Documentation of laf') .setDescription('`The APIs of laf server`') .setVersion('1.0.alpha') - .addServer('http://localhost:3000', 'local server') + .addServer(ServerConfig.SERVER, 'current server') .addServer('http://dev.server:3000', 'dev server') - .addServer(ServerConfig.SERVER, 'prod server') .addBearerAuth( { type: 'http', scheme: 'bearer', bearerFormat: 'JWT', in: 'header' }, 'Authorization',