Introduced Secrets Manager
This commit is contained in:
1
package-lock.json
generated
1
package-lock.json
generated
@@ -16,6 +16,7 @@
|
|||||||
"@fastify/multipart": "^9.0.3",
|
"@fastify/multipart": "^9.0.3",
|
||||||
"@fastify/swagger": "^9.5.1",
|
"@fastify/swagger": "^9.5.1",
|
||||||
"@fastify/swagger-ui": "^5.2.3",
|
"@fastify/swagger-ui": "^5.2.3",
|
||||||
|
"@infisical/sdk": "^4.0.6",
|
||||||
"@prisma/client": "^6.15.0",
|
"@prisma/client": "^6.15.0",
|
||||||
"@supabase/supabase-js": "^2.56.1",
|
"@supabase/supabase-js": "^2.56.1",
|
||||||
"@zip.js/zip.js": "^2.7.73",
|
"@zip.js/zip.js": "^2.7.73",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"@fastify/multipart": "^9.0.3",
|
"@fastify/multipart": "^9.0.3",
|
||||||
"@fastify/swagger": "^9.5.1",
|
"@fastify/swagger": "^9.5.1",
|
||||||
"@fastify/swagger-ui": "^5.2.3",
|
"@fastify/swagger-ui": "^5.2.3",
|
||||||
|
"@infisical/sdk": "^4.0.6",
|
||||||
"@prisma/client": "^6.15.0",
|
"@prisma/client": "^6.15.0",
|
||||||
"@supabase/supabase-js": "^2.56.1",
|
"@supabase/supabase-js": "^2.56.1",
|
||||||
"@zip.js/zip.js": "^2.7.73",
|
"@zip.js/zip.js": "^2.7.73",
|
||||||
|
|||||||
@@ -22,9 +22,11 @@ import exportRoutes from "./routes/exports"
|
|||||||
import emailAsUserRoutes from "./routes/emailAsUser";
|
import emailAsUserRoutes from "./routes/emailAsUser";
|
||||||
|
|
||||||
import {sendMail} from "./utils/mailer";
|
import {sendMail} from "./utils/mailer";
|
||||||
|
import {loadSecrets, secrets} from "./utils/secrets";
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const app = Fastify({ logger: true });
|
const app = Fastify({ logger: true });
|
||||||
|
await loadSecrets();
|
||||||
|
|
||||||
/*app.addHook("onRequest", (req, reply, done) => {
|
/*app.addHook("onRequest", (req, reply, done) => {
|
||||||
console.log("Incoming:", req.method, req.url, "Headers:", req.headers)
|
console.log("Incoming:", req.method, req.url, "Headers:", req.headers)
|
||||||
@@ -37,7 +39,7 @@ async function main() {
|
|||||||
await app.register(supabasePlugin);
|
await app.register(supabasePlugin);
|
||||||
await app.register(tenantPlugin);
|
await app.register(tenantPlugin);
|
||||||
app.register(fastifyCookie, {
|
app.register(fastifyCookie, {
|
||||||
secret: process.env.COOKIE_SECRET || "supersecret", // optional, für signierte Cookies
|
secret: secrets.COOKIE_SECRET,
|
||||||
})
|
})
|
||||||
// Öffentliche Routes
|
// Öffentliche Routes
|
||||||
await app.register(authRoutes);
|
await app.register(authRoutes);
|
||||||
@@ -68,8 +70,8 @@ async function main() {
|
|||||||
|
|
||||||
// Start
|
// Start
|
||||||
try {
|
try {
|
||||||
await app.listen({ port: 3100, host: "0.0.0.0" });
|
await app.listen({ port: secrets.PORT, host: secrets.HOST });
|
||||||
console.log("🚀 Server läuft auf http://localhost:3100");
|
console.log(`🚀 Server läuft auf http://${secrets.HOST}:${secrets.PORT}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
app.log.error(err);
|
app.log.error(err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { FastifyInstance } from "fastify";
|
import { FastifyInstance } from "fastify";
|
||||||
import fp from "fastify-plugin";
|
import fp from "fastify-plugin";
|
||||||
import jwt from "jsonwebtoken";
|
import jwt from "jsonwebtoken";
|
||||||
|
import {secrets} from "../utils/secrets";
|
||||||
|
|
||||||
export default fp(async (server: FastifyInstance) => {
|
export default fp(async (server: FastifyInstance) => {
|
||||||
server.addHook("preHandler", async (req, reply) => {
|
server.addHook("preHandler", async (req, reply) => {
|
||||||
@@ -28,7 +29,7 @@ export default fp(async (server: FastifyInstance) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const payload = jwt.verify(token, process.env.JWT_SECRET!) as {
|
const payload = jwt.verify(token, secrets.JWT_SECRET!) as {
|
||||||
user_id: string;
|
user_id: string;
|
||||||
email: string;
|
email: string;
|
||||||
tenant_id?: string;
|
tenant_id?: string;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { FastifyInstance } from "fastify";
|
import { FastifyInstance } from "fastify";
|
||||||
import fp from "fastify-plugin";
|
import fp from "fastify-plugin";
|
||||||
import { createClient, SupabaseClient } from "@supabase/supabase-js";
|
import { createClient, SupabaseClient } from "@supabase/supabase-js";
|
||||||
|
import {secrets} from "../utils/secrets";
|
||||||
|
|
||||||
export default fp(async (server: FastifyInstance) => {
|
export default fp(async (server: FastifyInstance) => {
|
||||||
const supabaseUrl = process.env.SUPABASE_URL || "https://uwppvcxflrcsibuzsbil.supabase.co";
|
const supabaseUrl = secrets.SUPABASE_URL
|
||||||
const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY || "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV3cHB2Y3hmbHJjc2lidXpzYmlsIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcwMDkzODE5NCwiZXhwIjoyMDE2NTE0MTk0fQ.6hOkD1J8XBkVJUm-swv0ngLQ74xrEYr28EEbo0rUrts";
|
const supabaseServiceKey = secrets.SUPABASE_SERVICE_ROLE_KEY
|
||||||
|
|
||||||
const supabase: SupabaseClient = createClient(supabaseUrl, supabaseServiceKey);
|
const supabase: SupabaseClient = createClient(supabaseUrl, supabaseServiceKey);
|
||||||
|
|
||||||
// Fastify um supabase erweitern
|
// Fastify um supabase erweitern
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import bcrypt from "bcrypt";
|
|||||||
import jwt from "jsonwebtoken";
|
import jwt from "jsonwebtoken";
|
||||||
import { generateRandomPassword, hashPassword } from "../../utils/password"
|
import { generateRandomPassword, hashPassword } from "../../utils/password"
|
||||||
import { sendMail } from "../../utils/mailer"
|
import { sendMail } from "../../utils/mailer"
|
||||||
|
import {secrets} from "../../utils/secrets";
|
||||||
|
|
||||||
export default async function authRoutes(server: FastifyInstance) {
|
export default async function authRoutes(server: FastifyInstance) {
|
||||||
// Registrierung
|
// Registrierung
|
||||||
@@ -140,7 +141,7 @@ export default async function authRoutes(server: FastifyInstance) {
|
|||||||
} else {
|
} else {
|
||||||
const token = jwt.sign(
|
const token = jwt.sign(
|
||||||
{ user_id: user.id, email: user.email, tenant_id: req.tenant ? req.tenant.id : null },
|
{ user_id: user.id, email: user.email, tenant_id: req.tenant ? req.tenant.id : null },
|
||||||
process.env.JWT_SECRET!,
|
secrets.JWT_SECRET!,
|
||||||
{ expiresIn: "3h" }
|
{ expiresIn: "3h" }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {GetObjectCommand, PutObjectCommand} from "@aws-sdk/client-s3"
|
|||||||
import {getSignedUrl} from "@aws-sdk/s3-request-presigner";
|
import {getSignedUrl} from "@aws-sdk/s3-request-presigner";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import {randomUUID} from "node:crypto";
|
import {randomUUID} from "node:crypto";
|
||||||
|
import {secrets} from "../utils/secrets";
|
||||||
|
|
||||||
const createExport = async (server:FastifyInstance,req:any,startDate,endDate,beraternr,mandantennr) => {
|
const createExport = async (server:FastifyInstance,req:any,startDate,endDate,beraternr,mandantennr) => {
|
||||||
console.log(startDate,endDate,beraternr,mandantennr)
|
console.log(startDate,endDate,beraternr,mandantennr)
|
||||||
@@ -22,7 +23,7 @@ const createExport = async (server:FastifyInstance,req:any,startDate,endDate,ber
|
|||||||
// 3) In S3 hochladen
|
// 3) In S3 hochladen
|
||||||
await s3.send(
|
await s3.send(
|
||||||
new PutObjectCommand({
|
new PutObjectCommand({
|
||||||
Bucket: process.env.S3_BUCKET || "FEDEO",
|
Bucket: secrets.S3_BUCKET,
|
||||||
Key: fileKey,
|
Key: fileKey,
|
||||||
Body: buffer,
|
Body: buffer,
|
||||||
ContentType: "application/zip",
|
ContentType: "application/zip",
|
||||||
@@ -33,7 +34,7 @@ const createExport = async (server:FastifyInstance,req:any,startDate,endDate,ber
|
|||||||
const url = await getSignedUrl(
|
const url = await getSignedUrl(
|
||||||
s3,
|
s3,
|
||||||
new GetObjectCommand({
|
new GetObjectCommand({
|
||||||
Bucket: process.env.S3_BUCKET || "FEDEO",
|
Bucket: secrets.S3_BUCKET,
|
||||||
Key: fileKey,
|
Key: fileKey,
|
||||||
}),
|
}),
|
||||||
{ expiresIn: 60 * 60 * 24 }
|
{ expiresIn: 60 * 60 * 24 }
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { s3 } from "../utils/s3"
|
|||||||
import {GetObjectCommand, PutObjectCommand} from "@aws-sdk/client-s3"
|
import {GetObjectCommand, PutObjectCommand} from "@aws-sdk/client-s3"
|
||||||
import {getSignedUrl} from "@aws-sdk/s3-request-presigner";
|
import {getSignedUrl} from "@aws-sdk/s3-request-presigner";
|
||||||
import archiver from "archiver"
|
import archiver from "archiver"
|
||||||
|
import {secrets} from "../utils/secrets"
|
||||||
|
|
||||||
export default async function fileRoutes(server: FastifyInstance) {
|
export default async function fileRoutes(server: FastifyInstance) {
|
||||||
await server.register(multipart,{
|
await server.register(multipart,{
|
||||||
@@ -59,7 +60,7 @@ export default async function fileRoutes(server: FastifyInstance) {
|
|||||||
const fileKey = `${tenantId}/filesbyid/${createdFileData.id}/${data.filename}`
|
const fileKey = `${tenantId}/filesbyid/${createdFileData.id}/${data.filename}`
|
||||||
|
|
||||||
await s3.send(new PutObjectCommand({
|
await s3.send(new PutObjectCommand({
|
||||||
Bucket: process.env.S3_BUCKET || "FEDEO",
|
Bucket: secrets.S3_BUCKET,
|
||||||
Key: fileKey,
|
Key: fileKey,
|
||||||
Body: fileBuffer,
|
Body: fileBuffer,
|
||||||
ContentType: data.mimetype,
|
ContentType: data.mimetype,
|
||||||
@@ -143,7 +144,7 @@ export default async function fileRoutes(server: FastifyInstance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const command = new GetObjectCommand({
|
const command = new GetObjectCommand({
|
||||||
Bucket: process.env.S3_BUCKET || "FEDEO",
|
Bucket: secrets.S3_BUCKET,
|
||||||
Key: data.path,
|
Key: data.path,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -187,7 +188,7 @@ export default async function fileRoutes(server: FastifyInstance) {
|
|||||||
|
|
||||||
for (const entry of supabaseFiles) {
|
for (const entry of supabaseFiles) {
|
||||||
const command = new GetObjectCommand({
|
const command = new GetObjectCommand({
|
||||||
Bucket: process.env.S3_BUCKET || "FEDEO",
|
Bucket: secrets.S3_BUCKET,
|
||||||
Key: entry.path,
|
Key: entry.path,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -217,7 +218,7 @@ export default async function fileRoutes(server: FastifyInstance) {
|
|||||||
const {data,error} = await server.supabase.from("files").select("*").eq("id", id).single()
|
const {data,error} = await server.supabase.from("files").select("*").eq("id", id).single()
|
||||||
|
|
||||||
const command = new GetObjectCommand({
|
const command = new GetObjectCommand({
|
||||||
Bucket: process.env.S3_BUCKET || "FEDEO",
|
Bucket: secrets.S3_BUCKET,
|
||||||
Key: data.path,
|
Key: data.path,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -256,7 +257,7 @@ export default async function fileRoutes(server: FastifyInstance) {
|
|||||||
if(!key) console.log(file)
|
if(!key) console.log(file)
|
||||||
|
|
||||||
const command = new GetObjectCommand({
|
const command = new GetObjectCommand({
|
||||||
Bucket: process.env.S3_BUCKET || "FEDEO",
|
Bucket: secrets.S3_BUCKET,
|
||||||
Key: key,
|
Key: key,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { FastifyInstance } from "fastify";
|
import { FastifyInstance } from "fastify";
|
||||||
import jwt from "jsonwebtoken";
|
import jwt from "jsonwebtoken";
|
||||||
|
import {secrets} from "../utils/secrets";
|
||||||
|
|
||||||
export default async function routes(server: FastifyInstance) {
|
export default async function routes(server: FastifyInstance) {
|
||||||
server.get("/tenant", async (req) => {
|
server.get("/tenant", async (req) => {
|
||||||
@@ -45,7 +46,7 @@ export default async function routes(server: FastifyInstance) {
|
|||||||
email: req.user.email,
|
email: req.user.email,
|
||||||
tenant_id: body.tenant_id,
|
tenant_id: body.tenant_id,
|
||||||
},
|
},
|
||||||
process.env.JWT_SECRET!,
|
secrets.JWT_SECRET!,
|
||||||
{ expiresIn: "3h" }
|
{ expiresIn: "3h" }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {BlobWriter, Data64URIReader, TextReader, TextWriter, ZipWriter} from "@z
|
|||||||
import {FastifyInstance} from "fastify";
|
import {FastifyInstance} from "fastify";
|
||||||
import {GetObjectCommand} from "@aws-sdk/client-s3";
|
import {GetObjectCommand} from "@aws-sdk/client-s3";
|
||||||
import {s3} from "../s3";
|
import {s3} from "../s3";
|
||||||
|
import {secrets} from "../secrets";
|
||||||
dayjs.extend(isBetween)
|
dayjs.extend(isBetween)
|
||||||
|
|
||||||
const getCreatedDocumentTotal = (item) => {
|
const getCreatedDocumentTotal = (item) => {
|
||||||
@@ -92,7 +93,7 @@ export async function buildExportZip(server: FastifyInstance, tenant: number, st
|
|||||||
|
|
||||||
const downloadFile = async (bucketName, filePath, downloadFilePath,fileId) => {
|
const downloadFile = async (bucketName, filePath, downloadFilePath,fileId) => {
|
||||||
const command = new GetObjectCommand({
|
const command = new GetObjectCommand({
|
||||||
Bucket: process.env.S3_BUCKET || "FEDEO",
|
Bucket: secrets.S3_BUCKET,
|
||||||
Key: filePath,
|
Key: filePath,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import nodemailer from "nodemailer"
|
import nodemailer from "nodemailer"
|
||||||
|
import {secrets} from "./secrets"
|
||||||
|
|
||||||
const transporter = nodemailer.createTransport({
|
const transporter = nodemailer.createTransport({
|
||||||
host: process.env.SMTP_HOST,
|
host: secrets.MAILER_SMTP_HOST,
|
||||||
port: Number(process.env.SMTP_PORT) || 587,
|
port: Number(secrets.MAILER_SMTP_PORT) || 587,
|
||||||
secure: process.env.SMTP_SSL === "true", // true für 465, false für andere Ports
|
secure: secrets.MAILER_SMTP_SSL === "true", // true für 465, false für andere Ports
|
||||||
auth: {
|
auth: {
|
||||||
user: process.env.SMTP_USER,
|
user: secrets.MAILER_SMTP_USER,
|
||||||
pass: process.env.SMTP_PASS,
|
pass: secrets.MAILER_SMTP_PASS,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ export async function sendMail(
|
|||||||
): Promise<{ success: boolean; info?: any; error?: any }> {
|
): Promise<{ success: boolean; info?: any; error?: any }> {
|
||||||
try {
|
try {
|
||||||
const info = await transporter.sendMail({
|
const info = await transporter.sendMail({
|
||||||
from: process.env.MAIL_FROM,
|
from: secrets.MAILER_FROM,
|
||||||
to,
|
to,
|
||||||
subject,
|
subject,
|
||||||
html,
|
html,
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"
|
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"
|
||||||
|
import {secrets} from "./secrets";
|
||||||
|
|
||||||
export const s3 = new S3Client({
|
|
||||||
endpoint: process.env.S3_ENDPOINT || "https://fedeo.nbg1.your-objectstorage.com", // z. B. http://localhost:9000 für MinIO
|
|
||||||
region: process.env.S3_REGION || "eu-central",
|
export let s3 = null
|
||||||
credentials: {
|
|
||||||
accessKeyId: process.env.S3_ACCESS_KEY || "RYOMQRW8KSTY3UQX7RPJ",
|
export const initS3 = async () => {
|
||||||
secretAccessKey: process.env.S3_SECRET_KEY || "aZ33xBv47sPPsHuFKeHSDiLagjqF7nShnuGkj7B1",
|
s3 = new S3Client({
|
||||||
},
|
endpoint: secrets.S3_ENDPOINT, // z. B. http://localhost:9000 für MinIO
|
||||||
forcePathStyle: true, // wichtig für MinIO
|
region: secrets.S3_REGION,
|
||||||
})
|
credentials: {
|
||||||
|
accessKeyId: secrets.S3_ACCESS_KEY,
|
||||||
|
secretAccessKey: secrets.S3_SECRET_KEY,
|
||||||
|
},
|
||||||
|
forcePathStyle: true, // wichtig für MinIO
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
29
src/utils/secrets.ts
Normal file
29
src/utils/secrets.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import {InfisicalSDK} from "@infisical/sdk"
|
||||||
|
|
||||||
|
const client = new InfisicalSDK({
|
||||||
|
siteUrl: "https://secrets.fedeo.io"
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export let secrets = {}
|
||||||
|
|
||||||
|
export async function loadSecrets () {
|
||||||
|
|
||||||
|
await client.auth().universalAuth.login({
|
||||||
|
clientId: process.env.INFISICAL_CLIENT_ID,
|
||||||
|
clientSecret: process.env.INFISICAL_CLIENT_SECRET,
|
||||||
|
});
|
||||||
|
|
||||||
|
const allSecrets = await client.secrets().listSecrets({
|
||||||
|
environment: "dev", // stg, dev, prod, or custom environment slugs
|
||||||
|
projectId: "39774094-2aaf-49fb-a213-d6b2c10f6144"
|
||||||
|
});
|
||||||
|
|
||||||
|
allSecrets.secrets.forEach(secret => {
|
||||||
|
secrets[secret.secretKey] = secret.secretValue
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log("✅ Secrets aus Infisical geladen");
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user