-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add encryptFileWithKeys #580
base: develop
Are you sure you want to change the base?
Conversation
WalkthroughThe introduced changeset adds a new function Changes
Uplevel your code reviews with CodeRabbit ProCodeRabbit ProIf you like this project, please support us by purchasing the Pro version. The Pro version has advanced context, superior noise reduction and several proprietary improvements compared to the open source version. Moreover, CodeRabbit Pro is free for open source projects. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Files selected (1)
- packages/web/src/pages/Submissions/SubmissionFormPage/encrypt.ts (2)
Files ignored due to filter (2)
- packages/web/package.json
- yarn.lock
Review comments generated (2)
- Review: 1
- LGTM: 1
Tips
Chat with CodeRabbit Bot (@coderabbitai
)
- Reply on review comments left by this bot to ask follow-up questions. A review comment is a comment on a diff or a file.
- Invite the bot into a review comment chain by tagging
@coderabbitai
in a reply.
Code suggestions
- The bot may make code suggestions, but please review them carefully before committing since the line number ranges may be misaligned.
- You can edit the comment made by the bot and manually tweak the suggestion if it is slightly off.
Pausing incremental reviews
- Add
@coderabbitai: ignore
anywhere in the PR description to pause further reviews from the bot.
export async function encryptFileWithKeys(publicKeyOrKeys: string | string[], fileToEncrypt: File) { | ||
let encryptionKeys: MaybeArray<Key>; | ||
|
||
if (Array.isArray(publicKeyOrKeys)) { | ||
encryptionKeys = []; | ||
|
||
const encryptionKeysList = await Promise.all(publicKeyOrKeys.map((key) => readKey({ armoredKey: key }))); | ||
for (let key of encryptionKeysList) { | ||
try { | ||
await key.verifyPrimaryKey(); | ||
encryptionKeys.push(key); | ||
} catch { | ||
continue; | ||
} | ||
} | ||
|
||
if (encryptionKeys.length === 0) return undefined; | ||
} else { | ||
encryptionKeys = await readKey({ armoredKey: publicKeyOrKeys }); | ||
|
||
try { | ||
await encryptionKeys.verifyPrimaryKey(); | ||
} catch (error) { | ||
return undefined; | ||
} | ||
} | ||
|
||
const sessionKey = await generateSessionKey({ encryptionKeys }); | ||
|
||
const message = await encrypt({ | ||
message: await createMessage({ binary: new Uint8Array(await fileToEncrypt.arrayBuffer() as ArrayBuffer) }), | ||
encryptionKeys, | ||
sessionKey, | ||
}); | ||
|
||
const encryptedData = await readToEnd(message); | ||
|
||
const encryptedFile = new File([encryptedData], fileToEncrypt.name, {type: fileToEncrypt.type}) | ||
|
||
return { encryptedFile, sessionKey }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function encryptFileWithKeys
is quite large and does a lot of things. It would be beneficial to break it down into smaller, more manageable functions. This will improve readability, maintainability, and testability.
For example, the key reading and verification process could be extracted into its own function:
+ async function readAndVerifyKeys(publicKeyOrKeys: string | string[]): Promise<MaybeArray<Key> | undefined> {
+ let encryptionKeys: MaybeArray<Key>;
+
+ if (Array.isArray(publicKeyOrKeys)) {
+ encryptionKeys = [];
+
+ const encryptionKeysList = await Promise.all(publicKeyOrKeys.map((key) => readKey({ armoredKey: key })));
+ for (let key of encryptionKeysList) {
+ try {
+ await key.verifyPrimaryKey();
+ encryptionKeys.push(key);
+ } catch {
+ continue;
+ }
+ }
+
+ if (encryptionKeys.length === 0) return undefined;
+ } else {
+ encryptionKeys = await readKey({ armoredKey: publicKeyOrKeys });
+
+ try {
+ await encryptionKeys.verifyPrimaryKey();
+ } catch (error) {
+ return undefined;
+ }
+ }
+
+ return encryptionKeys;
+ }
- export async function encryptFileWithKeys(publicKeyOrKeys: string | string[], fileToEncrypt: File) {
- let encryptionKeys: MaybeArray<Key>;
-
- if (Array.isArray(publicKeyOrKeys)) {
- encryptionKeys = [];
-
- const encryptionKeysList = await Promise.all(publicKeyOrKeys.map((key) => readKey({ armoredKey: key })));
- for (let key of encryptionKeysList) {
- try {
- await key.verifyPrimaryKey();
- encryptionKeys.push(key);
- } catch {
- continue;
- }
- }
-
- if (encryptionKeys.length === 0) return undefined;
- } else {
- encryptionKeys = await readKey({ armoredKey: publicKeyOrKeys });
-
- try {
- await encryptionKeys.verifyPrimaryKey();
- } catch (error) {
- return undefined;
- }
- }
+ const encryptionKeys = await readAndVerifyKeys(publicKeyOrKeys);
+ if (!encryptionKeys) return undefined;
const sessionKey = await generateSessionKey({ encryptionKeys });
const message = await encrypt({
message: await createMessage({ binary: new Uint8Array(await fileToEncrypt.arrayBuffer() as ArrayBuffer) }),
encryptionKeys,
sessionKey,
});
const encryptedData = await readToEnd(message);
const encryptedFile = new File([encryptedData], fileToEncrypt.name, {type: fileToEncrypt.type})
return { encryptedFile, sessionKey };
}
Also, it's important to note that the function currently swallows any errors that occur during the key verification process. This could make debugging difficult in the future. It might be better to let these errors propagate up to the caller, or at least log them for future reference.
Deploying with Cloudflare Pages
|
Summary by CodeRabbit
encryptFileWithKeys
in the SubmissionFormPage. This feature enhances the security of file submissions by encrypting them using one or more public keys. The encrypted file and session key are returned, ensuring secure transmission and storage of sensitive user data.