Skip to content
Snippets Groups Projects
Commit 56a7e34c authored by Berend Sliedrecht's avatar Berend Sliedrecht
Browse files

feat(ssi-abstraction): integrate revocation and minio server


Signed-off-by: default avatarBerend Sliedrecht <berend@animo.id>
parent 9cd9dc83
No related branches found
No related tags found
1 merge request!25feat(ssi): revocation ssi-abstraction
......@@ -34,8 +34,8 @@
"@ocm/shared": "workspace:*",
"axios": "^1.6.2",
"express": "^4.17.3",
"form-data": "^4.0.0",
"joi": "^17.6.0",
"minio": "^7.1.3",
"nats": "^2.18.0",
"rxjs": "^7.2.0",
"winston": "^3.11.0"
......
......@@ -2,52 +2,8 @@ import type { AnonCredsRevocationRegistryDefinition } from '@credo-ts/anoncreds'
import type { AgentContext } from '@credo-ts/core';
import { BasicTailsFileService } from '@credo-ts/anoncreds';
import FormData from 'form-data';
import fs from 'fs';
export type UploadToS3Options = {
s3Url: string;
bucketName: string;
fileId: string;
content: Uint8Array;
accessKey: string;
secret: string;
};
// Upload to S3 and return the URL to fetch it from
export const uploadToS3 = async ({
s3Url,
content,
fileId,
bucketName,
accessKey,
secret,
}: UploadToS3Options) => {
// TODO: double check all headers
const headers = new Headers();
headers.set('Host', s3Url);
headers.set('Date', generateRfc1123Date());
headers.set('Content-Type', 'application/octet-stream');
headers.set('Authorization', accessKey);
headers.set('Secret', secret);
const sanitizedUrl = s3Url.endsWith('/')
? s3Url.slice(0, s3Url.length - 1)
: s3Url;
const url = `${sanitizedUrl}/${bucketName}/${fileId}`;
// TODO: check whether we need to include the sig or not
const result = await axios.put(url, content, {
headers,
});
if (result.status > 299) {
throw new Error(`Error uploading to S3. Error: ${JSON.stringify(result)}`);
}
return url;
};
import { Client } from 'minio';
export class S3TailsFileService extends BasicTailsFileService {
private tailsServerBaseUrl: string;
......@@ -79,64 +35,35 @@ export class S3TailsFileService extends BasicTailsFileService {
revocationRegistryDefinition: AnonCredsRevocationRegistryDefinition;
},
) {
const headers = this.prepareS3Headers(
this.tailsServerBaseUrl,
this.s3Secrets.s3AccessKey,
this.s3Secrets.s3Secret,
);
const url = new URL(this.tailsServerBaseUrl);
const useSSL = url.protocol === 'https:';
const [endPoint, port] = url.host.split(':');
const client = new Client({
endPoint,
port: port ? Number(port) : undefined,
useSSL,
accessKey: this.s3Secrets.s3AccessKey,
secretKey: this.s3Secrets.s3Secret,
});
const revocationRegistryDefinition = options.revocationRegistryDefinition;
const localTailsFilePath = revocationRegistryDefinition.value.tailsLocation;
const pathParts = localTailsFilePath.split('/');
const tailsFileId = pathParts[pathParts.length - 1];
const data = new FormData();
const readStream = fs.createReadStream(localTailsFilePath);
data.append('file', readStream);
const tailsFileUrl = `${this.tailsServerBaseUrl}/${this.tailsServerBucketName}/${tailsFileId}`;
const response = await agentContext.config.agentDependencies.fetch(
tailsFileUrl,
{
method: 'PUT',
body: data,
headers,
},
agentContext.config.logger.debug(
`Uploading tails file to: ${tailsFileUrl}`,
);
if (response.status !== 200) {
throw new Error('Cannot upload tails file');
}
await client.putObject(this.tailsServerBucketName, tailsFileId, readStream);
return {
tailsFileUrl,
};
}
private prepareS3Headers(url: string, accessKey: string, secret: string) {
const rfc1123Date =
new Date()
.toLocaleString('en-GB', {
timeZone: 'UTC',
hour12: false,
weekday: 'short',
year: 'numeric',
month: 'short',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
})
.replace(/(?:(\d),)/, '$1') + ' GMT';
// TODO: double check all headers
const headers = new Headers();
headers.set('Host', url);
headers.set('Date', rfc1123Date);
headers.set('Content-Type', 'application/octet-stream');
headers.set('Authorization', accessKey);
headers.set('Secret', secret);
return headers;
}
}
......@@ -9,12 +9,12 @@ const mockConfig = (port: number = 3001, withLedger = false): AppConfig => ({
agentHost: '',
port: 3000,
s3: {
secret: 'some-secret',
accessKey: 'some-access-key',
secret: 'very-long-secret-key',
accessKey: 'ssi-abstraction',
},
tailsServer: {
baseUrl: 'http://localhost:8080',
bucketName: 'tails',
baseUrl: 'http://localhost:9000',
bucketName: 'ssi',
},
jwtSecret: '',
nats: {
......
......@@ -6,13 +6,17 @@ services:
ports:
- '4222:4222' #Nats server port
- '8222:8222' #Nats server Monitoring port
command: [
"--config", "nats-server.conf",
"--debug",
"--trace",
"--user", "nats_user",
"--pass", "Rw+dYIymAQm9H6ELLNwSuGo1812jqQ=="
]
command:
[
'--config',
'nats-server.conf',
'--debug',
'--trace',
'--user',
'nats_user',
'--pass',
'Rw+dYIymAQm9H6ELLNwSuGo1812jqQ==',
]
s3:
image: minio/minio
......@@ -22,7 +26,7 @@ services:
environment:
MINIO_ROOT_USER: minio
MINIO_ROOT_PASSWORD: minio123
command: ["server", "/data", "--console-address", ":9001"]
command: ['server', '/data', '--console-address', ':9001']
volumes:
- /data
......@@ -33,6 +37,8 @@ services:
/usr/bin/mc config host add ssi-s3 http://s3:9000 minio minio123;
/usr/bin/mc mb --ignore-existing ssi-s3/ssi;
/usr/bin/mc anonymous set download ssi-s3/ssi;
/usr/bin/mc admin user add ssi-s3 ssi-abstraction very-long-secret-key;
/usr/bin/mc admin policy attach ssi-s3 readwrite --user=ssi-abstraction;
exit 0;
"
depends_on:
......
......@@ -583,12 +583,12 @@ importers:
express:
specifier: ^4.17.3
version: 4.18.2
form-data:
specifier: ^4.0.0
version: 4.0.0
joi:
specifier: ^17.6.0
version: 17.11.1
minio:
specifier: ^7.1.3
version: 7.1.3
nats:
specifier: ^2.18.0
version: 2.19.0
......@@ -5847,6 +5847,12 @@ packages:
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
dev: true
 
/@zxing/text-encoding@0.9.0:
resolution: {integrity: sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==}
requiresBuild: true
dev: false
optional: true
/JSONStream@1.3.5:
resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
hasBin: true
......@@ -6497,6 +6503,12 @@ packages:
inherits: 2.0.4
readable-stream: 3.6.2
 
/block-stream2@2.1.0:
resolution: {integrity: sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==}
dependencies:
readable-stream: 3.6.2
dev: false
/blueimp-md5@2.19.0:
resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==}
dev: false
......@@ -6612,6 +6624,10 @@ packages:
dependencies:
fill-range: 7.0.1
 
/browser-or-node@2.1.1:
resolution: {integrity: sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==}
dev: false
/browserslist@4.22.2:
resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
......@@ -6647,6 +6663,10 @@ packages:
dev: false
optional: true
 
/buffer-crc32@0.2.13:
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
dev: false
/buffer-fill@1.0.0:
resolution: {integrity: sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==}
dev: false
......@@ -8556,7 +8576,6 @@ packages:
dependencies:
strnum: 1.0.5
dev: false
optional: true
 
/fastq@1.16.0:
resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==}
......@@ -9584,6 +9603,19 @@ packages:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'}
 
/ipaddr.js@2.1.0:
resolution: {integrity: sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==}
engines: {node: '>= 10'}
dev: false
/is-arguments@1.1.1:
resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
engines: {node: '>= 0.4'}
dependencies:
call-bind: 1.0.5
has-tostringtag: 1.0.0
dev: false
/is-array-buffer@3.0.2:
resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
dependencies:
......@@ -9687,6 +9719,13 @@ packages:
engines: {node: '>=6'}
dev: true
 
/is-generator-function@1.0.10:
resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==}
engines: {node: '>= 0.4'}
dependencies:
has-tostringtag: 1.0.0
dev: false
/is-glob@2.0.1:
resolution: {integrity: sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==}
engines: {node: '>=0.10.0'}
......@@ -10497,6 +10536,10 @@ packages:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
dev: true
 
/json-stream@1.0.0:
resolution: {integrity: sha512-H/ZGY0nIAg3QcOwE1QN/rK/Fa7gJn7Ii5obwp6zyPO4xiPNwpIMjqy2gwjBEGqzkF/vSWEIBQCBuN19hYiL6Qg==}
dev: false
/json-text-sequence@0.3.0:
resolution: {integrity: sha512-7khKIYPKwXQem4lWXfpIN/FEnhztCeRPSxH4qm3fVlqulwujrRDD54xAwDDn/qVKpFtV550+QAkcWJcufzqQuA==}
engines: {node: '>=10.18.0'}
......@@ -11482,6 +11525,26 @@ packages:
/minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
 
/minio@7.1.3:
resolution: {integrity: sha512-xPrLjWkTT5E7H7VnzOjF//xBp9I40jYB4aWhb2xTFopXXfw+Wo82DDWngdUju7Doy3Wk7R8C4LAgwhLHHnf0wA==}
engines: {node: ^16 || ^18 || >=20}
dependencies:
async: 3.2.5
block-stream2: 2.1.0
browser-or-node: 2.1.1
buffer-crc32: 0.2.13
fast-xml-parser: 4.3.3
ipaddr.js: 2.1.0
json-stream: 1.0.0
lodash: 4.17.21
mime-types: 2.1.35
query-string: 7.1.3
through2: 4.0.2
web-encoding: 1.1.5
xml: 1.0.1
xml2js: 0.5.0
dev: false
/minipass-collect@1.0.2:
resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==}
engines: {node: '>= 8'}
......@@ -13091,7 +13154,6 @@ packages:
/sax@1.3.0:
resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==}
dev: false
optional: true
 
/scheduler@0.24.0-canary-efb381bbf-20230505:
resolution: {integrity: sha512-ABvovCDe/k9IluqSh4/ISoq8tIJnW8euVAWYt5j/bg6dRnqwQwiGO1F/V4AyK96NGF/FB04FhOUDuWj8IKfABA==}
......@@ -13663,7 +13725,6 @@ packages:
/strnum@1.0.5:
resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==}
dev: false
optional: true
 
/strtok3@7.0.0:
resolution: {integrity: sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==}
......@@ -13964,7 +14025,6 @@ packages:
resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==}
dependencies:
readable-stream: 3.6.2
dev: true
 
/through@2.3.8:
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
......@@ -14427,6 +14487,16 @@ packages:
/util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
 
/util@0.12.5:
resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==}
dependencies:
inherits: 2.0.4
is-arguments: 1.1.1
is-generator-function: 1.0.10
is-typed-array: 1.1.12
which-typed-array: 1.1.13
dev: false
/utils-merge@1.0.1:
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
engines: {node: '>= 0.4.0'}
......@@ -14593,6 +14663,14 @@ packages:
- encoding
dev: false
 
/web-encoding@1.1.5:
resolution: {integrity: sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==}
dependencies:
util: 0.12.5
optionalDependencies:
'@zxing/text-encoding': 0.9.0
dev: false
/web-streams-polyfill@3.3.2:
resolution: {integrity: sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==}
engines: {node: '>= 8'}
......@@ -14906,6 +14984,14 @@ packages:
dev: false
optional: true
 
/xml2js@0.5.0:
resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==}
engines: {node: '>=4.0.0'}
dependencies:
sax: 1.3.0
xmlbuilder: 11.0.1
dev: false
/xml2js@0.6.0:
resolution: {integrity: sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==}
engines: {node: '>=4.0.0'}
......@@ -14915,11 +15001,14 @@ packages:
dev: false
optional: true
 
/xml@1.0.1:
resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==}
dev: false
/xmlbuilder@11.0.1:
resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==}
engines: {node: '>=4.0'}
dev: false
optional: true
 
/xmlbuilder@14.0.0:
resolution: {integrity: sha512-ts+B2rSe4fIckR6iquDjsKbQFK2NlUk6iG5nf14mDEyldgoc2nEKZ3jZWMPTxGQwVgToSjt6VGIho1H8/fNFTg==}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment