This commit is contained in:
Dawid Wysokiński 2022-11-27 08:26:10 +01:00
parent d85ebaf95d
commit ece1fb6ff5
Signed by: Kichiyaki
GPG Key ID: B5445E357FB8B892
8 changed files with 57 additions and 31 deletions

View File

@ -1,6 +1,6 @@
{
"name": "sessions-ext",
"version": "0.0.1",
"version": "0.1.0",
"description": "",
"scripts": {
"build": "parcel build src/manifest.json --no-content-hash --no-source-maps --dist-dir dist --detailed-report 0",

View File

@ -1,15 +1,20 @@
import { LoginMessage, Message, MessageType } from './message';
import { LoginMessage, LoginResponse, Message, MessageType } from './message';
import { optionsStorage } from './options-storage';
import { decrypt, encrypt } from './crypto';
const COOKIE_NAME = 'sid';
const HTTP_STATUS_OK = 200;
const API_KEY_HEADER = 'X-Api-Key';
chrome.runtime.onMessage.addListener(
(message: Message, sender, sendResponse) => {
switch (message.type) {
case MessageType.LOGIN:
handleLogin(message);
async (message: Message, sender, sendResponse) => {
try {
switch (message.type) {
case MessageType.LOGIN:
await handleLogin(message);
}
} catch (err: any) {
sendResponse({ error: err.message } as LoginResponse);
}
}
);
@ -20,8 +25,6 @@ const handleLogin = async (message: LoginMessage) => {
url: message.url,
});
console.log(sid);
if (sid) {
const success = await tryOpenOverview(message.url);
if (success) {
@ -93,7 +96,7 @@ const createOrUpdateCookie = async (server: string, sid: string) => {
method: 'PUT',
body: sid,
headers: {
'X-Api-Key': opts.apiKey,
[API_KEY_HEADER]: opts.apiKey,
'Content-Type': 'text/plain',
},
});
@ -108,7 +111,7 @@ const getSid = async (server: string): Promise<string> => {
const resp = await fetch(url, {
method: 'GET',
headers: {
'X-Api-Key': opts.apiKey,
[API_KEY_HEADER]: opts.apiKey,
},
});

View File

@ -1,4 +1,6 @@
import { LoginMessage, MessageType } from './message';
import { LoginMessage, LoginResponse, MessageType } from './message';
let isLoggingIn = false;
const renderUI = () => {
document
@ -21,21 +23,35 @@ const renderUI = () => {
});
};
const handleClick = (e: MouseEvent) => {
const handleClick = async (e: MouseEvent) => {
if (!(e.currentTarget instanceof HTMLAnchorElement)) {
return;
}
e.preventDefault();
if (isLoggingIn) {
return;
}
isLoggingIn = true;
const url = new URL(e.currentTarget.href);
const server = extractServerFromURL(url);
chrome.runtime.sendMessage({
type: MessageType.LOGIN,
server,
loginUrl: url.toString(),
url: url.protocol + '//' + url.host.replace('www', server),
} as LoginMessage);
chrome.runtime
.sendMessage({
type: MessageType.LOGIN,
server,
loginUrl: url.toString(),
url: url.protocol + '//' + url.host.replace('www', server),
} as LoginMessage)
.then((resp: LoginResponse) => {
isLoggingIn = false;
if (!resp?.error) {
return;
}
console.error(resp.error);
});
};
const extractServerFromURL = (url: URL): string => {

View File

@ -1,11 +1,13 @@
const ITERATIONS = 100000;
const SALT_LENGTH = 16;
const IV_LENGTH = 12;
const enc = new TextEncoder();
const dec = new TextDecoder();
export const encrypt = async (data: string, password: string) => {
const salt = crypto.getRandomValues(new Uint8Array(16));
const iv = crypto.getRandomValues(new Uint8Array(12));
const salt = crypto.getRandomValues(new Uint8Array(SALT_LENGTH));
const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));
const passwordKey = await getPasswordKey(password);
const aesKey = await deriveKey(passwordKey, salt, ['encrypt']);
const encryptedContent = await crypto.subtle.encrypt(
@ -18,7 +20,7 @@ export const encrypt = async (data: string, password: string) => {
);
const encryptedContentArr = new Uint8Array(encryptedContent);
let buf = new Uint8Array(
const buf = new Uint8Array(
salt.byteLength + iv.byteLength + encryptedContentArr.byteLength
);
buf.set(salt, 0);
@ -29,9 +31,9 @@ export const encrypt = async (data: string, password: string) => {
export const decrypt = async (encryptedData: string, password: string) => {
const encryptedDataBuff = base64ToBuf(encryptedData);
const salt = encryptedDataBuff.slice(0, 16);
const iv = encryptedDataBuff.slice(16, 16 + 12);
const data = encryptedDataBuff.slice(16 + 12);
const salt = encryptedDataBuff.slice(0, SALT_LENGTH);
const iv = encryptedDataBuff.slice(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);
const data = encryptedDataBuff.slice(SALT_LENGTH + IV_LENGTH);
const passwordKey = await getPasswordKey(password);
const aesKey = await deriveKey(passwordKey, salt, ['decrypt']);
const decryptedContent = await crypto.subtle.decrypt(

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -1,7 +1,7 @@
{
"name": "Awesome Extension",
"version": "0.0.0",
"description": "An awesome new browser extension",
"name": "Sessions",
"version": "0.1.0",
"description": "A browser extension aiming to simplify coplaying",
"homepage_url": "https://tribalwarshelp.com/",
"manifest_version": 3,
"minimum_chrome_version": "100",
@ -13,10 +13,10 @@
"default_popup": "popup.html"
},
"permissions": ["storage", "cookies", "activeTab", "tabs"],
"host_permissions": ["https://*.tribalwars.net/*"],
"host_permissions": ["https://*.tribalwars.net/*", "https://*.plemiona.pl/*"],
"content_scripts": [
{
"matches": ["https://www.tribalwars.net/*"],
"matches": ["https://www.tribalwars.net/*", "https://www.plemiona.pl/*"],
"js": ["content.ts"],
"run_at": "document_end"
}
@ -24,5 +24,6 @@
"background": {
"service_worker": "background.ts",
"type": "module"
}
},
"author": "Dawid Wysokiński"
}

View File

@ -10,3 +10,7 @@ export type LoginMessage = {
};
export type Message = LoginMessage;
export type LoginResponse = {
error?: string;
};

View File

@ -11,7 +11,7 @@
</head>
<body>
<main>
<h1>Hello</h1>
<h1>Options</h1>
<section id="options">
<form>
<label