Skip to content

Commit

Permalink
🔧 Rename all the storage key to be dynamic
Browse files Browse the repository at this point in the history
  • Loading branch information
mostafa-kheibary committed Feb 25, 2024
1 parent c0fcb9c commit d9602b8
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 29 deletions.
3 changes: 2 additions & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
}
],
"action": {
"default_title": "ChatGuard",
"default_popup": "src/popup/popup.html"
},
"permissions": ["storage"]
"permissions": ["storage", "tabs"]
}
26 changes: 13 additions & 13 deletions src/class/Cipher.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import forge from "node-forge";
import type { Config } from "src/types/Config";
import { config } from "src/config";
import BrowserStorage from "src/utils/BrowserStorage";
import LocalStorage from "src/utils/LocalStorage";

export class Cipher {
constructor(private readonly config: Config) {}
constructor() {}

public async createDRSAP(message: string, to: string) {
let store = await BrowserStorage.get();
const secretKey = forge.random.getBytesSync(16);
const hexSecret = forge.util.bytesToHex(secretKey);

const ownPublicKey = forge.pki.publicKeyFromPem(store.user!.publicKey);
const { publicKey: publicKeyPem } = LocalStorage.getMap("chatguard_contacts", to);
const { publicKey: publicKeyPem } = LocalStorage.getMap(config.CONTACTS_STORAGE_KEY, to);
if (!publicKeyPem) return null;
const toPublicKey = forge.pki.publicKeyFromPem(publicKeyPem);
const r1 = forge.util.bytesToHex(ownPublicKey.encrypt(secretKey));
const r2 = forge.util.bytesToHex(toPublicKey.encrypt(secretKey));
const encryptedMessage = await this.encryptAES(message, hexSecret);
const template = this.config.ENCRYPT_PREFIX + r1 + r2 + encryptedMessage;
const template = config.ENCRYPT_PREFIX + r1 + r2 + encryptedMessage;
return template;
}
public async resolveDRSAP(packet: string) {
let store = await BrowserStorage.get();
const packetArray = packet.split(this.config.ENCRYPT_PREFIX)[1].split("");
const packetArray = packet.split(config.ENCRYPT_PREFIX)[1].split("");
const r1 = packetArray.splice(0, 128).join("");
const r2 = packetArray.splice(0, 128).join("");

Expand All @@ -45,46 +45,46 @@ export class Cipher {
public async createDRSAPHandshake(to: string) {
const store = await BrowserStorage.get();
const cleanedPublicKey = store.user!.publicKey.replace(/[\r\n]/g, "");
const packet = `${this.config.HANDSHAKE_PREFIX}__${new Date().getTime()}__${to}__${cleanedPublicKey}`;
const packet = `${config.HANDSHAKE_PREFIX}__${new Date().getTime()}__${to}__${cleanedPublicKey}`;
return packet;
}
public async resolveDRSAPHandshake(packet: string, from: string) {
const [_prefix, timestamp, toId, publicKey] = packet.split("__");
if (toId === from) return;
const oldContact = LocalStorage.getMap("chatguard_contacts", from);
const oldContact = LocalStorage.getMap(config.CONTACTS_STORAGE_KEY, from);
if (+timestamp < +(oldContact.timestamp || 0)) return;
const allHandshakes = LocalStorage.get("chatguard_contacts");
const allHandshakes = LocalStorage.get(config.CONTACTS_STORAGE_KEY);
let isFound = false;
for (let handshake in allHandshakes) {
if (publicKey === allHandshakes[handshake].publicKey) isFound = true;
}
if (isFound) {
LocalStorage.setMap("chatguard_contacts", from, {
LocalStorage.setMap(config.CONTACTS_STORAGE_KEY, from, {
...oldContact,
acknowledged: true,
});

return;
}

LocalStorage.setMap("chatguard_contacts", from, {
LocalStorage.setMap(config.CONTACTS_STORAGE_KEY, from, {
publicKey,
timestamp,
enable: true,
});
return this.createDRSAPAcknowledgment(from);
}
public createDRSAPAcknowledgment(toId: string) {
return `${this.config.ACKNOWLEDGMENT_PREFIX}__${toId}`;
return `${config.ACKNOWLEDGMENT_PREFIX}__${toId}`;
}
public resolveDRSAPAcknowledgment(packet: string, from: string) {
const [_, id] = packet.split("__");
if (from === id) return;

const user = LocalStorage.getMap("chatguard_contacts", from);
const user = LocalStorage.getMap(config.CONTACTS_STORAGE_KEY, from);
if (!user.publicKey) return;
user.acknowledged = true;
LocalStorage.setMap("chatguard_contacts", from, user);
LocalStorage.setMap(config.CONTACTS_STORAGE_KEY, from, user);
}
public static validatePublicPem(pem: string) {
try {
Expand Down
7 changes: 4 additions & 3 deletions src/components/base/Status.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { chatStore as state } from "src/store/chat.store";
import type { Field } from "src/types/Config";
import type Cipher from "src/class/Cipher";
import { config } from "src/config";
export let cipher: Cipher;
export let selector: Field;
Expand All @@ -15,14 +16,14 @@
let status: "safe" | "unsafe" = "unsafe";
const checkStatus = () => {
const contact = LocalStorage.getMap("chatguard_contacts", $url.id);
const contact = LocalStorage.getMap(config.CONTACTS_STORAGE_KEY, $url.id);
contact.publicKey ? (status = "safe") : (status = "unsafe");
};
url.subscribe(checkStatus);
onMount(() => {
LocalStorage.on("chatguard_contacts", async () => {
const user = LocalStorage.getMap("chatguard_contacts", $url.id);
LocalStorage.on(config.CONTACTS_STORAGE_KEY, async () => {
const user = LocalStorage.getMap(config.CONTACTS_STORAGE_KEY, $url.id);
if ($state.loading && user.publicKey) {
status = "safe";
const ack = cipher.createDRSAPAcknowledgment($url.id);
Expand Down
22 changes: 16 additions & 6 deletions src/components/base/Switch.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
export let label: string;
import { createEventDispatcher } from "svelte";
export let design = "inner label";
export let options: string[] = [];
export let fontSize = 16;
Expand All @@ -8,28 +9,33 @@
let checked = true;
const uniqueID = Math.floor(Math.random() * 100);
const dispatch = createEventDispatcher();
function handleClick(event: Event) {
const target = event.target as HTMLElement;
const state = target.getAttribute("aria-checked");
checked = state === "true" ? false : true;
value = checked ? "on" : "off";
dispatch("change", value);
}
$: value === "on" ? (checked = true) : (checked = false);
</script>

{#if design == "inner"}
<div class="s s--inner">
<span id={`switch-${uniqueID}`}>{label}</span>
<button role="switch" aria-checked={checked} aria-labelledby={`switch-${uniqueID}`} on:click={handleClick}>
<button
style="cursor: pointer;"
role="switch"
aria-checked={checked}
aria-labelledby={`switch-${uniqueID}`}
on:click={handleClick}>
<span>on</span>
<span>off</span>
</button>
</div>
{:else if design == "slider"}
<div class="s s--slider" style="font-size:{fontSize}px">
<span id={`switch-${uniqueID}`}>{label}</span>
<button role="switch" aria-checked={checked} aria-labelledby={`switch-${uniqueID}`} on:click={handleClick}>
</button>
</div>
Expand All @@ -41,7 +47,6 @@
aria-labelledby={`label-${uniqueID}`}
style="font-size:{fontSize}px"
id={`group-${uniqueID}`}>
<div class="legend" id={`label-${uniqueID}`}>{label}</div>
{#each options as option}
<input type="radio" id={`${option}-${uniqueID}`} value={option} bind:group={value} />
<label for={`${option}-${uniqueID}`}>
Expand All @@ -57,10 +62,14 @@
--accent-color: #0f7dff;
--gray: #ccc;
}
.option {
cursor: pointer;
}
/* Inner Design Option */
.s--inner button {
padding: 0.5em;
background-color: #fff;
border-radius: 0.2rem;
border: 1px solid var(--gray);
}
[role="switch"][aria-checked="true"] :first-child,
Expand All @@ -72,13 +81,14 @@
.s--inner button span {
user-select: none;
pointer-events: none;
padding: 0.25em;
padding: 0.25em 0.8rem;
}
/* Slider Design Option */
.s--slider {
display: flex;
justify-content: center;
align-items: center;
}
Expand Down
17 changes: 17 additions & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
import type { Config, Selector } from "src/types/Config";

export const initLog = `
██████ ██ ██ █████ ████████
██ ██ ██ ██ ██ ██
██ ███████ ███████ ██
██ ██ ██ ██ ██ ██
██████ ██ ██ ██ ██ ██
██████ ██ ██ █████ ██████ ██████
██ ██ ██ ██ ██ ██ ██ ██ ██
██ ███ ██ ██ ███████ ██████ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██████ ██████ ██ ██ ██ ██ ██████
`;

export const config: Config = {
CONTACTS_STORAGE_KEY: "chatguard_contacts",
ENCRYPT_PREFIX: `::CGM::`,
HANDSHAKE_PREFIX: `::HSH::`,
ACKNOWLEDGMENT_PREFIX: `::ACK::`,
Expand Down
11 changes: 5 additions & 6 deletions src/content/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Status from "src/components/base/Status.svelte";
import { config } from "src/config";
import { config, initLog } from "src/config";
import Cipher from "src/class/Cipher";
import LoadingScreen from "src/components/base/LoadingScreen.svelte";
import { get } from "svelte/store";
Expand Down Expand Up @@ -32,7 +32,7 @@ async function register() {

store = await BrowserStorage.get();

LocalStorage.setMap("chatguard_contacts", "_me_", {
LocalStorage.setMap(config.CONTACTS_STORAGE_KEY, "_me_", {
publicKey: store.user?.publicKey,
timestamp: new Date().getTime(),
enable: true,
Expand All @@ -53,14 +53,14 @@ async function register() {

const idProvider = getIdProvider();

const cipher = new Cipher(config);
const cipher = new Cipher();
const appRoot = document.querySelector(selector.app) as HTMLElement;
const { on, onClick } = useListener(appRoot);
const { onObserve } = useObserver(appRoot);
const { render } = useRender(appRoot);
const { url, urlStore } = useUrl(idProvider);

new LoadingScreen({ target: document.body });
console.log(initLog);

render(selector.header, (target, id) => {
new Status({ target, props: { cipher, selector, id } });
Expand Down Expand Up @@ -98,7 +98,7 @@ async function register() {
});

url.subscribe((newUrl) => {
if (LocalStorage.getMap("chatguard_contacts", newUrl.id).publicKey) {
if (LocalStorage.getMap(config.CONTACTS_STORAGE_KEY, newUrl.id).publicKey) {
document.querySelector(selector.textField)?.dispatchEvent(new Event("input"));
}
});
Expand Down Expand Up @@ -148,7 +148,6 @@ async function register() {
}
// HandShakes
if (textNodeContent.startsWith(config.HANDSHAKE_PREFIX)) {
console.log(urlStore);
changeTextNode(target, "⏳ Loading ...");
await cipher.resolveDRSAPHandshake(textNodeContent, urlStore.id);
changeTextNode(target, "🤝 encryption Handshake");
Expand Down
1 change: 1 addition & 0 deletions src/types/Config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface Selector {
}

export interface Config {
CONTACTS_STORAGE_KEY: string;
ENCRYPT_PREFIX: string;
HANDSHAKE_PREFIX: string;
ACKNOWLEDGMENT_PREFIX: string;
Expand Down

0 comments on commit d9602b8

Please sign in to comment.