Skip to content

Commit 6a2abb5

Browse files
committed
refactor(ardrive): re-add public assertion arfsdao method PE-6155
1 parent fc3ba7d commit 6a2abb5

File tree

1 file changed

+60
-2
lines changed

1 file changed

+60
-2
lines changed

src/arfs/arfsdao.ts

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ import {
7070
ArFSPublicFolderCacheKey,
7171
defaultArFSAnonymousCache
7272
} from './arfsdao_anonymous';
73-
import { deriveDriveKey, deriveFileKey } from '../utils/crypto';
73+
import { deriveDriveKey, deriveFileKey, driveDecrypt } from '../utils/crypto';
7474
import {
7575
DEFAULT_APP_NAME,
7676
DEFAULT_APP_VERSION,
@@ -175,7 +175,7 @@ import {
175175
} from './tx/arfs_tx_data_types';
176176
import { ArFSTagAssembler } from './tags/tag_assembler';
177177
import { assertDataRootsMatch, rePrepareV2Tx } from '../utils/arfsdao_utils';
178-
import { ArFSDataToUpload, ArFSFolderToUpload } from '../exports';
178+
import { ArFSDataToUpload, ArFSFolderToUpload, DrivePrivacy } from '../exports';
179179
import { Turbo, TurboCachesResponse } from './turbo';
180180
import { ArweaveSigner } from 'arbundles/src/signing';
181181

@@ -1757,6 +1757,64 @@ export class ArFSDAO extends ArFSDAOAnonymous {
17571757
);
17581758
}
17591759

1760+
public async getOwnerAndAssertDrive(driveId: DriveID, driveKey?: DriveKey): Promise<ArweaveAddress> {
1761+
const cachedOwner = this.caches.ownerCache.get(driveId);
1762+
if (cachedOwner) {
1763+
return cachedOwner;
1764+
}
1765+
1766+
return this.caches.ownerCache.put(
1767+
driveId,
1768+
(async () => {
1769+
const gqlQuery = buildQuery({
1770+
tags: [
1771+
{ name: 'Entity-Type', value: 'drive' },
1772+
{ name: 'Drive-Id', value: `${driveId}` }
1773+
],
1774+
sort: ASCENDING_ORDER
1775+
});
1776+
const transactions = await this.gatewayApi.gqlRequest(gqlQuery);
1777+
const edges: GQLEdgeInterface[] = transactions.edges;
1778+
1779+
if (!edges.length) {
1780+
throw new Error(`Could not find a transaction with "Drive-Id": ${driveId}`);
1781+
}
1782+
1783+
const edgeOfFirstDrive = edges[0];
1784+
const driveOwnerAddress = edgeOfFirstDrive.node.owner.address;
1785+
const driveOwner = new ArweaveAddress(driveOwnerAddress);
1786+
1787+
const drivePrivacy: DrivePrivacy = driveKey ? 'private' : 'public';
1788+
const drivePrivacyFromTag = edgeOfFirstDrive.node.tags.find((t) => t.name === 'Drive-Privacy');
1789+
1790+
if (!drivePrivacyFromTag) {
1791+
throw new Error('Target drive has no "Drive-Privacy" tag!');
1792+
}
1793+
1794+
if (drivePrivacyFromTag.value !== drivePrivacy) {
1795+
throw new Error(`Target drive is not a ${drivePrivacy} drive!`);
1796+
}
1797+
1798+
if (driveKey) {
1799+
const cipherIVFromTag = edgeOfFirstDrive.node.tags.find((t) => t.name === 'Cipher-IV');
1800+
if (!cipherIVFromTag) {
1801+
throw new Error('Target private drive has no "Cipher-IV" tag!');
1802+
}
1803+
1804+
const driveDataBuffer = await this.gatewayApi.getTxData(TxID(edgeOfFirstDrive.node.id));
1805+
try {
1806+
// Attempt to decrypt drive to assert drive key is correct
1807+
await driveDecrypt(cipherIVFromTag.value, driveKey, driveDataBuffer);
1808+
} catch {
1809+
throw new Error('Provided drive key or password could not decrypt target private drive!');
1810+
}
1811+
}
1812+
1813+
return driveOwner;
1814+
})()
1815+
);
1816+
}
1817+
17601818
/**
17611819
* Lists the children of certain private folder
17621820
* @param {FolderID} folderId the folder ID to list children of

0 commit comments

Comments
 (0)