@cooperation/vc-storage 1.0.8 → 1.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -73,12 +73,13 @@ export class GoogleDriveStorage {
73
73
  const fileMetadata = {
74
74
  name: data.fileName,
75
75
  parents: [folderId], // Specify the folder ID
76
- mimeType: 'application/json', // Use provided MIME type or default to JSON
76
+ mimeType: data.mimeType,
77
77
  };
78
78
  let uploadUrl = 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart';
79
79
  const formData = new FormData();
80
80
  formData.append('metadata', new Blob([JSON.stringify(fileMetadata)], { type: 'application/json' }));
81
81
  formData.append('file', new Blob([data.body], { type: fileMetadata.mimeType })); // Set file data and MIME type
82
+ // Upload file to Google Drive
82
83
  const file = await this.fetcher({
83
84
  method: 'POST',
84
85
  headers: {},
@@ -86,10 +87,25 @@ export class GoogleDriveStorage {
86
87
  url: uploadUrl,
87
88
  });
88
89
  console.log('File uploaded successfully:', file.id);
89
- return file;
90
+ // Set the file permission to "Anyone with the link" can view
91
+ const permissionUrl = `https://www.googleapis.com/drive/v3/files/${file.id}/permissions`;
92
+ const permissionData = {
93
+ role: 'reader',
94
+ type: 'anyone', // Public access
95
+ };
96
+ await this.fetcher({
97
+ method: 'POST',
98
+ url: permissionUrl,
99
+ headers: {
100
+ 'Content-Type': 'application/json',
101
+ },
102
+ body: JSON.stringify(permissionData),
103
+ });
104
+ console.log('Permission set to public for file:', file.id);
105
+ return { id: file.id };
90
106
  }
91
107
  catch (error) {
92
- console.error('Error uploading file:', error.message);
108
+ console.error('Error uploading file or setting permission:', error.message);
93
109
  return null;
94
110
  }
95
111
  }
@@ -167,16 +183,66 @@ export class GoogleDriveStorage {
167
183
  * @returns file content
168
184
  */
169
185
  async retrieve(id) {
186
+ const metadataUrl = `https://www.googleapis.com/drive/v3/files/${id}?fields=name`;
187
+ const dataUrl = `https://www.googleapis.com/drive/v3/files/${id}?alt=media`;
170
188
  try {
171
- const file = await this.fetcher({
189
+ console.log(`Starting retrieval for file ID: ${id}`);
190
+ // Fetch file metadata to get the name
191
+ const metadataResponse = await fetch(metadataUrl, {
172
192
  method: 'GET',
173
- headers: {},
174
- url: `https://www.googleapis.com/drive/v3/files/${id}?alt=media`,
193
+ headers: {
194
+ Authorization: `Bearer ${this.accessToken}`,
195
+ },
196
+ });
197
+ if (!metadataResponse.ok) {
198
+ const errorData = await metadataResponse.json();
199
+ console.error(`Failed to retrieve metadata for file ID ${id}:`, errorData);
200
+ return null;
201
+ }
202
+ const metadata = await metadataResponse.json();
203
+ const fileName = metadata.name;
204
+ console.log(`File name retrieved: ${fileName}`);
205
+ // Fetch actual file data
206
+ const dataResponse = await fetch(dataUrl, {
207
+ method: 'GET',
208
+ headers: {
209
+ Authorization: `Bearer ${this.accessToken}`,
210
+ },
175
211
  });
176
- return file;
212
+ if (!dataResponse.ok) {
213
+ const errorData = await dataResponse.json();
214
+ console.error(`Failed to retrieve file data for ID ${id}:`, errorData);
215
+ return null;
216
+ }
217
+ const contentType = dataResponse.headers.get('Content-Type');
218
+ console.log(`File content type: ${contentType}`);
219
+ let fileData;
220
+ if (contentType?.includes('application/json')) {
221
+ fileData = await dataResponse.json();
222
+ }
223
+ else if (contentType?.includes('text') || contentType?.includes('image/svg+xml')) {
224
+ fileData = await dataResponse.text(); // Fetch SVG files as text for easy manipulation
225
+ }
226
+ else if (contentType?.includes('image') ||
227
+ contentType?.includes('video') ||
228
+ contentType?.includes('audio') ||
229
+ contentType?.includes('application/octet-stream') ||
230
+ contentType?.includes('application/pdf') ||
231
+ contentType?.includes('application/msword') ||
232
+ contentType?.includes('application/vnd.openxmlformats-officedocument.wordprocessingml.document') ||
233
+ contentType?.includes('application/vnd.ms-excel') ||
234
+ contentType?.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')) {
235
+ fileData = await dataResponse.blob();
236
+ }
237
+ else {
238
+ fileData = await dataResponse.arrayBuffer(); // Fallback for other binary types
239
+ }
240
+ console.log('🚀 ~ GoogleDriveStorage ~ retrieve ~ fileData:', fileData);
241
+ // Return file ID, name, and data
242
+ return { id, name: fileName, data: fileData };
177
243
  }
178
244
  catch (error) {
179
- console.error('Error retrieving file:', error);
245
+ console.error(`Error retrieving file with ID ${id}:`, error.message);
180
246
  return null;
181
247
  }
182
248
  }
@@ -309,6 +375,31 @@ export class GoogleDriveStorage {
309
375
  return []; // Return an empty array on error
310
376
  }
311
377
  }
378
+ /**
379
+ * Update the name of a file in Google Drive
380
+ * @param fileId - The ID of the file to update
381
+ * @param newFileName - The new name for the file
382
+ * @returns The updated file metadata, including the new name
383
+ */
384
+ async updateFileName(fileId, newFileName) {
385
+ try {
386
+ const metadata = {
387
+ name: newFileName, // New name for the file
388
+ };
389
+ const updatedFile = await this.fetcher({
390
+ method: 'PATCH',
391
+ headers: { 'Content-Type': 'application/json' },
392
+ body: JSON.stringify(metadata),
393
+ url: `https://www.googleapis.com/drive/v3/files/${fileId}`,
394
+ });
395
+ console.log('File name updated successfully:', updatedFile.name);
396
+ return updatedFile;
397
+ }
398
+ catch (error) {
399
+ console.error('Error updating file name:', error.message);
400
+ throw error;
401
+ }
402
+ }
312
403
  /**
313
404
  * Delete file by id
314
405
  * @param id
@@ -45,7 +45,11 @@ export declare class GoogleDriveStorage {
45
45
  * @param id
46
46
  * @returns file content
47
47
  */
48
- retrieve(id: string): Promise<any>;
48
+ retrieve(id: string): Promise<{
49
+ id: string;
50
+ name: string;
51
+ data: any;
52
+ } | null>;
49
53
  /**
50
54
  * Get folder by folderId, if folderId == null you will have them all
51
55
  * @param id [Optional]
@@ -64,7 +68,14 @@ export declare class GoogleDriveStorage {
64
68
  * @param type
65
69
  * @returns
66
70
  */
67
- getAllFilesByType(type: 'KEYPAIRs' | 'VCs' | 'SESSIONs' | 'DIDs' | 'RECOMMENDATIONs'): Promise<FileContent[]>;
71
+ getAllFilesByType(type: 'KEYPAIRs' | 'VCs' | 'SESSIONs' | 'DIDs' | 'RECOMMENDATIONs' | 'MEDIAs'): Promise<FileContent[]>;
72
+ /**
73
+ * Update the name of a file in Google Drive
74
+ * @param fileId - The ID of the file to update
75
+ * @param newFileName - The new name for the file
76
+ * @returns The updated file metadata, including the new name
77
+ */
78
+ updateFileName(fileId: string, newFileName: string): Promise<any>;
68
79
  /**
69
80
  * Delete file by id
70
81
  * @param id
@@ -14,9 +14,11 @@ export declare function saveToGoogleDrive(storage: GoogleDriveStorage, data: any
14
14
  * Upload an image to Google Drive in the Credentials/MEDIAs folder.
15
15
  * @param {GoogleDriveStorage} storage - The GoogleDriveStorage instance.
16
16
  * @param {File} imageFile - The image file to upload.
17
- * @returns {Promise<object>} - The uploaded image file object.
17
+ * @returns {Promise<>} - The uploaded image file object.
18
18
  * @throws Will throw an error if the upload operation fails.
19
19
  */
20
- export declare function uploadImageToGoogleDrive(storage: GoogleDriveStorage, imageFile: File): Promise<object>;
20
+ export declare function uploadImageToGoogleDrive(storage: GoogleDriveStorage, imageFile: File): Promise<{
21
+ id: string;
22
+ }>;
21
23
  export declare function generateViewLink(fileId: string): string;
22
24
  export declare function extractGoogleDriveFileId(url: string): string | null;
@@ -63,38 +63,28 @@ export async function saveToGoogleDrive(storage, data, type, uuid) {
63
63
  * Upload an image to Google Drive in the Credentials/MEDIAs folder.
64
64
  * @param {GoogleDriveStorage} storage - The GoogleDriveStorage instance.
65
65
  * @param {File} imageFile - The image file to upload.
66
- * @returns {Promise<object>} - The uploaded image file object.
66
+ * @returns {Promise<>} - The uploaded image file object.
67
67
  * @throws Will throw an error if the upload operation fails.
68
68
  */
69
69
  export async function uploadImageToGoogleDrive(storage, imageFile) {
70
70
  try {
71
- // Get all root folders
72
71
  const rootFolders = await storage.findFolders();
73
- console.log('Root folders:', rootFolders);
74
- // Find or create the "Credentials" folder
75
72
  let credentialsFolder = rootFolders.find((f) => f.name === 'Credentials');
76
73
  let credentialsFolderId;
77
74
  if (!credentialsFolder) {
78
75
  credentialsFolderId = await storage.createFolder('Credentials');
79
- console.log('Created Credentials folder with ID:', credentialsFolderId);
80
76
  }
81
77
  else {
82
78
  credentialsFolderId = credentialsFolder.id;
83
- console.log('Found Credentials folder with ID:', credentialsFolderId);
84
79
  }
85
- // Get subfolders within the "Credentials" folder
86
80
  const subfolders = await storage.findFolders(credentialsFolderId);
87
- console.log(`Subfolders in Credentials (ID: ${credentialsFolderId}):`, subfolders);
88
- // Find or create the "MEDIAs" folder
89
81
  let mediasFolder = subfolders.find((f) => f.name === 'MEDIAs');
90
82
  let mediasFolderId;
91
83
  if (!mediasFolder) {
92
84
  mediasFolderId = await storage.createFolder('MEDIAs', credentialsFolderId);
93
- console.log('Created MEDIAs folder with ID:', mediasFolderId);
94
85
  }
95
86
  else {
96
87
  mediasFolderId = mediasFolder.id;
97
- console.log('Found MEDIAs folder with ID:', mediasFolderId);
98
88
  }
99
89
  // Prepare the image file data
100
90
  const imageData = {
@@ -105,10 +95,6 @@ export async function uploadImageToGoogleDrive(storage, imageFile) {
105
95
  // Save the image in the "MEDIAs" folder
106
96
  const uploadedImage = await storage.save(imageData, mediasFolderId);
107
97
  console.log(`Image uploaded: ${uploadedImage?.id} to MEDIAs folder in Credentials`);
108
- if (uploadedImage && uploadedImage.id) {
109
- console.log('Sharing image file with second user...');
110
- await storage.addCommenterRoleToFile(uploadedImage.id);
111
- }
112
98
  return uploadedImage;
113
99
  }
114
100
  catch (error) {
@@ -36,7 +36,7 @@ export const createAndSignVerifiablePresentation = async (accessTokens, vcFileId
36
36
  }
37
37
  }
38
38
  // Create Verifiable Presentation (VP) with the retrieved VC
39
- const presentation = await engine.createPresentation([verifiableCredential, ...recommendations]); //! do not edit the array order!!
39
+ const presentation = await engine.createPresentation([verifiableCredential.data, ...recommendations]); //! do not edit the array order!!
40
40
  // Use the key pair to sign the presentation
41
41
  const signedPresentation = await engine.signPresentation(presentation);
42
42
  return { signedPresentation };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cooperation/vc-storage",
3
3
  "type": "module",
4
- "version": "1.0.8",
4
+ "version": "1.0.11",
5
5
  "description": "Sign and store your verifiable credentials.",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/types/index.d.ts",
@@ -16,7 +16,6 @@
16
16
  "author": "cooperation",
17
17
  "license": "ISC",
18
18
  "dependencies": {
19
- "@cooperation/vc-storage": "^1.0.6",
20
19
  "@digitalbazaar/did-method-key": "^5.2.0",
21
20
  "@digitalbazaar/ed25519-signature-2020": "^5.3.0",
22
21
  "@digitalbazaar/ed25519-verification-key-2020": "^4.1.0",