@cooperation/vc-storage 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +136 -0
- package/dist/index.js +3 -0
- package/dist/models/CredentialEngine.js +187 -0
- package/dist/models/CredentialVerefier.js +36 -0
- package/dist/models/GoogleDriveStorage.js +174 -0
- package/dist/models/StorageContext.js +50 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/models/CredentialEngine.d.ts +45 -0
- package/dist/types/models/CredentialVerefier.d.ts +9 -0
- package/dist/types/models/GoogleDriveStorage.d.ts +17 -0
- package/dist/types/models/StorageContext.d.ts +0 -0
- package/dist/types/utils/context.d.ts +538 -0
- package/dist/types/utils/saveToGoogle.d.ts +10 -0
- package/dist/utils/context.js +539 -0
- package/dist/utils/saveToGoogle.js +53 -0
- package/package.json +43 -0
package/README.md
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
# Trust Storage Library
|
2
|
+
|
3
|
+
Store your files using up to three strategies. Currently, we offer the GoogleDriveStorage class, which is designed for storing files in Google Drive. Stay tuned for additional methods coming soon 😊
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
To install the Trust Storage library, you can use either npm or yarn. Run one of the following commands in your project directory:
|
8
|
+
|
9
|
+
```bash
|
10
|
+
npm install trust_storage
|
11
|
+
```
|
12
|
+
|
13
|
+
or
|
14
|
+
|
15
|
+
```bash
|
16
|
+
yarn add trust_storage
|
17
|
+
```
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
To use the `GoogleDriveStorage` class in your application, you need to pass an access token that has appropriate permissions for Google Drive operations. You can generate an access token by following these steps:
|
22
|
+
|
23
|
+
1. Visit the [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/).
|
24
|
+
2. Enter the scope: `https://www.googleapis.com/auth/drive`.
|
25
|
+
3. Copy the accessToken and pass it to the `GoogleDriveStorage` class.
|
26
|
+
|
27
|
+
The `GoogleDriveStorage` class includes two methods:
|
28
|
+
|
29
|
+
- `createFolder()`: It is designed to create a new folder in Google Drive.
|
30
|
+
- `uploadFile()`: Ensure that the necessary folder has been created or identified where the file will be stored.
|
31
|
+
|
32
|
+
## Notes
|
33
|
+
|
34
|
+
- This library is a demonstration tool for uploading files to Google Drive.
|
35
|
+
|
36
|
+
### Your First Code Contribution
|
37
|
+
|
38
|
+
1. Clone the repository.
|
39
|
+
2. Run yarn or npm install to install dependencies.
|
40
|
+
3. Create a new branch for your feature or bugfix.
|
41
|
+
4. Make your changes.
|
42
|
+
5. Commit your changes and push your branch to your fork.
|
43
|
+
6. Open a pull request.
|
44
|
+
|
45
|
+
### Pull Requests
|
46
|
+
|
47
|
+
When you're ready to submit your pull request:
|
48
|
+
|
49
|
+
1. Ensure your work is aligned with the project's coding standards.
|
50
|
+
2. Fill out the pull request template.
|
51
|
+
3. Include a clear and detailed description of the changes.
|
52
|
+
4. Link any related issues.
|
53
|
+
5. Wait for review and address any feedback.
|
54
|
+
|
55
|
+
## Development Workflow
|
56
|
+
|
57
|
+
### Setup
|
58
|
+
|
59
|
+
1. Clone the repository:
|
60
|
+
```bash
|
61
|
+
git clone https://github.com/yourusername/your-repo-name.git
|
62
|
+
```
|
63
|
+
2. Navigate to the project directory:
|
64
|
+
```bash
|
65
|
+
cd your-repo-name
|
66
|
+
```
|
67
|
+
3. Install dependencies:
|
68
|
+
```bash
|
69
|
+
npm install
|
70
|
+
```
|
71
|
+
|
72
|
+
Certainly! Here is the provided text rewritten in `.md` format:
|
73
|
+
|
74
|
+
````markdown
|
75
|
+
## Publishing Flow
|
76
|
+
|
77
|
+
If you want to publish a new version of the package, please follow these steps:
|
78
|
+
|
79
|
+
### Request Access
|
80
|
+
|
81
|
+
Ask for access to publish the package in the Slack. Mention the version and any significant changes.
|
82
|
+
|
83
|
+
### Update Version
|
84
|
+
|
85
|
+
Ensure you update the version in `package.json` according to [Semantic Versioning](https://semver.org/). You can do this manually or using the npm command:
|
86
|
+
|
87
|
+
```bash
|
88
|
+
npm version [patch|minor|major]
|
89
|
+
```
|
90
|
+
````
|
91
|
+
|
92
|
+
### Ensure Tests Pass
|
93
|
+
|
94
|
+
Run all tests to make sure they are passing:
|
95
|
+
|
96
|
+
```bash
|
97
|
+
npm test
|
98
|
+
```
|
99
|
+
|
100
|
+
### Build the Project
|
101
|
+
|
102
|
+
Build the project to ensure all changes are compiled:
|
103
|
+
|
104
|
+
```bash
|
105
|
+
npm run build
|
106
|
+
```
|
107
|
+
|
108
|
+
### Commit and Push
|
109
|
+
|
110
|
+
Commit and push your changes to the main branch:
|
111
|
+
|
112
|
+
```bash
|
113
|
+
git add .
|
114
|
+
git commit -m "Prepare for release vX.Y.Z"
|
115
|
+
git push origin main
|
116
|
+
```
|
117
|
+
|
118
|
+
### Login to npm
|
119
|
+
|
120
|
+
If you are not already logged in, log in to npm using your credentials:
|
121
|
+
|
122
|
+
```bash
|
123
|
+
npm login
|
124
|
+
```
|
125
|
+
|
126
|
+
### Publish the Package
|
127
|
+
|
128
|
+
Once you have access and everything is set, publish the package:
|
129
|
+
|
130
|
+
```bash
|
131
|
+
npm publish
|
132
|
+
```
|
133
|
+
|
134
|
+
### Notify Team
|
135
|
+
|
136
|
+
Inform the team in the Slack channel that the new version has been published.
|
package/dist/index.js
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
import { Ed25519VerificationKey2020 } from '@digitalbazaar/ed25519-verification-key-2020';
|
2
|
+
import { Ed25519Signature2020 } from '@digitalbazaar/ed25519-signature-2020';
|
3
|
+
import { defaultDocumentLoader, issue } from '@digitalbazaar/vc';
|
4
|
+
import { v4 as uuidv4 } from 'uuid';
|
5
|
+
import { localOBContext, localED25519Context } from '../utils/context.js';
|
6
|
+
// Custom document loader
|
7
|
+
export const customDocumentLoader = async (url) => {
|
8
|
+
const contextMap = {
|
9
|
+
'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json': localOBContext,
|
10
|
+
'https://w3id.org/security/suites/ed25519-2020/v1': localED25519Context,
|
11
|
+
};
|
12
|
+
if (contextMap[url]) {
|
13
|
+
return {
|
14
|
+
contextUrl: null,
|
15
|
+
documentUrl: url,
|
16
|
+
document: contextMap[url],
|
17
|
+
};
|
18
|
+
}
|
19
|
+
return defaultDocumentLoader(url); // Fallback to default loader for unknown URLs
|
20
|
+
};
|
21
|
+
export class CredentialEngine {
|
22
|
+
/**
|
23
|
+
* Create a DID document using the provided key pair.
|
24
|
+
* @param {object} keyPair - The key pair used to create the DID document.
|
25
|
+
* @returns {Promise<object>} The created DID document.
|
26
|
+
*/
|
27
|
+
async generateDIDSchema(keyPair) {
|
28
|
+
try {
|
29
|
+
const DID = keyPair.controller;
|
30
|
+
const didDocument = {
|
31
|
+
'@context': ['https://www.w3.org/ns/did/v1'],
|
32
|
+
id: DID,
|
33
|
+
publicKey: [
|
34
|
+
{
|
35
|
+
id: keyPair.id,
|
36
|
+
type: 'Ed25519VerificationKey2020',
|
37
|
+
controller: DID,
|
38
|
+
publicKeyMultibase: keyPair.publicKeyMultibase,
|
39
|
+
},
|
40
|
+
],
|
41
|
+
authentication: [keyPair.id],
|
42
|
+
assertionMethod: [keyPair.id],
|
43
|
+
capabilityDelegation: [keyPair.id],
|
44
|
+
capabilityInvocation: [keyPair.id],
|
45
|
+
keyAgreement: [
|
46
|
+
{
|
47
|
+
id: `${keyPair.id}-keyAgreement`,
|
48
|
+
type: 'X25519KeyAgreementKey2020',
|
49
|
+
controller: DID,
|
50
|
+
publicKeyMultibase: keyPair.publicKeyMultibase,
|
51
|
+
},
|
52
|
+
],
|
53
|
+
};
|
54
|
+
return didDocument;
|
55
|
+
}
|
56
|
+
catch (error) {
|
57
|
+
console.error('Error creating DID document:', error);
|
58
|
+
throw error;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
/**
|
62
|
+
* Create a new DID with Digital Bazaar's Ed25519VerificationKey2020 key pair.
|
63
|
+
* @returns {Promise<{didDocument: object, keyPair: object}>} The created DID document and key pair.
|
64
|
+
* @throws Will throw an error if DID creation fails.
|
65
|
+
*/
|
66
|
+
async createDID() {
|
67
|
+
try {
|
68
|
+
const keyPair = await Ed25519VerificationKey2020.generate();
|
69
|
+
keyPair.controller = `did:key:${keyPair.publicKeyMultibase}`;
|
70
|
+
keyPair.id = `${keyPair.controller}#${keyPair.publicKeyMultibase}`;
|
71
|
+
keyPair.revoked = false;
|
72
|
+
const didDocument = await this.generateDIDSchema(keyPair);
|
73
|
+
return { didDocument, keyPair };
|
74
|
+
}
|
75
|
+
catch (error) {
|
76
|
+
console.error('Error creating DID:', error);
|
77
|
+
throw error;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
/**
|
81
|
+
* Create a new DID with user metamask address as controller
|
82
|
+
* @param walletrAddress
|
83
|
+
* @returns {Promise<{didDocument: object, keyPair: object}>} The created DID document and key pair.
|
84
|
+
* @throws Will throw an error if DID creation fails.
|
85
|
+
*/
|
86
|
+
async createWalletDID(walletrAddress) {
|
87
|
+
try {
|
88
|
+
const keyPair = await Ed25519VerificationKey2020.generate();
|
89
|
+
keyPair.controler = walletrAddress; // Using the MetaMask address as controller
|
90
|
+
keyPair.id = `${keyPair.controller}#${keyPair.fingerprint()}`;
|
91
|
+
keyPair.revoked = false;
|
92
|
+
const didDocument = await this.generateDIDSchema(keyPair);
|
93
|
+
return { didDocument, keyPair };
|
94
|
+
}
|
95
|
+
catch (error) {
|
96
|
+
console.error('Error creating DID:', error);
|
97
|
+
throw error;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
/**
|
101
|
+
* Create an unsigned Verifiable Credential (VC)
|
102
|
+
* @param {object} formData - The form data to include in the VC.
|
103
|
+
* @param {string} issuerDid - The DID of the issuer.
|
104
|
+
* @returns {Promise<object>} The created unsigned VC.
|
105
|
+
* @throws Will throw an error if unsigned VC creation fails.
|
106
|
+
*/
|
107
|
+
async createUnsignedVC(formData, issuerDid) {
|
108
|
+
try {
|
109
|
+
const issuanceDate = new Date().toISOString();
|
110
|
+
if (issuanceDate > formData.expirationDate)
|
111
|
+
throw Error('issuanceDate cannot be after expirationDate');
|
112
|
+
const unsignedCredential = {
|
113
|
+
'@context': [
|
114
|
+
'https://www.w3.org/2018/credentials/v1',
|
115
|
+
'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json',
|
116
|
+
{
|
117
|
+
duration: 'https://schema.org/duration',
|
118
|
+
fullName: 'https://schema.org/name',
|
119
|
+
portfolio: 'https://schema.org/portfolio',
|
120
|
+
evidenceLink: 'https://schema.org/evidenceLink',
|
121
|
+
evidenceDescription: 'https://schema.org/evidenceDescription',
|
122
|
+
credentialType: 'https://schema.org/credentialType',
|
123
|
+
},
|
124
|
+
],
|
125
|
+
id: `urn:uuid:${uuidv4()}`, // Add the id property
|
126
|
+
type: ['VerifiableCredential', 'OpenBadgeCredential'],
|
127
|
+
issuer: {
|
128
|
+
id: issuerDid,
|
129
|
+
type: ['Profile'],
|
130
|
+
},
|
131
|
+
issuanceDate,
|
132
|
+
expirationDate: formData.expirationDate,
|
133
|
+
credentialSubject: {
|
134
|
+
type: ['AchievementSubject'],
|
135
|
+
name: formData.fullName,
|
136
|
+
portfolio: formData.portfolio,
|
137
|
+
evidenceLink: formData.evidenceLink,
|
138
|
+
evidenceDescription: formData.achievementDescription,
|
139
|
+
duration: formData.duration,
|
140
|
+
credentialType: formData.credentialType,
|
141
|
+
achievement: [
|
142
|
+
{
|
143
|
+
id: `urn:uuid:${uuidv4()}`,
|
144
|
+
type: ['Achievement'],
|
145
|
+
criteria: {
|
146
|
+
narrative: formData.criteriaNarrative,
|
147
|
+
},
|
148
|
+
description: formData.achievementDescription,
|
149
|
+
name: formData.achievementName,
|
150
|
+
image: formData.evidenceLink
|
151
|
+
? {
|
152
|
+
id: formData.evidenceLink,
|
153
|
+
type: 'Image',
|
154
|
+
}
|
155
|
+
: undefined,
|
156
|
+
},
|
157
|
+
],
|
158
|
+
},
|
159
|
+
};
|
160
|
+
console.log('Successfully created Unsigned Credentials', unsignedCredential);
|
161
|
+
return unsignedCredential;
|
162
|
+
}
|
163
|
+
catch (error) {
|
164
|
+
console.error('Error creating unsigned VC', error);
|
165
|
+
throw error;
|
166
|
+
}
|
167
|
+
}
|
168
|
+
/**
|
169
|
+
* Sign a Verifiable Credential (VC)
|
170
|
+
* @param {object} credential - The credential to sign.
|
171
|
+
* @param {object} keyPair - The key pair to use for signing.
|
172
|
+
* @returns {Promise<object>} The signed VC.
|
173
|
+
* @throws Will throw an error if VC signing fails.
|
174
|
+
*/
|
175
|
+
async signVC(credential, keyPair) {
|
176
|
+
const suite = new Ed25519Signature2020({ key: keyPair, verificationMethod: keyPair.id });
|
177
|
+
try {
|
178
|
+
const signedVC = await issue({ credential, suite, documentLoader: customDocumentLoader });
|
179
|
+
console.log('Successfully created Signed VC', signedVC);
|
180
|
+
return signedVC;
|
181
|
+
}
|
182
|
+
catch (error) {
|
183
|
+
console.error('Error signing VC:', error);
|
184
|
+
throw error;
|
185
|
+
}
|
186
|
+
}
|
187
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { Ed25519Signature2020 } from '@digitalbazaar/ed25519-signature-2020';
|
2
|
+
// import { verifyCredential } from '@digitalbazaar/vc';
|
3
|
+
import { customDocumentLoader } from './CredentialEngine';
|
4
|
+
export class CredentialVerifier {
|
5
|
+
/**
|
6
|
+
* Verify a signed Verifiable Credential (VC)
|
7
|
+
* @param {object} signedVC - The signed VC to verify.
|
8
|
+
* @returns {Promise<boolean>} True if the VC is valid, false otherwise.
|
9
|
+
* @throws Will throw an error if VC verification fails.
|
10
|
+
*/
|
11
|
+
async verifyVC(signedVC, keyPair) {
|
12
|
+
const suite = new Ed25519Signature2020({
|
13
|
+
key: keyPair,
|
14
|
+
verificationMethod: keyPair.id,
|
15
|
+
});
|
16
|
+
try {
|
17
|
+
const result = await verifyCredential({
|
18
|
+
credential: signedVC,
|
19
|
+
suite,
|
20
|
+
documentLoader: customDocumentLoader,
|
21
|
+
});
|
22
|
+
if (result.verified) {
|
23
|
+
console.log('VC verification successful');
|
24
|
+
return true;
|
25
|
+
}
|
26
|
+
else {
|
27
|
+
console.log('VC verification failed', result);
|
28
|
+
return false;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
catch (error) {
|
32
|
+
console.error('Error verifying VC:', error);
|
33
|
+
throw error;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
@@ -0,0 +1,174 @@
|
|
1
|
+
export class GoogleDriveStorage {
|
2
|
+
accessToken;
|
3
|
+
constructor(accessToken) {
|
4
|
+
this.accessToken = accessToken;
|
5
|
+
}
|
6
|
+
async fetcher({ method, headers, body, url }) {
|
7
|
+
try {
|
8
|
+
const res = await fetch(url, {
|
9
|
+
method,
|
10
|
+
headers: new Headers({
|
11
|
+
Authorization: `Bearer ${this.accessToken}`,
|
12
|
+
...headers,
|
13
|
+
}),
|
14
|
+
body,
|
15
|
+
});
|
16
|
+
const data = await res.json();
|
17
|
+
if (!res.ok) {
|
18
|
+
throw new Error(data.error.message);
|
19
|
+
}
|
20
|
+
return data;
|
21
|
+
}
|
22
|
+
catch (error) {
|
23
|
+
console.error('Error fetching data:', error);
|
24
|
+
throw error;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
// New method to encapsulate search logic
|
28
|
+
async searchFiles(query) {
|
29
|
+
const result = await this.fetcher({
|
30
|
+
method: 'GET',
|
31
|
+
headers: {},
|
32
|
+
url: `https://www.googleapis.com/drive/v3/files?q=${encodeURIComponent(query)}&trashed=false&fields=files(id,name,mimeType,parents)`,
|
33
|
+
});
|
34
|
+
return result.files;
|
35
|
+
}
|
36
|
+
async createFolder(folderName, parentFolderId) {
|
37
|
+
const metadata = {
|
38
|
+
name: folderName,
|
39
|
+
mimeType: 'application/vnd.google-apps.folder',
|
40
|
+
parents: parentFolderId ? [parentFolderId] : [],
|
41
|
+
};
|
42
|
+
const folder = await this.fetcher({
|
43
|
+
method: 'POST',
|
44
|
+
headers: { 'Content-Type': 'application/json' },
|
45
|
+
body: JSON.stringify(metadata),
|
46
|
+
url: 'https://www.googleapis.com/drive/v3/files',
|
47
|
+
});
|
48
|
+
console.log('Folder ID:', folder.id);
|
49
|
+
return folder.id;
|
50
|
+
}
|
51
|
+
async save(data, folderId) {
|
52
|
+
try {
|
53
|
+
const fileMetadata = {
|
54
|
+
name: data.fileName,
|
55
|
+
mimeType: data.mimeType,
|
56
|
+
parents: [folderId],
|
57
|
+
};
|
58
|
+
const formData = new FormData();
|
59
|
+
formData.append('metadata', new Blob([JSON.stringify(fileMetadata)], { type: 'application/json' }));
|
60
|
+
formData.append('file', data.body);
|
61
|
+
const file = await this.fetcher({
|
62
|
+
method: 'POST',
|
63
|
+
headers: {},
|
64
|
+
body: formData,
|
65
|
+
url: 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart',
|
66
|
+
});
|
67
|
+
console.log('File uploaded:', file.id);
|
68
|
+
return file;
|
69
|
+
}
|
70
|
+
catch (error) {
|
71
|
+
console.error('Error uploading file:', error);
|
72
|
+
return null;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
async retrieve(id) {
|
76
|
+
try {
|
77
|
+
const file = await this.fetcher({
|
78
|
+
method: 'GET',
|
79
|
+
headers: {},
|
80
|
+
url: `https://www.googleapis.com/drive/v3/files/${id}?alt=media`,
|
81
|
+
});
|
82
|
+
console.log('File retrieved:', file);
|
83
|
+
return file;
|
84
|
+
}
|
85
|
+
catch (error) {
|
86
|
+
console.error('Error retrieving file:', error);
|
87
|
+
return null;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
findFolders = async (id) => {
|
91
|
+
const query = id
|
92
|
+
? `'${id}' in parents and mimeType='application/vnd.google-apps.folder'`
|
93
|
+
: `'root' in parents and mimeType='application/vnd.google-apps.folder'`;
|
94
|
+
const folders = await this.searchFiles(query);
|
95
|
+
return folders.filter((file) => file.mimeType === 'application/vnd.google-apps.folder');
|
96
|
+
};
|
97
|
+
findLastFile = async (folderId) => {
|
98
|
+
try {
|
99
|
+
const files = await this.searchFiles(`'${folderId}' in parents`);
|
100
|
+
const fileContents = await Promise.all(files
|
101
|
+
.filter((file) => file.mimeType !== 'application/vnd.google-apps.folder')
|
102
|
+
.map(async (file) => {
|
103
|
+
const content = await this.fetcher({
|
104
|
+
method: 'GET',
|
105
|
+
headers: {},
|
106
|
+
url: `https://www.googleapis.com/drive/v3/files/${file.id}?alt=media`,
|
107
|
+
});
|
108
|
+
return {
|
109
|
+
...file,
|
110
|
+
content,
|
111
|
+
};
|
112
|
+
}));
|
113
|
+
const latestFile = fileContents.reduce((latest, current) => {
|
114
|
+
const latestTimestamp = latest ? parseInt(latest.name.split('-')[1].split('.')[0], 10) : 0;
|
115
|
+
const currentTimestamp = parseInt(current.name.split('-')[1].split('.')[0], 10);
|
116
|
+
return currentTimestamp > latestTimestamp ? current : latest;
|
117
|
+
}, null);
|
118
|
+
return latestFile ? latestFile.content : null;
|
119
|
+
}
|
120
|
+
catch (error) {
|
121
|
+
console.error('Error finding last file:', error);
|
122
|
+
return null;
|
123
|
+
}
|
124
|
+
};
|
125
|
+
async getAllClaims() {
|
126
|
+
const rootFolders = await this.findFolders();
|
127
|
+
const credentialsFolder = rootFolders.find((f) => f.name === 'Credentials');
|
128
|
+
if (!credentialsFolder)
|
129
|
+
return [];
|
130
|
+
const credentialsFolderId = credentialsFolder.id;
|
131
|
+
const subfolders = await this.findFolders(credentialsFolderId);
|
132
|
+
const signedVCFolder = subfolders.find((f) => f.name === 'VCs');
|
133
|
+
if (!signedVCFolder)
|
134
|
+
return [];
|
135
|
+
const claims = await this.fetcher({
|
136
|
+
method: 'GET',
|
137
|
+
headers: {},
|
138
|
+
url: `https://www.googleapis.com/drive/v3/files?q='${signedVCFolder.id}' in parents and trashed=false&fields=files(id,name,mimeType,parents)`,
|
139
|
+
});
|
140
|
+
return claims;
|
141
|
+
}
|
142
|
+
async getAllSessions() {
|
143
|
+
const rootFolders = await this.findFolders();
|
144
|
+
const credentialsFolder = rootFolders.find((f) => f.name === 'Credentials');
|
145
|
+
if (!credentialsFolder)
|
146
|
+
return [];
|
147
|
+
const credentialsFolderId = credentialsFolder.id;
|
148
|
+
const subfolders = await this.findFolders(credentialsFolderId);
|
149
|
+
const sessionsFolder = subfolders.find((f) => f.name === 'Sessions');
|
150
|
+
if (!sessionsFolder)
|
151
|
+
return [];
|
152
|
+
const sessions = await this.fetcher({
|
153
|
+
method: 'GET',
|
154
|
+
headers: {},
|
155
|
+
url: `https://www.googleapis.com/drive/v3/files?q='${sessionsFolder.id}' in parents and trashed=false&fields=files(id,name,mimeType,parents)`,
|
156
|
+
});
|
157
|
+
return sessions;
|
158
|
+
}
|
159
|
+
async delete(id) {
|
160
|
+
try {
|
161
|
+
const response = await this.fetcher({
|
162
|
+
method: 'DELETE',
|
163
|
+
headers: {},
|
164
|
+
url: `https://www.googleapis.com/drive/v3/files/${id}`,
|
165
|
+
});
|
166
|
+
console.log('File deleted:', response);
|
167
|
+
return response;
|
168
|
+
}
|
169
|
+
catch (error) {
|
170
|
+
console.error('Error deleting file:', error);
|
171
|
+
return null;
|
172
|
+
}
|
173
|
+
}
|
174
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
// import { GoogleDriveStorage } from './GoogleDriveStorage.js';
|
2
|
+
// import { StorageStrategy, StorageType } from '../../types/index.js';
|
3
|
+
// class StorageContext {
|
4
|
+
// public strategy: StorageStrategy;
|
5
|
+
// constructor(strategy: StorageStrategy) {
|
6
|
+
// this.strategy = strategy;
|
7
|
+
// }
|
8
|
+
// setStrategy(strategy: StorageStrategy) {
|
9
|
+
// this.strategy = strategy;
|
10
|
+
// }
|
11
|
+
// async createFolder(folderName: string, parentFolderId?: string) {
|
12
|
+
// return this.strategy.createFolder(folderName, parentFolderId);
|
13
|
+
// }
|
14
|
+
// async save(data: any, folderId: string) {
|
15
|
+
// return this.strategy.save(data, folderId);
|
16
|
+
// }
|
17
|
+
// async retrieve(id: string) {
|
18
|
+
// return this.strategy.retrieve(id);
|
19
|
+
// }
|
20
|
+
// async findFolders(id?: string) {
|
21
|
+
// return this.strategy.findFolders(id);
|
22
|
+
// }
|
23
|
+
// async findLastFile(folderId: string) {
|
24
|
+
// return this.strategy.findLastFile(folderId);
|
25
|
+
// }
|
26
|
+
// async getAllClaims() {
|
27
|
+
// return this.strategy.getAllClaims();
|
28
|
+
// }
|
29
|
+
// async getAllSessions() {
|
30
|
+
// return this.strategy.getAllSessions();
|
31
|
+
// }
|
32
|
+
// async getFileContent(fileId: string) {
|
33
|
+
// return this.strategy.getFileContent(fileId);
|
34
|
+
// }
|
35
|
+
// }
|
36
|
+
// class StorageFactory {
|
37
|
+
// static getStorageStrategy(type: StorageType, options: any): StorageStrategy {
|
38
|
+
// switch (type) {
|
39
|
+
// case 'googleDrive':
|
40
|
+
// const { accessToken } = options;
|
41
|
+
// if (!accessToken) {
|
42
|
+
// throw new Error('Missing required parameters');
|
43
|
+
// }
|
44
|
+
// return new GoogleDriveStorage(accessToken);
|
45
|
+
// default:
|
46
|
+
// throw new Error('Unsupported storage type');
|
47
|
+
// }
|
48
|
+
// }
|
49
|
+
// }
|
50
|
+
// export { StorageContext, StorageFactory };
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import { KeyPair, FormDataI, Credential, DidDocument } from '../../types/Credential.js';
|
2
|
+
export declare const customDocumentLoader: (url: string) => Promise<any>;
|
3
|
+
export declare class CredentialEngine {
|
4
|
+
/**
|
5
|
+
* Create a DID document using the provided key pair.
|
6
|
+
* @param {object} keyPair - The key pair used to create the DID document.
|
7
|
+
* @returns {Promise<object>} The created DID document.
|
8
|
+
*/
|
9
|
+
private generateDIDSchema;
|
10
|
+
/**
|
11
|
+
* Create a new DID with Digital Bazaar's Ed25519VerificationKey2020 key pair.
|
12
|
+
* @returns {Promise<{didDocument: object, keyPair: object}>} The created DID document and key pair.
|
13
|
+
* @throws Will throw an error if DID creation fails.
|
14
|
+
*/
|
15
|
+
createDID(): Promise<{
|
16
|
+
didDocument: DidDocument;
|
17
|
+
keyPair: KeyPair;
|
18
|
+
}>;
|
19
|
+
/**
|
20
|
+
* Create a new DID with user metamask address as controller
|
21
|
+
* @param walletrAddress
|
22
|
+
* @returns {Promise<{didDocument: object, keyPair: object}>} The created DID document and key pair.
|
23
|
+
* @throws Will throw an error if DID creation fails.
|
24
|
+
*/
|
25
|
+
createWalletDID(walletrAddress: string): Promise<{
|
26
|
+
didDocument: DidDocument;
|
27
|
+
keyPair: KeyPair;
|
28
|
+
}>;
|
29
|
+
/**
|
30
|
+
* Create an unsigned Verifiable Credential (VC)
|
31
|
+
* @param {object} formData - The form data to include in the VC.
|
32
|
+
* @param {string} issuerDid - The DID of the issuer.
|
33
|
+
* @returns {Promise<object>} The created unsigned VC.
|
34
|
+
* @throws Will throw an error if unsigned VC creation fails.
|
35
|
+
*/
|
36
|
+
createUnsignedVC(formData: FormDataI, issuerDid: string): Promise<Credential>;
|
37
|
+
/**
|
38
|
+
* Sign a Verifiable Credential (VC)
|
39
|
+
* @param {object} credential - The credential to sign.
|
40
|
+
* @param {object} keyPair - The key pair to use for signing.
|
41
|
+
* @returns {Promise<object>} The signed VC.
|
42
|
+
* @throws Will throw an error if VC signing fails.
|
43
|
+
*/
|
44
|
+
signVC(credential: Credential, keyPair: KeyPair): Promise<Credential>;
|
45
|
+
}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
export declare class CredentialVerifier {
|
2
|
+
/**
|
3
|
+
* Verify a signed Verifiable Credential (VC)
|
4
|
+
* @param {object} signedVC - The signed VC to verify.
|
5
|
+
* @returns {Promise<boolean>} True if the VC is valid, false otherwise.
|
6
|
+
* @throws Will throw an error if VC verification fails.
|
7
|
+
*/
|
8
|
+
verifyVC(signedVC: Credential, keyPair: any): Promise<boolean>;
|
9
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { DataToSaveI } from '../../types';
|
2
|
+
export declare class GoogleDriveStorage {
|
3
|
+
private accessToken;
|
4
|
+
constructor(accessToken: string);
|
5
|
+
private fetcher;
|
6
|
+
private searchFiles;
|
7
|
+
createFolder(folderName: string, parentFolderId?: string): Promise<string>;
|
8
|
+
save(data: DataToSaveI, folderId: string): Promise<{
|
9
|
+
id: string;
|
10
|
+
} | null>;
|
11
|
+
retrieve(id: string): Promise<any>;
|
12
|
+
findFolders: (id?: string) => Promise<any[]>;
|
13
|
+
findLastFile: (folderId: string) => Promise<any>;
|
14
|
+
getAllClaims(): Promise<any>;
|
15
|
+
getAllSessions(): Promise<any>;
|
16
|
+
delete(id: string): Promise<any>;
|
17
|
+
}
|
File without changes
|