🚧 Added Proof of Work on image-upload and more

This commit is contained in:
Mawoka
2022-06-20 21:47:12 +02:00
parent 2b8168ad5e
commit 25ac42bdae
13 changed files with 297 additions and 23 deletions
+1
View File
@@ -40,6 +40,7 @@
"@uppy/xhr-upload": "^2.1.2",
"autoprefixer": "^10.4.7",
"cookie": "^0.5.0",
"crypto-js": "^4.1.1",
"cssnano": "^5.1.11",
"eslint": "^8.17.0",
"eslint-config-prettier": "^8.5.0",
+9
View File
@@ -27,6 +27,7 @@ specifiers:
'@uppy/xhr-upload': ^2.1.2
autoprefixer: ^10.4.7
cookie: ^0.5.0
crypto-js: ^4.1.1
cssnano: ^5.1.11
eslint: ^8.17.0
eslint-config-prettier: ^8.5.0
@@ -89,6 +90,7 @@ devDependencies:
'@uppy/xhr-upload': 2.1.2_@uppy+core@2.3.1
autoprefixer: 10.4.7_postcss@8.4.14
cookie: 0.5.0
crypto-js: 4.1.1
cssnano: 5.1.11_postcss@8.4.14
eslint: 8.17.0
eslint-config-prettier: 8.5.0_eslint@8.17.0
@@ -1562,6 +1564,13 @@ packages:
which: 2.0.2
dev: true
/crypto-js/4.1.1:
resolution:
{
integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==
}
dev: true
/css-declaration-sorter/6.3.0_postcss@8.4.14:
resolution:
{
+12 -4
View File
@@ -1,12 +1,13 @@
<script lang="ts">
import { getLocalization } from '$lib/i18n';
import * as yup from 'yup';
import { mint } from '$lib/hashcash';
import { dataSchema } from '$lib/yupSchemas';
import type { EditorData, Question, Answer } from './quiz_types';
import Sidebar from '$lib/editor/sidebar.svelte';
import SettingsCard from '$lib/editor/settings-card.svelte';
import QuizCard from '$lib/editor/card.svelte';
import Spinner from './Spinner.svelte';
import { onMount } from 'svelte';
const { t } = getLocalization();
@@ -67,6 +68,7 @@
};
let edit_id;
let confirm_to_leave = true;
let pow_data;
const getEditID = async () => {
let res;
@@ -82,7 +84,7 @@
if (res.status === 200) {
const json = await res.json();
edit_id = json.token;
console.log(edit_id, json);
setPOWdata();
} else {
alert('Error!');
}
@@ -110,7 +112,6 @@
body: JSON.stringify(data)
});
if (res.ok) {
console.log('Hier');
confirm_to_leave = false;
console.log(confirm_to_leave);
window.location.href = '/overview';
@@ -118,6 +119,13 @@
alert('Error');
}
};
const setPOWdata = async () => {
const res = await fetch(`/api/v1/editor/pow?edit_id=${edit_id}`);
const data = (await res.json()).data;
console.log(data);
pow_data = await mint(data);
console.log(pow_data);
};
</script>
<svelte:window on:beforeunload={confirmUnload} />
@@ -167,7 +175,7 @@
{#if selected_question === -1}
<SettingsCard bind:data />
{:else}
<QuizCard bind:data bind:selected_question bind:edit_id />
<QuizCard bind:data bind:selected_question bind:edit_id bind:pow_data />
{/if}
</div>
</div>
+4
View File
@@ -8,6 +8,7 @@
export let data: EditorData;
export let selected_question: number;
export let edit_id: string;
export let pow_data;
const empty_answer: Answer = {
right: false,
answer: ''
@@ -67,6 +68,8 @@
}}
/>
</div>
{:else if pow_data === undefined}
<Spinner />
{:else}
{#await import('$lib/editor/uploader.svelte')}
<Spinner />
@@ -77,6 +80,7 @@
bind:edit_id
bind:data
bind:selected_question
bind:pow_data
/>
{/await}
{/if}
+4 -1
View File
@@ -20,7 +20,9 @@
export let edit_id: string;
export let data: EditorData;
export let selected_question: number;
export let pow_data;
console.log(pow_data);
const uppy = new Uppy()
.use(DropTarget, {
target: document.body
@@ -34,7 +36,7 @@
quality: 0.6
})
.use(XHRUpload, {
endpoint: `/api/v1/editor/image?edit_id=${edit_id}`
endpoint: `/api/v1/editor/image?edit_id=${edit_id}&pow_data=${pow_data}`
});
const props = { inline: true };
let image_id;
@@ -42,6 +44,7 @@
image_id = response.body.id;
});
uppy.on('complete', (res) => {
console.log(pow_data);
data.questions[
selected_question
].image = `${window.location.origin}/api/v1/storage/download/${image_id}`;
+47
View File
@@ -0,0 +1,47 @@
import { DateTime } from 'luxon';
const gen_salt = (l: number): string => {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const charLength = chars.length;
let result = '';
for (let i = 0; i < l; i++) {
result += chars.charAt(Math.floor(Math.random() * charLength));
}
return result;
};
export const mint = async (
resource: string,
bits = 19,
now = null,
ext = '',
saltchars = 8,
stamp_seconds = false
): Promise<string> => {
const ver = '1';
let ts;
if (stamp_seconds) {
ts = DateTime.now().toFormat('yyMMddHHmmss');
} else {
ts = DateTime.now().toFormat('yyMMdd');
}
const hex_digits = Math.ceil(bits / 4);
const zeros = '0'.repeat(hex_digits);
const salt = gen_salt(saltchars);
const challenge = `${ver}:${bits}:${ts}:${resource}:${ext}:${salt}`;
let digest: string;
let counter = 0;
let result: string;
while (true) {
const data = new TextEncoder().encode(`${challenge}:${counter.toString(16)}`);
const hashBuffer = await crypto.subtle.digest('SHA-1', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const digest = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
if (digest.slice(0, hex_digits) == zeros) {
result = counter.toString(16);
break;
}
counter += 1;
}
return `${challenge}:${result}`;
};
+1
View File
@@ -20,6 +20,7 @@
import LandingPromo from '$lib/landing/landing-promo.svelte';
import { onMount } from 'svelte';
import { mint } from '$lib/hashcash';
const { t } = getLocalization();