Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
11ba4b5
Create v2 routes
Altahrim Aug 16, 2023
a8b9f84
Wrap-up changes for updated subfolders
artonge Mar 20, 2023
cfa1c25
Use header to provide e2e-token
artonge May 23, 2023
0136ba4
Use major.minor for api-versions in capabilities
artonge May 23, 2023
3e650b8
Run psalm:fix
artonge May 23, 2023
40fcf73
Update API doc
artonge May 23, 2023
6809689
Prevent access to set and delete endpoints without valid lock token
artonge May 24, 2023
9184afe
Allow to abort changes during unlock
artonge Jun 1, 2023
1832289
Add support for X-NC-E2EE-COUNTER
artonge Jun 1, 2023
c113866
Store signature on metadata save
artonge Jul 3, 2023
f7cf8cc
Check if required headers are set
artonge Jul 5, 2023
9a20a39
Update api.md for new headers
artonge Jul 17, 2023
787b1c2
REMOVE ME: temporary fix to allow both routes on same endpoint
Altahrim Aug 24, 2023
7b17847
Fix leave share for root folder
Altahrim Aug 30, 2023
93734bf
Adapt filedrop to v2 routes
artonge Aug 31, 2023
ac78ddd
Adapt filedrop to v2
artonge Jan 8, 2024
861ce18
Add default mimetype
artonge Jan 11, 2024
ed8e83e
Remove triple base64 encoding
artonge Jan 11, 2024
3b87088
Use top e2ee folder to retrieve users list in public shares
artonge Jan 15, 2024
1d62c07
Correctly validate lock state
artonge Jan 16, 2024
9463aad
Run cs:fix
artonge Jan 16, 2024
cd7c4bd
Fix psalm errors
artonge Jan 16, 2024
8f25f61
Fix lint error
artonge Jan 16, 2024
c151738
Fix phpUnit tests
artonge Jan 16, 2024
a183add
Fix eslint error
artonge Jan 17, 2024
0e06e46
Fix php unit tests
artonge Jan 17, 2024
daa6e6d
Expose all routes to v2
artonge Jan 17, 2024
2600192
Move folder lock to the backend for filedrops
artonge Jan 18, 2024
b047110
Add node workflows
artonge Jan 18, 2024
4ad7837
Fix phpunit tests
artonge Jan 18, 2024
1b7218b
Ignore missing signature on v2 endpoint when the metadata is not in v2
artonge Jan 23, 2024
a32f989
Return 403 when old client access version 2.0 encrypted folders
artonge Jan 25, 2024
b8b1211
Improve readability of isLocked return condition
artonge Jan 31, 2024
14df4e7
Remove support for e2e-token in header in PUT v1/meta-data
artonge Jan 31, 2024
89eb51b
Apply review suggestions
artonge Jan 31, 2024
b1892d4
Compile assets
artonge Jan 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 12 additions & 22 deletions lib/E2EEPublicShareTemplateProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,16 @@
use Psr\Log\LoggerInterface;

class E2EEPublicShareTemplateProvider implements IPublicShareTemplateProvider {
private IUserManager $userManager;
private IUrlGenerator $urlGenerator;
private IL10N $l10n;
private Defaults $defaults;
private IInitialState $initialState;
private IKeyStorage $keyStorage;
private LoggerInterface $logger;

public function __construct(
IUserManager $userManager,
IUrlGenerator $urlGenerator,
IL10N $l10n,
Defaults $defaults,
IInitialState $initialState,
IKeyStorage $keyStorage,
LoggerInterface $logger
private IUserManager $userManager,
private IUrlGenerator $urlGenerator,
private IL10N $l10n,
private Defaults $defaults,
private IInitialState $initialState,
private IKeyStorage $keyStorage,
private LoggerInterface $logger,
private MetaDataStorage $metadataStorage,
) {
$this->userManager = $userManager;
$this->urlGenerator = $urlGenerator;
$this->l10n = $l10n;
$this->defaults = $defaults;
$this->initialState = $initialState;
$this->keyStorage = $keyStorage;
$this->logger = $logger;
}

public function shouldRespond(IShare $share): bool {
Expand All @@ -61,10 +47,14 @@ public function renderPage(IShare $share, string $token, string $path): Template
return new TemplateResponse(Application::APP_ID, 'error');
}

$metadata = json_decode($this->metadataStorage->getMetaData($owner->getUID(), $shareNode->getId()), true);

$this->initialState->provideInitialState('publicKey', $publicKey);
$this->initialState->provideInitialState('fileId', $shareNode->getId());
$this->initialState->provideInitialState('token', $token);
$this->initialState->provideInitialState('fileName', $shareNode->getName());
$this->initialState->provideInitialState('encryptionVersion', $metadata['version']);
$this->initialState->provideInitialState('counter', $this->metadataStorage->getCounter($shareNode->getId()));

// OpenGraph Support: http://ogp.me/
Util::addHeader('meta', ['property' => "og:title", 'content' => $this->l10n->t("Encrypted share")]);
Expand Down
9 changes: 6 additions & 3 deletions src/services/filedrop.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,17 @@ export async function getFileDropEntry(file, tag, publicKey) {
}

/**
* @param {1|2} encryptionVersion - The encrypted version for the folder
* @param {string} folderId
* @param {EncryptedFileMetadata[]} fileDrop
* @param {string} lockToken
* @param {string} shareToken
*/
export async function uploadFileDrop(folderId, fileDrop, lockToken, shareToken) {
export async function uploadFileDrop(encryptionVersion, folderId, fileDrop, lockToken, shareToken) {
const ocsUrl = generateOcsUrl(
'apps/end_to_end_encryption/api/v1/meta-data/{folderId}',
'apps/end_to_end_encryption/api/v{encryptionVersion}/meta-data/{folderId}',
{
encryptionVersion,
folderId,
}
)
Expand All @@ -103,10 +105,11 @@ export async function uploadFileDrop(folderId, fileDrop, lockToken, shareToken)
{
headers: {
'x-e2ee-supported': true,
'e2e-token': lockToken,
...(encryptionVersion === 2 ? { 'e2e-token': lockToken } : {}),
},
params: {
shareToken,
...(encryptionVersion === 1 ? { 'e2e-token': lockToken } : {}),
Comment thread
nfebe marked this conversation as resolved.
Outdated
},
},
)
Expand Down
12 changes: 8 additions & 4 deletions src/services/lock.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import { generateOcsUrl } from '@nextcloud/router'
import axios from '@nextcloud/axios'

/**
* @param {1|2} encryptionVersion - The encrypted version for the folder
* @param {number} counter - The metadata counter received from the initial state
* @param {string} fileId - The file id to lock
* @param {?string} shareToken - The optional share token if this is a file drop.
* @return {Promise<string>} lockToken
*/
export async function lock(fileId, shareToken) {
export async function lock(encryptionVersion, counter, fileId, shareToken) {
const { data: { ocs: { meta, data } } } = await axios.post(
generateOcsUrl('apps/end_to_end_encryption/api/v1/lock/{fileId}', { fileId }),
generateOcsUrl('apps/end_to_end_encryption/api/v{encryptionVersion}/lock/{fileId}', { encryptionVersion, fileId }),
undefined,
{
headers: {
'x-e2ee-supported': true,
'x-nc-e2ee-counter': counter,
},
params: {
shareToken,
Expand All @@ -31,13 +34,14 @@ export async function lock(fileId, shareToken) {
}

/**
* @param {1|2} encryptionVersion - The encrypted version for the folder
* @param {string} fileId - The file id to lock
* @param {string} lockToken - The optional lock token if the folder was already locked.
* @param {?string} shareToken - The optional share token if this is a file drop.
*/
export async function unlock(fileId, lockToken, shareToken) {
export async function unlock(encryptionVersion, fileId, lockToken, shareToken) {
const { data: { ocs: { meta } } } = await axios.delete(
generateOcsUrl('apps/end_to_end_encryption/api/v1/lock/{fileId}', { fileId }),
generateOcsUrl('apps/end_to_end_encryption/api/v{encryptionVersion}/lock/{fileId}', { encryptionVersion, fileId }),
{
headers: {
'x-e2ee-supported': true,
Expand Down
11 changes: 8 additions & 3 deletions src/views/FileDrop.vue
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ export default {
publicKey: loadState('end_to_end_encryption', 'publicKey'),
/** @type {string} */
fileName: loadState('end_to_end_encryption', 'fileName'),
/** @type {"v1"|"v2"} */
encryptionVersion: Number.parseInt(loadState('end_to_end_encryption', 'encryptionVersion')),
/** @type {number} */
counter: Number.parseInt(loadState('end_to_end_encryption', 'counter')),
/** @type {{file: File, step: string, error: boolean}[]} */
uploadedFiles: [],
loading: false,
Expand Down Expand Up @@ -149,7 +153,7 @@ export default {

try {
logger.debug('Locking the folder', { lockToken: this.lockToken, shareToken: this.shareToken })
lockToken = await lock(this.folderId, this.shareToken)
lockToken = await lock(this.encryptionVersion, this.counter + 1, this.folderId, this.shareToken)
} catch (exception) {
logger.error('Could not lock the folder', { exception })
showError(t('end_to_end_encryption', 'Could not lock the folder'))
Expand Down Expand Up @@ -179,7 +183,7 @@ export default {
.filter(({ error }) => !error)
.reduce((fileDropEntries, { fileDrop }) => ({ ...fileDropEntries, ...fileDrop }), {})

await uploadFileDrop(this.folderId, fileDrops, lockToken, this.shareToken)
await uploadFileDrop(this.encryptionVersion, this.folderId, fileDrops, lockToken, this.shareToken)
} catch (exception) {
logger.error('Error while uploading metadata', { exception })
showError(t('end_to_end_encryption', 'Error while uploading metadata'))
Expand All @@ -190,7 +194,8 @@ export default {
progresses
.filter(({ error }) => !error)
.forEach(progress => { progress.step = UploadStep.UNLOCKING })
await unlock(this.folderId, lockToken, this.shareToken)
await unlock(this.encryptionVersion, this.folderId, lockToken, this.shareToken)
this.counter++
logger.debug('Unlocking the folder', { lockToken, shareToken: this.shareToken })
progresses
.filter(({ error }) => !error)
Expand Down