minio_s3_storage
This commit is contained in:
parent
aef4a3ec8b
commit
d5a649da82
420
Channel-Backend/package-lock.json
generated
420
Channel-Backend/package-lock.json
generated
@ -8,6 +8,8 @@
|
||||
"name": "channel-server",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.1083.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.1083.0",
|
||||
"@prisma/adapter-pg": "^7.8.0",
|
||||
"@prisma/client": "^7.8.0",
|
||||
"bcrypt": "^6.0.0",
|
||||
@ -36,6 +38,331 @@
|
||||
"typescript": "^5.4.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/checksums": {
|
||||
"version": "3.1000.16",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/checksums/-/checksums-3.1000.16.tgz",
|
||||
"integrity": "sha512-EKnvkXSmz3IpA99tCNuI+dLFXyZyClSm8zns9sB/elvkU+MTuomAs6toJMPMBf98/fICG/urXDkzGz0/c3yyAQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/client-s3": {
|
||||
"version": "3.1083.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1083.0.tgz",
|
||||
"integrity": "sha512-3YOicHy6qjexsy4rHk5jPvtLgg6Ho1u+ycOWtJcVTAIMlMq32MRtnhllAyFSezhAXeBnnLLtKtAGXim7vV8oog==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/checksums": "^3.1000.16",
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/credential-provider-node": "^3.972.66",
|
||||
"@aws-sdk/middleware-sdk-s3": "^3.972.62",
|
||||
"@aws-sdk/signature-v4-multi-region": "^3.996.39",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/fetch-http-handler": "^5.6.4",
|
||||
"@smithy/node-http-handler": "^4.9.4",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/core": {
|
||||
"version": "3.975.1",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.975.1.tgz",
|
||||
"integrity": "sha512-8qh/6EYb7hl/ZwVfQufhbMEZs1gQIc7GbdrIf4eprQJ7cv042+74nE6l3YDfyWNzb9iPXb8fRyYSHkNIk5eE6Q==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@aws-sdk/xml-builder": "^3.972.34",
|
||||
"@aws/lambda-invoke-store": "^0.3.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/signature-v4": "^5.6.3",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"bowser": "^2.11.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/credential-provider-env": {
|
||||
"version": "3.972.57",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.57.tgz",
|
||||
"integrity": "sha512-1RfJaF7SW1TOnvNGU7kaYjwUf5H3sfm+synGH1bHhRlqcnxCt3szebH3dmKEyY4tuGcbQ6ffzUT89cRitBV8OQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/credential-provider-http": {
|
||||
"version": "3.972.59",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.59.tgz",
|
||||
"integrity": "sha512-sRCkpTiFnCdQvuaRVjQ6SVoHu6i7RUpurVo1c4F81HWhPvUJ7Wdp5MNtSdX1O29CNXc8em3O5m52hCjVtAD9SA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/fetch-http-handler": "^5.6.4",
|
||||
"@smithy/node-http-handler": "^4.9.4",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/credential-provider-ini": {
|
||||
"version": "3.973.1",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.973.1.tgz",
|
||||
"integrity": "sha512-6d8H6ZAh3ZPKZ6fe1nG2OWeZEZPtt9ravoD1dezPdPtsSkJRoxGAnFSHwKT3E/Te6fHE30zRzjV6TD12rvF6yQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/credential-provider-env": "^3.972.57",
|
||||
"@aws-sdk/credential-provider-http": "^3.972.59",
|
||||
"@aws-sdk/credential-provider-login": "^3.972.63",
|
||||
"@aws-sdk/credential-provider-process": "^3.972.57",
|
||||
"@aws-sdk/credential-provider-sso": "^3.973.1",
|
||||
"@aws-sdk/credential-provider-web-identity": "^3.972.63",
|
||||
"@aws-sdk/nested-clients": "^3.997.31",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/credential-provider-imds": "^4.4.7",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/credential-provider-login": {
|
||||
"version": "3.972.63",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.63.tgz",
|
||||
"integrity": "sha512-GREWRrMj0XnNKMaVa/Mauoaui26qBEHu71WWqXbwZOu/jFQOnPZjTf7u0KtGKC8VGa6VUs9kDWGgocrKNLS9vw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/nested-clients": "^3.997.31",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/credential-provider-node": {
|
||||
"version": "3.972.66",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.66.tgz",
|
||||
"integrity": "sha512-f+qjRXZpz7sgzbc4QB+6nLKfyKFgRRXzWdXbsKPv/VhVRyHsDyq4yBWC/B75BAJpFIcUeI2XR/3gdWJ677zB4A==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/credential-provider-env": "^3.972.57",
|
||||
"@aws-sdk/credential-provider-http": "^3.972.59",
|
||||
"@aws-sdk/credential-provider-ini": "^3.973.1",
|
||||
"@aws-sdk/credential-provider-process": "^3.972.57",
|
||||
"@aws-sdk/credential-provider-sso": "^3.973.1",
|
||||
"@aws-sdk/credential-provider-web-identity": "^3.972.63",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/credential-provider-imds": "^4.4.7",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/credential-provider-process": {
|
||||
"version": "3.972.57",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.57.tgz",
|
||||
"integrity": "sha512-TiVQhuU0pbhIZAUZacbPHMyzrIdiH+lnx+PMY/Pu/b93dJrq3wdZwzUJ0TPpvNxaqbHsxJvQZW3/h/beLiKq7Q==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/credential-provider-sso": {
|
||||
"version": "3.973.1",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.973.1.tgz",
|
||||
"integrity": "sha512-3foTZUJ4821Ij60X7K3NJroygiZLnbBmarN+T//O2cjkISan90zElN3NBmgSlDrTQ7Gs6z/yO8V7h60QNcDZHQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/nested-clients": "^3.997.31",
|
||||
"@aws-sdk/token-providers": "3.1083.0",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/credential-provider-web-identity": {
|
||||
"version": "3.972.63",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.63.tgz",
|
||||
"integrity": "sha512-8qZLFhM69eKcS37m459ctPR05Qimycm/74OPVioe6wNZabMT54GYhwBju0+J656RkMasNSawWQu+c8CmBe3TUQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/nested-clients": "^3.997.31",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/middleware-sdk-s3": {
|
||||
"version": "3.972.62",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.62.tgz",
|
||||
"integrity": "sha512-k8JJwYXVYlOOjWnPZDThQS1xDFJgi5Dokt73qFlDtrZAbdcint5aIdjB9XgJAAQVP5OoqcefQmh1FYXiPpvsvw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/signature-v4-multi-region": "^3.996.39",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/nested-clients": {
|
||||
"version": "3.997.31",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.31.tgz",
|
||||
"integrity": "sha512-BDHTpwcsZHEBNEJzOg/B1BkFYJxAXY50dau/NyVWs3d51F0WgIUGSWZot/Os+N3KpDhXeaXnz37mWffAvduREw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/signature-v4-multi-region": "^3.996.39",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/fetch-http-handler": "^5.6.4",
|
||||
"@smithy/node-http-handler": "^4.9.4",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/s3-request-presigner": {
|
||||
"version": "3.1083.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.1083.0.tgz",
|
||||
"integrity": "sha512-gVyNRD1b3R2egLMsCR9WGRghNtesNGXEojBOUdCsi/tnR1zlEDyxJCVBCIyvsN2Yxre0+CUt0RSZmtD7SpJ3Fg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/signature-v4-multi-region": "^3.996.39",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/signature-v4-multi-region": {
|
||||
"version": "3.996.39",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.39.tgz",
|
||||
"integrity": "sha512-8+srXqYIF8KYMLC4FxMLEM5Ek7kUNibJu1R4m8/fUhhNYIZZz26oGtKkCr8I/HiG2fFQxBvaGgQZT4/mqRCSnA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/signature-v4": "^5.6.3",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/token-providers": {
|
||||
"version": "3.1083.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1083.0.tgz",
|
||||
"integrity": "sha512-s0woKnxuHrExLc5L2ArIH5BMkbonHPtt+5hSBM8oknp9M6QTuUmmAmJ2E0EdzCGONrO+8+ADPqvv6UX0nNcc7A==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/core": "^3.975.1",
|
||||
"@aws-sdk/nested-clients": "^3.997.31",
|
||||
"@aws-sdk/types": "^3.974.0",
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/types": {
|
||||
"version": "3.974.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.974.0.tgz",
|
||||
"integrity": "sha512-QIBrw90CDm4O0UaIIzkU6DrFdeJzEb2Va5EPEVpyldj6sHJxB6cshhStJuhZxk3wR3PmjJlYsjPmY1kNb+KGBg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/xml-builder": {
|
||||
"version": "3.972.34",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.34.tgz",
|
||||
"integrity": "sha512-wHhWL1y7sN3enBA8POrPpQM5jCcmu2ozyhbRei4c8OjVcEaEs6yLucLa/pla457ggS/ysuy7bosagz3HaJkZXA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws/lambda-invoke-store": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.3.0.tgz",
|
||||
"integrity": "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
@ -484,6 +811,87 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@smithy/core": {
|
||||
"version": "3.29.2",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.29.2.tgz",
|
||||
"integrity": "sha512-DXUk6yU0C1Q1tYvJh1VCtl8QOBcSoZpKwjTPkxT6A4MUQYHvgeKGByL8mrEdxnvhdf9nq5GyzmRb5n/vPgu3Lw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@smithy/credential-provider-imds": {
|
||||
"version": "4.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.4.7.tgz",
|
||||
"integrity": "sha512-UEMLOoA0Fl4uYBxh6l0uN0H6EJe/A89OGeDNTteQeXpJ20BcpfIr4wlCY9pel1jEAUHAxaYwuqrYlrKdXE1GKQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@smithy/fetch-http-handler": {
|
||||
"version": "5.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.6.4.tgz",
|
||||
"integrity": "sha512-psnst7NZWdAEvJvyW8YZEE7xNVMyLrQFfHtyrVFrxNyy+dKWkQ+rqC6oI5ZhxThpUy9RSfEshgm34zqbOxzsRw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@smithy/node-http-handler": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.9.4.tgz",
|
||||
"integrity": "sha512-BNTop/fSOptmoVk8g+efwHCofFh37g70OWGAFES1TeAAJja1K5aAI8rTE26ETSc5k8IQuWY2kAIoPla01NgYrA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@smithy/signature-v4": {
|
||||
"version": "5.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.6.3.tgz",
|
||||
"integrity": "sha512-8qVKKzqh7naF27ePmx0SkUfnGP/wBI9dyaeAmhHvopnbIlItUAmB/e6PkPCU3rRb2v9BY8D4EZXSoydSibatvw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/core": "^3.29.2",
|
||||
"@smithy/types": "^4.16.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@smithy/types": {
|
||||
"version": "4.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.16.0.tgz",
|
||||
"integrity": "sha512-aVUabzlBBmY0PfvVgLKQSOGFIL5/7R54JE3uD9a5Ay/jSED61SkuAcCYENNXJzYUvJ1NPrWO0P+rAXHCkbBUKw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@standard-schema/spec": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
|
||||
@ -883,6 +1291,12 @@
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/bowser": {
|
||||
"version": "2.14.1",
|
||||
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz",
|
||||
"integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "5.0.7",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz",
|
||||
@ -3114,6 +3528,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
|
||||
@ -9,6 +9,8 @@
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.1083.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.1083.0",
|
||||
"@prisma/adapter-pg": "^7.8.0",
|
||||
"@prisma/client": "^7.8.0",
|
||||
"bcrypt": "^6.0.0",
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import express, { Express, Request, Response } from 'express';
|
||||
import express, { Express, Request, Response, NextFunction } from 'express';
|
||||
import cors from 'cors';
|
||||
import helmet from 'helmet';
|
||||
import dotenv from 'dotenv';
|
||||
import path from 'path';
|
||||
import cookieParser from 'cookie-parser';
|
||||
import { Readable } from 'stream';
|
||||
import { GetObjectCommand } from '@aws-sdk/client-s3';
|
||||
import { s3Client, BUCKET_NAME } from './utils/s3';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
@ -13,6 +16,8 @@ import assetRoutes from './routes/asset.routes';
|
||||
import orgRoutes from './routes/organization.routes';
|
||||
import legalRoutes from './routes/legal.routes';
|
||||
|
||||
import { ensureBucketExists } from './utils/s3';
|
||||
|
||||
const app: Express = express();
|
||||
const PORT = process.env.PORT || 5000;
|
||||
|
||||
@ -32,8 +37,45 @@ app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
app.use(cookieParser());
|
||||
|
||||
// Static uploads directory
|
||||
app.use('/uploads', express.static(path.join(__dirname, '../../uploads')));
|
||||
// Dynamic MinIO object delivery handler
|
||||
app.get('/uploads/:filename', async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const filename = req.params.filename;
|
||||
const command = new GetObjectCommand({
|
||||
Bucket: BUCKET_NAME,
|
||||
Key: filename,
|
||||
});
|
||||
|
||||
const s3Response = await s3Client.send(command);
|
||||
|
||||
if (s3Response.ContentType) {
|
||||
res.setHeader('Content-Type', s3Response.ContentType);
|
||||
}
|
||||
if (s3Response.ContentLength) {
|
||||
res.setHeader('Content-Length', s3Response.ContentLength);
|
||||
}
|
||||
res.setHeader('Accept-Ranges', 'bytes');
|
||||
|
||||
if (s3Response.Body instanceof Readable) {
|
||||
s3Response.Body.pipe(res);
|
||||
} else if (s3Response.Body) {
|
||||
const body = s3Response.Body as any;
|
||||
if (typeof body.pipe === 'function') {
|
||||
body.pipe(res);
|
||||
} else {
|
||||
res.send(await s3Response.Body.transformToByteArray());
|
||||
}
|
||||
} else {
|
||||
res.status(404).send('Not found');
|
||||
}
|
||||
} catch (err: any) {
|
||||
if (err.name === 'NoSuchKey' || err.$metadata?.httpStatusCode === 404) {
|
||||
res.status(404).send('File not found in storage');
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// API Routes
|
||||
app.use('/api/v1/auth', authRoutes);
|
||||
@ -57,6 +99,7 @@ if (process.env.NODE_ENV === 'production') {
|
||||
});
|
||||
}
|
||||
|
||||
app.listen(PORT, () => {
|
||||
app.listen(PORT, async () => {
|
||||
console.log(`[Server]: API is running on http://localhost:${PORT}`);
|
||||
await ensureBucketExists();
|
||||
});
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
import { Response, NextFunction } from 'express';
|
||||
import path from 'path';
|
||||
import { PutObjectCommand } from '@aws-sdk/client-s3';
|
||||
import { s3Client, BUCKET_NAME } from '../utils/s3';
|
||||
import { AssetService } from '../services/asset.service';
|
||||
import { AuthRequest } from '../middleware/auth.middleware';
|
||||
|
||||
@ -21,11 +24,28 @@ export class AssetController {
|
||||
try { shares = JSON.parse(shares); } catch { shares = undefined; }
|
||||
}
|
||||
|
||||
let fileUrl = '';
|
||||
if (!isUrlAsset && req.file) {
|
||||
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
|
||||
const filename = uniqueSuffix + path.extname(req.file.originalname);
|
||||
|
||||
await s3Client.send(new PutObjectCommand({
|
||||
Bucket: BUCKET_NAME,
|
||||
Key: filename,
|
||||
Body: req.file.buffer,
|
||||
ContentType: req.file.mimetype,
|
||||
}));
|
||||
|
||||
fileUrl = `/uploads/${filename}`;
|
||||
} else {
|
||||
fileUrl = req.body.url;
|
||||
}
|
||||
|
||||
const assetData = {
|
||||
title: req.body.title || (req.file ? req.file.originalname : 'URL Asset'),
|
||||
type: isUrlAsset ? 'url' : req.file!.mimetype,
|
||||
size: isUrlAsset ? 0 : req.file!.size,
|
||||
url: isUrlAsset ? req.body.url : `/uploads/${req.file!.filename}`,
|
||||
url: fileUrl,
|
||||
uploadedBy: uploaderId,
|
||||
description: req.body.description || null,
|
||||
categoryId: req.body.categoryId || null,
|
||||
|
||||
@ -1,19 +1,5 @@
|
||||
import multer from 'multer';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
const storage = multer.diskStorage({
|
||||
destination: (req, file, cb) => {
|
||||
const uploadDir = path.join(__dirname, '../../../uploads');
|
||||
if (!fs.existsSync(uploadDir)) {
|
||||
fs.mkdirSync(uploadDir, { recursive: true });
|
||||
}
|
||||
cb(null, uploadDir);
|
||||
},
|
||||
filename: (req, file, cb) => {
|
||||
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
|
||||
cb(null, uniqueSuffix + path.extname(file.originalname));
|
||||
},
|
||||
});
|
||||
const storage = multer.memoryStorage();
|
||||
|
||||
export const upload = multer({ storage });
|
||||
|
||||
57
Channel-Backend/src/seed-minio.ts
Normal file
57
Channel-Backend/src/seed-minio.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { PutObjectCommand } from '@aws-sdk/client-s3';
|
||||
import { s3Client, BUCKET_NAME, ensureBucketExists } from './utils/s3';
|
||||
|
||||
async function migrateLocalUploads() {
|
||||
console.log('[Migration] Starting local uploads migration to MinIO...');
|
||||
await ensureBucketExists();
|
||||
|
||||
const localUploadsDir = path.join(__dirname, '../../uploads');
|
||||
if (!fs.existsSync(localUploadsDir)) {
|
||||
console.log('[Migration] No local uploads directory found.');
|
||||
return;
|
||||
}
|
||||
|
||||
const files = fs.readdirSync(localUploadsDir);
|
||||
console.log(`[Migration] Found ${files.length} local files.`);
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = path.join(localUploadsDir, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
|
||||
if (stat.isFile()) {
|
||||
console.log(`[Migration] Uploading "${file}" to MinIO bucket "${BUCKET_NAME}"...`);
|
||||
const fileBuffer = fs.readFileSync(filePath);
|
||||
|
||||
let contentType = 'application/octet-stream';
|
||||
if (file.endsWith('.pdf')) {
|
||||
contentType = 'application/pdf';
|
||||
} else if (file.endsWith('.png')) {
|
||||
contentType = 'image/png';
|
||||
} else if (file.endsWith('.jpg') || file.endsWith('.jpeg')) {
|
||||
contentType = 'image/jpeg';
|
||||
} else if (file.endsWith('.md')) {
|
||||
contentType = 'text/markdown';
|
||||
} else if (file.endsWith('.docx')) {
|
||||
contentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
|
||||
}
|
||||
|
||||
try {
|
||||
await s3Client.send(new PutObjectCommand({
|
||||
Bucket: BUCKET_NAME,
|
||||
Key: file,
|
||||
Body: fileBuffer,
|
||||
ContentType: contentType,
|
||||
}));
|
||||
console.log(`[Migration] Successfully uploaded "${file}".`);
|
||||
} catch (err) {
|
||||
console.error(`[Migration] Failed to upload "${file}":`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[Migration] Migration complete.');
|
||||
}
|
||||
|
||||
migrateLocalUploads().catch(console.error);
|
||||
36
Channel-Backend/src/utils/s3.ts
Normal file
36
Channel-Backend/src/utils/s3.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { S3Client, CreateBucketCommand, HeadBucketCommand } from '@aws-sdk/client-s3';
|
||||
|
||||
const minioEndpoint = process.env.MINIO_ENDPOINT || 'http://localhost:9000';
|
||||
const accessKeyId = process.env.MINIO_ACCESS_KEY || 'minio_admin';
|
||||
const secretAccessKey = process.env.MINIO_SECRET_KEY || 'minio_password_2026';
|
||||
export const BUCKET_NAME = process.env.MINIO_BUCKET || 'secure-assets';
|
||||
|
||||
export const s3Client = new S3Client({
|
||||
endpoint: minioEndpoint,
|
||||
region: 'us-east-1',
|
||||
credentials: {
|
||||
accessKeyId,
|
||||
secretAccessKey,
|
||||
},
|
||||
forcePathStyle: true,
|
||||
});
|
||||
|
||||
export async function ensureBucketExists() {
|
||||
try {
|
||||
await s3Client.send(new HeadBucketCommand({ Bucket: BUCKET_NAME }));
|
||||
console.log(`[MinIO] Bucket "${BUCKET_NAME}" already exists.`);
|
||||
} catch (err: any) {
|
||||
// If the bucket doesn't exist, create it
|
||||
if (err.name === 'NotFound' || err.$metadata?.httpStatusCode === 404) {
|
||||
console.log(`[MinIO] Bucket "${BUCKET_NAME}" not found. Creating it...`);
|
||||
try {
|
||||
await s3Client.send(new CreateBucketCommand({ Bucket: BUCKET_NAME }));
|
||||
console.log(`[MinIO] Bucket "${BUCKET_NAME}" created successfully.`);
|
||||
} catch (createErr) {
|
||||
console.error(`[MinIO] Failed to create bucket "${BUCKET_NAME}":`, createErr);
|
||||
}
|
||||
} else {
|
||||
console.error('[MinIO] HeadBucket error:', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14,5 +14,20 @@ services:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
container_name: channel_minio
|
||||
ports:
|
||||
- "9000:9000"
|
||||
- "9090:9001"
|
||||
environment:
|
||||
MINIO_ROOT_USER: minio_admin
|
||||
MINIO_ROOT_PASSWORD: minio_password_2026
|
||||
volumes:
|
||||
- minio_data:/data
|
||||
command: server /data --console-address ":9001"
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
minio_data:
|
||||
|
||||
@ -24,9 +24,9 @@ if ! docker info &> /dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. Spin up PostgreSQL container
|
||||
info "Starting PostgreSQL container via docker-compose..."
|
||||
docker compose up -d postgres || docker-compose up -d postgres
|
||||
# 3. Spin up PostgreSQL & MinIO containers
|
||||
info "Starting database and storage services via docker-compose..."
|
||||
docker compose up -d || docker-compose up -d
|
||||
|
||||
# 4. Wait for PostgreSQL to be ready inside container
|
||||
info "Waiting for database to accept connections..."
|
||||
@ -50,6 +50,10 @@ PORT=5000
|
||||
DATABASE_URL="postgresql://pipeline_admin:secure_pipeline_2024@localhost:5433/backend_channel?schema=public"
|
||||
JWT_SECRET="super-secret-jwt-key-2026-world-class"
|
||||
NODE_ENV="development"
|
||||
MINIO_ENDPOINT="http://localhost:9000"
|
||||
MINIO_ACCESS_KEY="minio_admin"
|
||||
MINIO_SECRET_KEY="minio_password_2026"
|
||||
MINIO_BUCKET="secure-assets"
|
||||
EOT
|
||||
else
|
||||
info "Channel-Backend/.env file already exists."
|
||||
|
||||
Loading…
Reference in New Issue
Block a user