mirror of
https://github.com/cupcakearmy/cryptgeon.git
synced 2025-09-06 17:30:39 +00:00
add password to frontend
This commit is contained in:
@@ -8,48 +8,69 @@
|
||||
|
||||
export let note: Note
|
||||
export let timeExpiration = false
|
||||
|
||||
let customPassword = false
|
||||
|
||||
$: if (!customPassword) note.password = undefined
|
||||
</script>
|
||||
|
||||
<div class="fields">
|
||||
<TextInput
|
||||
data-testid="field-views"
|
||||
type="number"
|
||||
label={$t('common.views', { values: { n: 0 } })}
|
||||
bind:value={note.views}
|
||||
disabled={timeExpiration}
|
||||
max={$status?.max_views}
|
||||
min={1}
|
||||
validate={(v) =>
|
||||
($status && v <= $status?.max_views && v > 0) ||
|
||||
$t('home.errors.max', { values: { n: $status?.max_views ?? 0 } })}
|
||||
/>
|
||||
<div class="middle-switch">
|
||||
<div class="flex col">
|
||||
<div class="flex">
|
||||
<TextInput
|
||||
data-testid="field-views"
|
||||
type="number"
|
||||
label={$t('common.views', { values: { n: 0 } })}
|
||||
bind:value={note.views}
|
||||
disabled={timeExpiration}
|
||||
max={$status?.max_views}
|
||||
min={1}
|
||||
validate={(v) =>
|
||||
($status && v <= $status?.max_views && v > 0) ||
|
||||
$t('home.errors.max', { values: { n: $status?.max_views ?? 0 } })}
|
||||
/>
|
||||
<Switch
|
||||
data-testid="switch-advanced-toggle"
|
||||
label={$t('common.mode')}
|
||||
bind:value={timeExpiration}
|
||||
color={false}
|
||||
/>
|
||||
<TextInput
|
||||
data-testid="field-expiration"
|
||||
type="number"
|
||||
label={$t('common.minutes', { values: { n: 0 } })}
|
||||
bind:value={note.expiration}
|
||||
disabled={!timeExpiration}
|
||||
max={$status?.max_expiration}
|
||||
validate={(v) =>
|
||||
($status && v < $status?.max_expiration) ||
|
||||
$t('home.errors.max', { values: { n: $status?.max_expiration ?? 0 } })}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<Switch bind:value={customPassword} label={$t('home.advanced.custom_password')} />
|
||||
<TextInput
|
||||
type="password"
|
||||
bind:value={note.password}
|
||||
label={$t('common.password')}
|
||||
disabled={!customPassword}
|
||||
random
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{$t('home.advanced.explanation')}
|
||||
</div>
|
||||
<TextInput
|
||||
data-testid="field-expiration"
|
||||
type="number"
|
||||
label={$t('common.minutes', { values: { n: 0 } })}
|
||||
bind:value={note.expiration}
|
||||
disabled={!timeExpiration}
|
||||
max={$status?.max_expiration}
|
||||
validate={(v) =>
|
||||
($status && v < $status?.max_expiration) ||
|
||||
$t('home.errors.max', { values: { n: $status?.max_expiration ?? 0 } })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.middle-switch {
|
||||
margin: 0 1rem;
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fields {
|
||||
display: flex;
|
||||
.col {
|
||||
gap: 1.5rem;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" context="module">
|
||||
export type NoteResult = {
|
||||
password: string
|
||||
id: string
|
||||
password?: string
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
export let result: NoteResult
|
||||
|
||||
$: url = `${window.location.origin}/note/${result.id}#${result.password}`
|
||||
let url = `${window.location.origin}/note/${result.id}`
|
||||
if (result.password) url += `#${result.password}`
|
||||
|
||||
function reset() {
|
||||
window.location.reload()
|
||||
|
@@ -4,43 +4,35 @@
|
||||
export let color = true
|
||||
</script>
|
||||
|
||||
<div {...$$restProps}>
|
||||
<label class="switch">
|
||||
<small>{label}</small>
|
||||
<input type="checkbox" bind:checked={value} />
|
||||
<span class:color class="slider" />
|
||||
</label>
|
||||
</div>
|
||||
<label {...$$restProps}>
|
||||
<small>{label}</small>
|
||||
<input type="checkbox" bind:checked={value} />
|
||||
<span class:color class="slider" />
|
||||
</label>
|
||||
|
||||
<style>
|
||||
div {
|
||||
height: 3.75rem;
|
||||
}
|
||||
|
||||
.switch {
|
||||
label {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 4rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
label input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
small {
|
||||
display: block;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 4rem;
|
||||
height: 2.5rem;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border: 2px solid var(--ui-bg-1);
|
||||
background-color: var(--ui-bg-0);
|
||||
transition: var(--ui-anim);
|
||||
transform: translateY(1.2rem);
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
|
@@ -30,7 +30,7 @@
|
||||
</script>
|
||||
|
||||
<label>
|
||||
<small disabled={$$restProps.disabled}>
|
||||
<small class:disabled={$$restProps.disabled}>
|
||||
{label}
|
||||
{#if valid !== true}
|
||||
<span class="error-text">{valid}</span>
|
||||
@@ -54,6 +54,7 @@
|
||||
label {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
label > small {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { AES, Hex } from 'occulto'
|
||||
import { AES, Hex, Bytes } from 'occulto'
|
||||
import { t } from 'svelte-intl-precompile'
|
||||
import { blur } from 'svelte/transition'
|
||||
|
||||
@@ -57,13 +57,14 @@
|
||||
try {
|
||||
loading = $t('common.encrypting')
|
||||
|
||||
const key = await AES.generateKey()
|
||||
const password = Hex.encode(key)
|
||||
const derived = note.password && (await AES.derive(note.password))
|
||||
const key = derived ? derived[0] : await AES.generateKey()
|
||||
|
||||
const data: Note = {
|
||||
contents: '',
|
||||
meta: note.meta,
|
||||
}
|
||||
if (derived) data.meta.derivation = derived[1]
|
||||
if (isFile) {
|
||||
if (files.length === 0) throw new EmptyContentError()
|
||||
data.contents = await Adapters.Files.encrypt(files, key)
|
||||
@@ -77,8 +78,8 @@
|
||||
loading = $t('common.uploading')
|
||||
const response = await create(data)
|
||||
result = {
|
||||
password: password,
|
||||
id: response.id,
|
||||
password: note.password ? undefined : Hex.encode(key),
|
||||
}
|
||||
notify.success($t('home.messages.note_created'))
|
||||
} catch (e) {
|
||||
@@ -148,7 +149,7 @@
|
||||
|
||||
{#if advanced}
|
||||
<div transition:blur={{ duration: 250 }}>
|
||||
<br />
|
||||
<hr />
|
||||
<AdvancedParameters bind:note bind:timeExpiration />
|
||||
</div>
|
||||
{/if}
|
||||
|
@@ -23,6 +23,7 @@
|
||||
right: 0;
|
||||
width: 100%;
|
||||
background-color: var(--ui-bg-0-85);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
a {
|
||||
|
Reference in New Issue
Block a user