@cooperation/vc-storage 1.0.10 → 1.0.12

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.
@@ -1,20 +1,39 @@
1
1
  import { KeyPair, DidDocument, FormDataI, RecommendationCredential, Credential, RecommendationFormDataI, VerifiableCredential } from '../../types/credential';
2
2
  /**
3
3
  * Create a DID document using the provided key pair.
4
- * @param {object} keyPair - The key pair used to create the DID document.
5
- * @returns {Promise<object>} The created DID document.
4
+ * @param {KeyPair} keyPair - The key pair used to create the DID document.
5
+ * @returns {Promise<DidDocument>} The created DID document.
6
+ * @throws Will throw an error if the DID document generation fails.
6
7
  */
7
8
  export declare const generateDIDSchema: (keyPair: KeyPair) => Promise<DidDocument>;
8
9
  /**
9
- * Generate an unsigned Verifiable Credential (VC)
10
- * @param {object} formData - The form data to include in the VC.
11
- * @param {string} issuerDid - The DID of the issuer.
12
- * @param {string} vcId - The ID of the credential generated by uuidv4()
13
- * @returns {Promise<object>} The created unsigned VC.
14
- * @throws Will throw an error if unsigned VC creation fails.
10
+ * Generate an unsigned Verifiable Credential (VC).
11
+ * Hashes the credential to create a unique ID.
12
+ * @param {FormDataI} params
13
+ * @param {string} params.FormData - The form dta to include in the VC.
14
+ * @param {string} params.issuerDid - The DID of the issuer.
15
+ * @returns {Credential} The created unsigned VC.
16
+ * @throws Will throw an error if the VC creation fails or if issuance date exceeds expiration date.
15
17
  */
16
- export declare function generateUnsignedVC(formData: FormDataI, issuerDid: string, vcId: string): Credential;
17
- export declare function generateUnsignedRecommendation(recommendation: RecommendationFormDataI, issuerDid: string): RecommendationCredential;
18
+ export declare function generateUnsignedVC({ formData, issuerDid }: {
19
+ formData: FormDataI;
20
+ issuerDid: string;
21
+ }): Credential;
22
+ /**
23
+ * Generate an unsigned Recommendation Credential.
24
+ * Uses the hash of the VC to set the `id` for consistency.
25
+ * @param {object} params
26
+ * @param {VerifiableCredential} params.vc - The Verifiable Credential to base the recommendation on.
27
+ * @param {RecommendationFormDataI} params.recommendation - The recommendation form data.
28
+ * @param {string} params.issuerDid - The DID of the issuer.
29
+ * @returns {RecommendationCredential} The created unsigned Recommendation Credential.
30
+ * @throws Will throw an error if the recommendation creation fails or if issuance date exceeds expiration date.
31
+ */
32
+ export declare function generateUnsignedRecommendation({ vc, recommendation, issuerDid, }: {
33
+ vc: any;
34
+ recommendation: RecommendationFormDataI;
35
+ issuerDid: string;
36
+ }): RecommendationCredential;
18
37
  /**
19
38
  * Extracts the keypair from a Verifiable Credential
20
39
  * @param {Object} credential - The signed Verifiable Credential
@@ -1,15 +1,32 @@
1
1
  import { GoogleDriveStorage } from '../models/GoogleDriveStorage.js';
2
+ export type FileType = 'VC' | 'DID' | 'SESSION' | 'RECOMMENDATION' | 'KEYPAIR';
3
+ interface SaveToGooglePropsI {
4
+ storage: GoogleDriveStorage;
5
+ data: any;
6
+ type: FileType;
7
+ vcId?: string;
8
+ }
9
+ export declare const getVCWithRecommendations: ({ vcId, storage }: {
10
+ vcId: string;
11
+ storage: GoogleDriveStorage;
12
+ }) => Promise<{
13
+ vc: {
14
+ name: string;
15
+ data: any;
16
+ id: string;
17
+ };
18
+ recommendations: any[];
19
+ relationsFileId: any;
20
+ }>;
2
21
  /**
3
- * keyFile name = {uuid}-type-timestamp // we need that
4
- * vc.id = urn-uuid-{uuid} // we got that
5
22
  * Save data to Google Drive in the specified folder type.
6
23
  * @param {object} data - The data to save.
7
- * @param {'VC' | 'DID' | 'SESSION' | 'RECOMMENDATION' | 'KEYPAIR'} type - The type of data being saved.
24
+ * @param {FileType} data.type - The type of data being saved.
8
25
  * @returns {Promise<object>} - The file object saved to Google Drive.
9
- * @param {string} uuid - Optional unique identifier for the VC.
26
+ * @param {string} data.vcId - Optional unique identifier for the VC to link the recommendations.
10
27
  * @throws Will throw an error if the save operation fails.
11
28
  */
12
- export declare function saveToGoogleDrive(storage: GoogleDriveStorage, data: any, type: 'VC' | 'DID' | 'SESSION' | 'RECOMMENDATION' | 'KEYPAIR', uuid?: string): Promise<object>;
29
+ export declare function saveToGoogleDrive({ storage, data, type }: SaveToGooglePropsI): Promise<any>;
13
30
  /**
14
31
  * Upload an image to Google Drive in the Credentials/MEDIAs folder.
15
32
  * @param {GoogleDriveStorage} storage - The GoogleDriveStorage instance.
@@ -22,3 +39,4 @@ export declare function uploadImageToGoogleDrive(storage: GoogleDriveStorage, im
22
39
  }>;
23
40
  export declare function generateViewLink(fileId: string): string;
24
41
  export declare function extractGoogleDriveFileId(url: string): string | null;
42
+ export {};
@@ -1,14 +1,28 @@
1
1
  import { Ed25519VerificationKey2020 } from '@digitalbazaar/ed25519-verification-key-2020';
2
+ import crypto from 'crypto';
2
3
  import { v4 as uuidv4 } from 'uuid';
4
+ /**
5
+ * Utility function to generate a hashed ID for a credential.
6
+ * Excludes the `id` field when hashing.
7
+ * @param {object} credential - The credential object to hash.
8
+ * @returns {string} The generated hashed ID.
9
+ */
10
+ function generateHashedId(credential) {
11
+ // Exclude the `id` field from the hash
12
+ const credentialWithoutId = { ...credential, id: undefined };
13
+ const serialized = JSON.stringify(credentialWithoutId);
14
+ return crypto.createHash('sha256').update(serialized).digest('hex');
15
+ }
3
16
  /**
4
17
  * Create a DID document using the provided key pair.
5
- * @param {object} keyPair - The key pair used to create the DID document.
6
- * @returns {Promise<object>} The created DID document.
18
+ * @param {KeyPair} keyPair - The key pair used to create the DID document.
19
+ * @returns {Promise<DidDocument>} The created DID document.
20
+ * @throws Will throw an error if the DID document generation fails.
7
21
  */
8
22
  export const generateDIDSchema = async (keyPair) => {
9
23
  try {
10
24
  const DID = keyPair.controller;
11
- const didDocument = {
25
+ return {
12
26
  '@context': ['https://www.w3.org/ns/did/v1'],
13
27
  id: DID,
14
28
  publicKey: [
@@ -32,7 +46,6 @@ export const generateDIDSchema = async (keyPair) => {
32
46
  },
33
47
  ],
34
48
  };
35
- return didDocument;
36
49
  }
37
50
  catch (error) {
38
51
  console.error('Error creating DID document:', error);
@@ -40,117 +53,126 @@ export const generateDIDSchema = async (keyPair) => {
40
53
  }
41
54
  };
42
55
  /**
43
- * Generate an unsigned Verifiable Credential (VC)
44
- * @param {object} formData - The form data to include in the VC.
45
- * @param {string} issuerDid - The DID of the issuer.
46
- * @param {string} vcId - The ID of the credential generated by uuidv4()
47
- * @returns {Promise<object>} The created unsigned VC.
48
- * @throws Will throw an error if unsigned VC creation fails.
56
+ * Generate an unsigned Verifiable Credential (VC).
57
+ * Hashes the credential to create a unique ID.
58
+ * @param {FormDataI} params
59
+ * @param {string} params.FormData - The form dta to include in the VC.
60
+ * @param {string} params.issuerDid - The DID of the issuer.
61
+ * @returns {Credential} The created unsigned VC.
62
+ * @throws Will throw an error if the VC creation fails or if issuance date exceeds expiration date.
49
63
  */
50
- export function generateUnsignedVC(formData, issuerDid, vcId) {
51
- try {
52
- const issuanceDate = new Date().toISOString();
53
- if (issuanceDate > formData.expirationDate)
54
- throw Error('issuanceDate cannot be after expirationDate');
55
- const unsignedCredential = {
56
- '@context': [
57
- 'https://www.w3.org/2018/credentials/v1',
58
- 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json',
59
- {
60
- duration: 'https://schema.org/duration',
61
- fullName: 'https://schema.org/name',
62
- portfolio: 'https://schema.org/portfolio',
63
- evidenceLink: 'https://schema.org/evidenceLink',
64
- evidenceDescription: 'https://schema.org/evidenceDescription',
65
- credentialType: 'https://schema.org/credentialType',
66
- },
67
- ],
68
- id: `urn:uuid:${vcId}`, //! i want this uuid to be in the condition where vcId part == keypair file name which is like this `${uuid ? uuid + '_' : ''}${type}_${timestamp}.json`,
69
- type: ['VerifiableCredential', 'OpenBadgeCredential'],
70
- issuer: {
71
- id: issuerDid,
72
- type: ['Profile'],
64
+ export function generateUnsignedVC({ formData, issuerDid }) {
65
+ const issuanceDate = new Date().toISOString();
66
+ if (issuanceDate > formData.expirationDate)
67
+ throw new Error('issuanceDate cannot be after expirationDate');
68
+ const unsignedCredential = {
69
+ '@context': [
70
+ 'https://www.w3.org/2018/credentials/v1',
71
+ 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json',
72
+ {
73
+ duration: 'https://schema.org/duration',
74
+ fullName: 'https://schema.org/name',
75
+ portfolio: 'https://schema.org/portfolio',
76
+ evidenceLink: 'https://schema.org/evidenceLink',
77
+ evidenceDescription: 'https://schema.org/evidenceDescription',
78
+ credentialType: 'https://schema.org/credentialType',
73
79
  },
74
- issuanceDate,
75
- expirationDate: formData.expirationDate,
76
- credentialSubject: {
77
- type: ['AchievementSubject'],
78
- name: formData.fullName,
79
- portfolio: formData.portfolio,
80
- evidenceLink: formData.evidenceLink,
81
- evidenceDescription: formData.achievementDescription,
82
- duration: formData.duration,
83
- credentialType: formData.credentialType,
84
- achievement: [
85
- {
86
- id: `urn:uuid:${uuidv4()}`,
87
- type: ['Achievement'],
88
- criteria: {
89
- narrative: formData.criteriaNarrative,
90
- },
91
- description: formData.achievementDescription,
92
- name: formData.achievementName,
93
- image: formData.evidenceLink
94
- ? {
95
- id: formData.evidenceLink,
96
- type: 'Image',
97
- }
98
- : undefined,
99
- },
100
- ],
101
- },
102
- };
103
- return unsignedCredential;
104
- }
105
- catch (error) {
106
- console.error('Error creating unsigned VC', error);
107
- throw error;
108
- }
109
- }
110
- export function generateUnsignedRecommendation(recommendation, issuerDid) {
111
- try {
112
- const issuanceDate = new Date().toISOString();
113
- if (issuanceDate > recommendation.expirationDate)
114
- throw Error('issuanceDate cannot be after expirationDate');
115
- const unsignedRecommendation = {
116
- '@context': [
117
- 'https://www.w3.org/2018/credentials/v1',
118
- 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json',
80
+ ],
81
+ id: '', // Will be set after hashing
82
+ type: ['VerifiableCredential', 'OpenBadgeCredential'],
83
+ issuer: {
84
+ id: issuerDid,
85
+ type: ['Profile'],
86
+ },
87
+ issuanceDate,
88
+ expirationDate: formData.expirationDate,
89
+ credentialSubject: {
90
+ type: ['AchievementSubject'],
91
+ name: formData.fullName,
92
+ portfolio: formData.portfolio.map((item) => ({
93
+ '@type': 'schema:CreativeWork',
94
+ name: item.name,
95
+ url: item.url,
96
+ })),
97
+ evidenceLink: formData.evidenceLink,
98
+ evidenceDescription: formData.achievementDescription,
99
+ duration: formData.duration,
100
+ credentialType: formData.credentialType,
101
+ achievement: [
119
102
  {
120
- howKnow: 'https://schema.org/howKnow',
121
- recommendationText: 'https://schema.org/recommendationText',
122
- qualifications: 'https://schema.org/qualifications',
123
- explainAnswer: 'https://schema.org/explainAnswer',
124
- portfolio: 'https://schema.org/portfolio',
103
+ id: `urn:uuid:${uuidv4()}`,
104
+ type: ['Achievement'],
105
+ criteria: {
106
+ narrative: formData.criteriaNarrative,
107
+ },
108
+ description: formData.achievementDescription,
109
+ name: formData.achievementName,
110
+ image: formData.evidenceLink
111
+ ? {
112
+ id: formData.evidenceLink,
113
+ type: 'Image',
114
+ }
115
+ : undefined,
125
116
  },
126
117
  ],
127
- id: `urn:uuid:${uuidv4()}`, // Unique identifier for the recommendation
128
- type: ['VerifiableCredential', 'https://schema.org/RecommendationCredential'], // Use a fully qualified URI for 'RecommendationCredential'
129
- issuer: {
130
- id: issuerDid,
131
- type: ['Profile'],
132
- },
133
- issuanceDate,
134
- expirationDate: recommendation.expirationDate,
135
- credentialSubject: {
136
- name: recommendation.fullName,
137
- howKnow: recommendation.howKnow,
138
- recommendationText: recommendation.recommendationText,
139
- qualifications: recommendation.qualifications,
140
- explainAnswer: recommendation.explainAnswer,
141
- portfolio: recommendation.portfolio.map((item) => ({
142
- name: item.name,
143
- url: item.url,
144
- })),
118
+ },
119
+ };
120
+ // Generate the hashed ID
121
+ unsignedCredential.id = 'urn:' + generateHashedId(unsignedCredential);
122
+ return unsignedCredential;
123
+ }
124
+ /**
125
+ * Generate an unsigned Recommendation Credential.
126
+ * Uses the hash of the VC to set the `id` for consistency.
127
+ * @param {object} params
128
+ * @param {VerifiableCredential} params.vc - The Verifiable Credential to base the recommendation on.
129
+ * @param {RecommendationFormDataI} params.recommendation - The recommendation form data.
130
+ * @param {string} params.issuerDid - The DID of the issuer.
131
+ * @returns {RecommendationCredential} The created unsigned Recommendation Credential.
132
+ * @throws Will throw an error if the recommendation creation fails or if issuance date exceeds expiration date.
133
+ */
134
+ export function generateUnsignedRecommendation({ vc, recommendation, issuerDid, }) {
135
+ console.log('🚀 ~ vc.id:', vc.id);
136
+ console.log('🚀 ~ vc:', vc);
137
+ console.log('🚀 ~ recommendation:', recommendation);
138
+ const issuanceDate = new Date().toISOString();
139
+ if (issuanceDate > recommendation.expirationDate)
140
+ throw new Error('issuanceDate cannot be after expirationDate');
141
+ const unsignedRecommendation = {
142
+ '@context': [
143
+ 'https://www.w3.org/2018/credentials/v1',
144
+ 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json',
145
+ {
146
+ howKnow: 'https://schema.org/howKnow',
147
+ recommendationText: 'https://schema.org/recommendationText',
148
+ qualifications: 'https://schema.org/qualifications',
149
+ explainAnswer: 'https://schema.org/explainAnswer',
150
+ portfolio: 'https://schema.org/portfolio',
145
151
  },
146
- };
147
- console.log('Successfully created Unsigned Recommendation', unsignedRecommendation);
148
- return unsignedRecommendation;
149
- }
150
- catch (error) {
151
- console.error('Error creating unsigned recommendation', error);
152
- throw error;
153
- }
152
+ ],
153
+ id: '', // Will be set after hashing VC
154
+ type: ['VerifiableCredential', 'https://schema.org/RecommendationCredential'],
155
+ issuer: {
156
+ id: issuerDid,
157
+ type: ['Profile'],
158
+ },
159
+ issuanceDate,
160
+ expirationDate: recommendation.expirationDate,
161
+ credentialSubject: {
162
+ name: recommendation.fullName,
163
+ howKnow: recommendation.howKnow,
164
+ recommendationText: recommendation.recommendationText,
165
+ qualifications: recommendation.qualifications,
166
+ explainAnswer: recommendation.explainAnswer,
167
+ portfolio: recommendation.portfolio.map((item) => ({
168
+ name: item.name,
169
+ url: item.url,
170
+ })),
171
+ },
172
+ };
173
+ // Use the VC's hashed ID for the Recommendation's ID
174
+ unsignedRecommendation.id = vc.data.id;
175
+ return unsignedRecommendation;
154
176
  }
155
177
  /**
156
178
  * Extracts the keypair from a Verifiable Credential
@@ -1,18 +1,29 @@
1
+ export const getVCWithRecommendations = async ({ vcId, storage }) => {
2
+ const vcFolderId = await storage.getFileParents(vcId);
3
+ const files = await storage.findFilesUnderFolder(vcFolderId);
4
+ const relationsFile = files.find((f) => f.name === 'RELATIONS');
5
+ const relationsContent = await storage.retrieve(relationsFile.id);
6
+ const relationsData = relationsContent.data;
7
+ const [vcFileId, recommendationIds] = [relationsData.vc_id, relationsData.recommendations];
8
+ const vc = await storage.retrieve(vcFileId);
9
+ const recommendations = await Promise.all(recommendationIds.map(async (rec) => {
10
+ const recFile = await storage.retrieve(rec);
11
+ return recFile;
12
+ }));
13
+ return { vc: vc, recommendations, relationsFileId: relationsFile.id };
14
+ };
1
15
  /**
2
- * keyFile name = {uuid}-type-timestamp // we need that
3
- * vc.id = urn-uuid-{uuid} // we got that
4
16
  * Save data to Google Drive in the specified folder type.
5
17
  * @param {object} data - The data to save.
6
- * @param {'VC' | 'DID' | 'SESSION' | 'RECOMMENDATION' | 'KEYPAIR'} type - The type of data being saved.
18
+ * @param {FileType} data.type - The type of data being saved.
7
19
  * @returns {Promise<object>} - The file object saved to Google Drive.
8
- * @param {string} uuid - Optional unique identifier for the VC.
20
+ * @param {string} data.vcId - Optional unique identifier for the VC to link the recommendations.
9
21
  * @throws Will throw an error if the save operation fails.
10
22
  */
11
- export async function saveToGoogleDrive(storage, data, type, uuid) {
23
+ export async function saveToGoogleDrive({ storage, data, type }) {
12
24
  try {
13
- const timestamp = Date.now();
14
25
  const fileData = {
15
- fileName: `${uuid ? uuid + '_' : ''}${type}_${timestamp}.json`,
26
+ fileName: type === 'VC' ? 'VC' : `${type}-${Date.now()}`,
16
27
  mimeType: 'application/json',
17
28
  body: JSON.stringify(data),
18
29
  };
@@ -24,34 +35,31 @@ export async function saveToGoogleDrive(storage, data, type, uuid) {
24
35
  let credentialsFolderId;
25
36
  if (!credentialsFolder) {
26
37
  credentialsFolderId = await storage.createFolder('Credentials');
27
- console.log('Created Credentials folder with ID:', credentialsFolderId);
28
38
  }
29
39
  else {
30
40
  credentialsFolderId = credentialsFolder.id;
31
- console.log('Found Credentials folder with ID:', credentialsFolderId);
32
41
  }
33
42
  // Get subfolders within the "Credentials" folder
34
43
  const subfolders = await storage.findFolders(credentialsFolderId);
35
- console.log(`Subfolders in Credentials (ID: ${credentialsFolderId}):`, subfolders);
36
44
  // Find or create the specific subfolder (DIDs or VCs)
37
45
  let typeFolder = subfolders.find((f) => f.name === `${type}s`);
38
46
  let typeFolderId;
39
47
  if (!typeFolder) {
40
48
  typeFolderId = await storage.createFolder(`${type}s`, credentialsFolderId);
41
- console.log(`Created ${type}s folder with ID:`, typeFolderId);
42
49
  }
43
50
  else {
44
51
  typeFolderId = typeFolder.id;
45
- console.log(`Found ${type} files:`, await storage.findLastFile(typeFolderId));
46
- console.log(`Found ${type}s folder with ID:`, typeFolderId);
52
+ }
53
+ if (type === 'VC') {
54
+ // save the data in Credentials/VCs/VC-timestamp/vc.json
55
+ const vcFolderId = await storage.createFolder(`${fileData.fileName}-${Date.now()}`, typeFolderId);
56
+ const file = await storage.saveFile({ data: fileData, folderId: vcFolderId });
57
+ console.log(`File uploaded: ${file?.id} under ${fileData.fileName} folder in VCs folder`);
58
+ return file;
47
59
  }
48
60
  // Save the file in the specific subfolder
49
- const file = await storage.save(fileData, typeFolderId);
61
+ const file = await storage.saveFile({ data: fileData, folderId: typeFolderId });
50
62
  console.log(`File uploaded: ${file?.id} under ${type}s with ID ${typeFolderId} folder in Credentials folder`);
51
- if (file && file.id) {
52
- console.log('Sharing file with second user...');
53
- await storage.addCommenterRoleToFile(file.id);
54
- }
55
63
  return file;
56
64
  }
57
65
  catch (error) {
@@ -68,9 +76,7 @@ export async function saveToGoogleDrive(storage, data, type, uuid) {
68
76
  */
69
77
  export async function uploadImageToGoogleDrive(storage, imageFile) {
70
78
  try {
71
- // Get all root folders
72
79
  const rootFolders = await storage.findFolders();
73
- // Find or create the "Credentials" folder
74
80
  let credentialsFolder = rootFolders.find((f) => f.name === 'Credentials');
75
81
  let credentialsFolderId;
76
82
  if (!credentialsFolder) {
@@ -79,9 +85,7 @@ export async function uploadImageToGoogleDrive(storage, imageFile) {
79
85
  else {
80
86
  credentialsFolderId = credentialsFolder.id;
81
87
  }
82
- // Get subfolders within the "Credentials" folder
83
88
  const subfolders = await storage.findFolders(credentialsFolderId);
84
- // Find or create the "MEDIAs" folder
85
89
  let mediasFolder = subfolders.find((f) => f.name === 'MEDIAs');
86
90
  let mediasFolderId;
87
91
  if (!mediasFolder) {
@@ -96,8 +100,11 @@ export async function uploadImageToGoogleDrive(storage, imageFile) {
96
100
  mimeType: imageFile.type,
97
101
  body: imageFile,
98
102
  };
99
- // Save the image in the "MEDIAs" folder
100
- const uploadedImage = await storage.save(imageData, mediasFolderId);
103
+ // SaveFile the image in the "MEDIAs" folder
104
+ const uploadedImage = await storage.saveFile({
105
+ data: imageData,
106
+ folderId: mediasFolderId,
107
+ });
101
108
  console.log(`Image uploaded: ${uploadedImage?.id} to MEDIAs folder in Credentials`);
102
109
  return uploadedImage;
103
110
  }
@@ -1,6 +1,3 @@
1
- import { CredentialEngine } from '../models/CredentialEngine.js';
2
- import { GoogleDriveStorage } from '../models/GoogleDriveStorage.js';
3
- import { extractGoogleDriveFileId } from './google.js';
4
1
  /**
5
2
  * Create and sign a Verifiable Presentation (VP) from a given Verifiable Credential (VC) file and any associated recommendations.
6
3
  * @param {string} accessTokens - The access tokens for the user.
@@ -14,32 +11,32 @@ export const createAndSignVerifiablePresentation = async (accessTokens, vcFileId
14
11
  return null;
15
12
  }
16
13
  try {
17
- const storage = new GoogleDriveStorage(accessTokens);
18
- const engine = new CredentialEngine(accessTokens);
19
- // Fetch Verifiable Credential (VC)
20
- const verifiableCredential = await storage.retrieve(vcFileId);
21
- if (!verifiableCredential) {
22
- throw new Error('Verifiable Credential not found.');
23
- }
24
- // Fetch VC comments (potential recommendations)
25
- const verifiableCredentialComments = await storage.getFileComments(vcFileId);
26
- let recommendations = [];
27
- // Extract recommendations from comments if present
28
- if (verifiableCredentialComments.length > 0) {
29
- for (const comment of verifiableCredentialComments) {
30
- console.log('🚀 ~ createAndSignVerifiablePresentation ~ comment', comment);
31
- const recommendationFile = await storage.retrieve(extractGoogleDriveFileId(comment.content));
32
- console.log('🚀 ~ createAndSignVerifiablePresentation ~ recommendationFile', recommendationFile);
33
- if (recommendationFile) {
34
- recommendations.push(recommendationFile);
35
- }
36
- }
37
- }
38
- // Create Verifiable Presentation (VP) with the retrieved VC
39
- const presentation = await engine.createPresentation([verifiableCredential.data, ...recommendations]); //! do not edit the array order!!
40
- // Use the key pair to sign the presentation
41
- const signedPresentation = await engine.signPresentation(presentation);
42
- return { signedPresentation };
14
+ // const storage = new GoogleDriveStorage(accessTokens);
15
+ // const engine = new CredentialEngine(accessTokens);
16
+ // // Fetch Verifiable Credential (VC)
17
+ // const verifiableCredential = await storage.retrieve(vcFileId);
18
+ // if (!verifiableCredential) {
19
+ // throw new Error('Verifiable Credential not found.');
20
+ // }
21
+ // // Fetch VC comments (potential recommendations)
22
+ // const verifiableCredentialComments = await storage.getFileComments(vcFileId);
23
+ // let recommendations: object[] = [];
24
+ // // Extract recommendations from comments if present
25
+ // if (verifiableCredentialComments.length > 0) {
26
+ // for (const comment of verifiableCredentialComments) {
27
+ // console.log('🚀 ~ createAndSignVerifiablePresentation ~ comment', comment);
28
+ // const recommendationFile = await storage.retrieve(extractGoogleDriveFileId(comment.content));
29
+ // console.log('🚀 ~ createAndSignVerifiablePresentation ~ recommendationFile', recommendationFile);
30
+ // if (recommendationFile) {
31
+ // recommendations.push(recommendationFile);
32
+ // }
33
+ // }
34
+ // }
35
+ // // Create Verifiable Presentation (VP) with the retrieved VC
36
+ // const presentation = await engine.createPresentation([verifiableCredential.data, ...recommendations]); //! do not edit the array order!!
37
+ // // Use the key pair to sign the presentation
38
+ // const signedPresentation = await engine.signPresentation(presentation);
39
+ // return {};
43
40
  }
44
41
  catch (error) {
45
42
  console.error('Error during Verifiable Presentation creation and signing:', error);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cooperation/vc-storage",
3
3
  "type": "module",
4
- "version": "1.0.10",
4
+ "version": "1.0.12",
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",
@@ -1,10 +0,0 @@
1
- import { GoogleDriveStorage } from '../models/GoogleDriveStorage.js';
2
- /**
3
- * Save data to Google Drive in the specified folder type.
4
- * @param {object} data - The data to save.
5
- * @param {'VC' | 'DID' | 'UnsignedVC'} type - The type of data being saved.
6
- * @returns {Promise<object>} - The file object saved to Google Drive.
7
- * @throws Will throw an error if the save operation fails.
8
- */
9
- export declare function saveToGoogleDrive(storage: GoogleDriveStorage, data: any, type: 'VC' | 'DID' | 'SESSION' | 'RECOMMENDATION'): Promise<object>;
10
- export declare function generateViewLink(fileId: string): string;
@@ -1,65 +0,0 @@
1
- /**
2
- * Save data to Google Drive in the specified folder type.
3
- * @param {object} data - The data to save.
4
- * @param {'VC' | 'DID' | 'UnsignedVC'} type - The type of data being saved.
5
- * @returns {Promise<object>} - The file object saved to Google Drive.
6
- * @throws Will throw an error if the save operation fails.
7
- */
8
- export async function saveToGoogleDrive(storage, data, type) {
9
- try {
10
- const timestamp = Date.now();
11
- const fileData = {
12
- fileName: `${type}-${timestamp}.json`,
13
- mimeType: 'application/json',
14
- body: JSON.stringify(data),
15
- };
16
- // Get all root folders
17
- const rootFolders = await storage.findFolders();
18
- console.log('Root folders:', rootFolders);
19
- // Find or create the "Credentials" folder
20
- let credentialsFolder = rootFolders.find((f) => f.name === 'Credentials');
21
- let credentialsFolderId;
22
- if (!credentialsFolder) {
23
- credentialsFolderId = await storage.createFolder('Credentials');
24
- console.log('Created Credentials folder with ID:', credentialsFolderId);
25
- }
26
- else {
27
- credentialsFolderId = credentialsFolder.id;
28
- console.log('Found Credentials folder with ID:', credentialsFolderId);
29
- }
30
- // Get subfolders within the "Credentials" folder
31
- const subfolders = await storage.findFolders(credentialsFolderId);
32
- console.log(`Subfolders in Credentials (ID: ${credentialsFolderId}):`, subfolders);
33
- // Find or create the specific subfolder (DIDs or VCs)
34
- let typeFolder = subfolders.find((f) => f.name === `${type}s`);
35
- let typeFolderId;
36
- if (!typeFolder) {
37
- typeFolderId = await storage.createFolder(`${type}s`, credentialsFolderId);
38
- console.log(`Created ${type}s folder with ID:`, typeFolderId);
39
- }
40
- else {
41
- typeFolderId = typeFolder.id;
42
- console.log(`Found ${type} files:`, await storage.findLastFile(typeFolderId));
43
- console.log(`Found ${type}s folder with ID:`, typeFolderId);
44
- }
45
- // Save the file in the specific subfolder
46
- const file = await storage.save(fileData, typeFolderId);
47
- console.log(`File uploaded: ${file?.id} under ${type}s with ID ${typeFolderId} folder in Credentials folder`);
48
- if (file && file.id) {
49
- console.log('Sharing file with second user...');
50
- await storage.addCommenterRoleToFile(file.id);
51
- }
52
- return file;
53
- }
54
- catch (error) {
55
- console.error('Error saving to Google Drive:', error);
56
- throw error;
57
- }
58
- }
59
- export function generateViewLink(fileId) {
60
- if (!fileId) {
61
- throw new Error('File ID is required to generate a view link.');
62
- }
63
- // Construct the view URL based on the file ID
64
- return `https://drive.google.com/file/d/${fileId}/view`;
65
- }