Skip to content

Commit

Permalink
added support for multiple recepients
Browse files Browse the repository at this point in the history
  • Loading branch information
SammCheese committed Feb 24, 2023
1 parent c61952e commit 9f197aa
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 44 deletions.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"discordID": "372148345894076416",
"github": "SammCheese"
},
"version": "1.1.1",
"version": "1.2.0",
"updater": {
"type": "github",
"id": "SammCheese/RepluggedPGP"
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "repluggedpgp",
"version": "1.1.1",
"version": "1.2.0",
"description": "Encrypt, Sign and Decrypt messages with the power of GPG",
"engines": {
"node": ">=14.0.0"
Expand Down Expand Up @@ -32,7 +32,7 @@
"eslint-plugin-react": "^7.31.10",
"openpgp": "^5.5.0",
"prettier": "^2.8.1",
"replugged": "4.0.0-beta0.27",
"replugged": "4.0.0-beta0.28",
"typescript": "^4.8.4"
},
"dependencies": {
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/components/AddKey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ function AddKey(props: any) {
<Button
onClick={() => {
const savedArr = PGPSettings.get("savedPubKeys", []);
if (!savedArr.some((k) => k.includes(props.pubKey)))
if (!savedArr.some((k) => k.includes(props.pubKey))) {
PGPSettings.set("savedPubKeys", [...savedArr, props.pubKey]);
common.toast.toast("Added Key!", common.toast.Kind.SUCCESS);
}
closeModal(modalKey);
}}>
Add Public Key
Expand Down
66 changes: 40 additions & 26 deletions src/components/RecepientSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { common, components } from "replugged";
import { PGPSettings, getKey } from "../utils";

const { React } = common;
const { Button, Modal, Text, SelectItem, ErrorBoundary } = components;
const { Button, Modal, Text, CheckboxItem, ErrorBoundary } = components;
const { closeModal, openModal } = common.modal;

let modalKey: any;
Expand All @@ -14,29 +14,33 @@ interface PubKey {
}

function RecepientSelection(props: any) {
let [recepient, setRecepient] = React.useState("");
let [savedRecepients] = React.useState<PubKey[]>([]);
let [recepients, setRecepients] = React.useState<string[]>([]);
let [savedRecepients, setSavedRecepients] = React.useState<PubKey[]>([]);
let [isLoading, setIsLoading] = React.useState(true);

const handleConfirm = () => {
closeModal(modalKey);
props.onConfirm(recepient);
props.onConfirm(recepients);
};

onkeydown = (e) => {
if (e.key === "Enter") handleConfirm();
};

async function convertKeys() {
const keys = PGPSettings.get("savedPubKeys", []);
React.useEffect(() => {
async function convertKeys() {
const keys = PGPSettings.get("savedPubKeys", []);

for (const res of keys) {
const keyObject = await getKey(res);
savedRecepients.push({ keyObject, publicKey: res });
const recepients = await Promise.all(
keys.map(async (res) => {
const keyObject = await getKey(res);
return { keyObject, publicKey: res };
}),
);
setSavedRecepients(recepients);
}
}

React.useEffect(() => {
convertKeys();
convertKeys().then(() => setIsLoading(false));
}, []);

return (
Expand All @@ -45,19 +49,29 @@ function RecepientSelection(props: any) {
<Text.H1>Key Selection</Text.H1>
</Modal.ModalHeader>
<Modal.ModalContent>
{savedRecepients[0] ? (
<SelectItem
style={{ marginTop: "15px" }}
value={recepient}
options={savedRecepients.map((key) => ({
label: key.keyObject.users[0].userID?.userID! ?? "Couldnt fetch Username",
value: key.publicKey,
}))}
onChange={(e) => {
setRecepient(e);
}}></SelectItem>
) : (
<Text>Looks like you dont have any Public Keys yet, try adding some in Settings</Text>
{!isLoading && (
<>
{savedRecepients[0] ? (
<>
{savedRecepients.map((key) => (
<CheckboxItem
key={key.keyObject.getKeyID().toHex()}
onChange={() => {
setRecepients(
recepients.includes(key.publicKey)
? recepients.filter((elem) => elem !== key.publicKey)
: recepients.concat(key.publicKey),
);
}}
value={recepients.includes(key.publicKey)}>
{`${key.keyObject.users[0].userID?.userID}` ?? "Unknown User"}
</CheckboxItem>
))}
</>
) : (
<Text>Looks like you dont have any Public Keys yet, try adding some in Settings</Text>
)}
</>
)}
</Modal.ModalContent>
<Modal.ModalFooter>
Expand All @@ -67,7 +81,7 @@ function RecepientSelection(props: any) {
);
}

export function buildRecepientSelection(): Promise<string> {
export function buildRecepientSelection(): Promise<string[]> {
return new Promise((resolve) => {
try {
modalKey = openModal((props: any) => (
Expand Down
5 changes: 4 additions & 1 deletion src/components/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { common, components } from "replugged";
import { buildAddKeyModal } from "./AddKey";
import { getKey, pgpFormat } from "../utils";
import { PGPSettings, getKey, pgpFormat } from "../utils";
import { get, set } from "idb-keyval";

const { React } = common;
Expand Down Expand Up @@ -42,7 +42,10 @@ export function Settings() {
/>
<Button
style={{ flexBasis: "10%" }}
// eslint-disable-next-line consistent-return
onClick={async () => {
if (PGPSettings.get("savedPubKeys")?.includes(publicKeyField))
return common.toast.toast("Key already Added", common.toast.Kind.MESSAGE);
buildAddKeyModal({
keyInfo: await getKey(publicKeyField),
pubKey: publicKeyField,
Expand Down
13 changes: 7 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {

import { popoverIcon } from "./assets/PopoverIcon";
import { PGPToggleButton } from "./assets/ToggleButton";
import { buildRecepientSelection } from "./components/RecepientSelection";

import { PGPCONSTS } from "./constants";
import { DiscordMessage } from "./repluggedpgp";
Expand Down Expand Up @@ -43,6 +42,7 @@ export async function start(): Promise<void> {
};
}

// Used for Decryption
async function receiver(message: DiscordMessage): Promise<void> {
let tempContent = message.content;

Expand Down Expand Up @@ -98,15 +98,16 @@ async function injectSendMessage(): Promise<void> {
injector.instead(common.messages, "sendMessage", async (args, fn) => {
const { signingActive, encryptionActive, asFile } = PGPSettings.all();

if (encryptionActive)
args[1].content = await encryptMessage(args[1].content, [
await getKey(await buildRecepientSelection()),
]);
if (encryptionActive) args[1].content = await encryptMessage(args[1].content);

if (signingActive) args[1].content = await signMessage(args[1].content);

// premiumType, 0 - No nitro, 1 - Nitro Classic, 2 - Nitro, 3 - Nitro Basic
const isNitro = common.users.getCurrentUser().premiumType === 2;

// Always send as file if encrypted string is above no-nitro limit
if (args[1].content.length > 2000) return sendAsFile(args[1].content);
if (isNitro ? args[1].content.length > 4000 : args[1].content.length > 2000)
return sendAsFile(args[1].content);

// do not format in files
if (!asFile && (encryptionActive || signingActive))
Expand Down
10 changes: 7 additions & 3 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { common, settings, types, webpack } from "replugged";
import { buildKeyPass } from "./components/KeyPassword";
import { MaybeArray, PrivateKey, PublicKey, UserIDPacket, VerificationResult } from "openpgp";
import { addFileType, decryptMessageType } from "./repluggedpgp";
import { buildRecepientSelection } from "./components/RecepientSelection";

const { channels } = common;
const { addFile }: types.ModuleExportsWithProps<"addFiles"> & addFileType =
Expand Down Expand Up @@ -94,10 +95,13 @@ export async function verifyMessage(
return vResult.signatures[0];
}

export async function encryptMessage(message: string, recepients: PublicKey[]): Promise<string> {
export async function encryptMessage(message: string): Promise<string> {
const recepients = await buildRecepientSelection();
const publicKeys = await Promise.all(recepients.map((armoredKey) => pgp.readKey({ armoredKey })));

return await pgp.encrypt({
message: await pgp.createMessage({ text: message }),
encryptionKeys: recepients,
encryptionKeys: publicKeys,
});
}

Expand All @@ -117,7 +121,7 @@ export async function decryptMessage(message: string): Promise<decryptMessageTyp
}

export async function parseMessageFileContent(url: string): Promise<string> {
if (!url.endsWith("message.txt")) return "";
if (!url.endsWith(".txt") || !url.endsWith(".asc")) return "";
return await new Promise(async (resolve) => {
await fetch(url)
.then((res) => resolve(res.text()))
Expand Down

0 comments on commit 9f197aa

Please sign in to comment.