@cooperation/vc-storage 1.0.10 → 1.0.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- }