Require login for file upload
This commit is contained in:
@@ -163,10 +163,11 @@ const fullscreen = () => {
|
||||
|
||||
<IconBlock icon_href={file.icon_href}>
|
||||
|
||||
The online video player on pixeldrain is only available if the viewer or
|
||||
the uploader of the video has a registered pixeldrain account. You can
|
||||
still download the video and watch it locally on your computer without
|
||||
an account.
|
||||
The online video player on pixeldrain is only available while logged in
|
||||
to an account, or if the uploading user has verified their e-mail
|
||||
address. You can still download the video and watch it locally on your
|
||||
computer without an account.
|
||||
|
||||
<br/>
|
||||
<button on:click={download}>
|
||||
<i class="icon">download</i> Download
|
||||
|
@@ -7,12 +7,31 @@ import { formatDataVolume } from "../util/Formatting.svelte";
|
||||
let button
|
||||
let dialog
|
||||
|
||||
export let no_login_label = "Pixeldrain"
|
||||
export let hide_name = true
|
||||
export let hide_logo = false
|
||||
|
||||
const open = () => {
|
||||
// Show the window so we can get the location
|
||||
dialog.showModal()
|
||||
|
||||
let rect = button.getBoundingClientRect()
|
||||
dialog.style.top = Math.round(rect.bottom) + "px"
|
||||
dialog.style.left = Math.round(rect.left) + "px"
|
||||
const edge_offset = 5
|
||||
|
||||
// Get the egdes of the screen, so the window does not spawn off-screen
|
||||
const window_rect = dialog.getBoundingClientRect()
|
||||
const max_left = window.innerWidth - window_rect.width - edge_offset
|
||||
const max_top = window.innerHeight - window_rect.height - edge_offset
|
||||
|
||||
// Get the location of the button
|
||||
const button_rect = button.getBoundingClientRect()
|
||||
|
||||
// Prevent the window from being glued to the edges
|
||||
const min_left = Math.max(button_rect.left, edge_offset)
|
||||
const min_top = Math.max(button_rect.bottom, edge_offset)
|
||||
|
||||
// Place the window
|
||||
dialog.style.left = Math.round(Math.min(min_left, max_left)) + "px"
|
||||
dialog.style.top = Math.round(Math.min(min_top, max_top)) + "px"
|
||||
}
|
||||
|
||||
// Close the dialog when the user clicks the background
|
||||
@@ -25,9 +44,11 @@ const click = e => {
|
||||
|
||||
<div class="wrapper">
|
||||
<button bind:this={button} on:click={open} href="/user" class="button round" title="Menu">
|
||||
<PixeldrainLogo style="height: 1.8em; width: 1.8em; margin: 2px;"></PixeldrainLogo>
|
||||
<span class="button_username">
|
||||
{window.user.username === "" ? "Pixeldrain" : window.user.username}
|
||||
{#if !hide_logo}
|
||||
<PixeldrainLogo style="height: 1.8em; width: 1.8em; margin: 2px;"/>
|
||||
{/if}
|
||||
<span class="button_username" class:hide_name>
|
||||
{window.user.username === "" ? no_login_label : window.user.username}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -37,8 +58,10 @@ const click = e => {
|
||||
<dialog bind:this={dialog} on:click={click}>
|
||||
<div class="menu">
|
||||
{#if window.user.username !== ""}
|
||||
<div class="menu_username">{window.user.username}</div>
|
||||
|
||||
<Button link_href="/user" icon="person" label={window.user.username} />
|
||||
<div class="separator"></div>
|
||||
|
||||
<div class="stats_table">
|
||||
<div>Subscription</div>
|
||||
<div>{window.user.subscription.name}</div>
|
||||
@@ -54,13 +77,22 @@ const click = e => {
|
||||
<div>{formatDataVolume(window.user.monthly_transfer_used, 3)}</div>
|
||||
</div>
|
||||
<div class="separator"></div>
|
||||
<Button link_href="/d/me" icon="folder" label="My Filesystem"/>
|
||||
|
||||
{#if window.user.subscription.filesystem_access}
|
||||
<Button link_href="/d/me" icon="folder" label="My Filesystem"/>
|
||||
{:else}
|
||||
<Button link_href="/#pro" icon="star" label="Get Premium"/>
|
||||
{/if}
|
||||
|
||||
<Button link_href="/filesystem" icon="description" label="Filesystem Guide"/>
|
||||
|
||||
<div class="separator"></div>
|
||||
|
||||
<Button link_href="/user/filemanager#files" icon="image" label="My Files"/>
|
||||
<Button link_href="/user/filemanager#lists" icon="photo_library" label="My Albums"/>
|
||||
|
||||
<div class="separator"></div>
|
||||
<Button link_href="/user" icon="person" label="Profile"/>
|
||||
|
||||
<Button link_href="/user/settings" icon="settings" label="Account Settings"/>
|
||||
<Button link_href="/user/subscription" icon="shopping_cart" label="Subscription"/>
|
||||
<Button link_href="/user/prepaid/transactions" icon="receipt" label="Transactions"/>
|
||||
@@ -108,10 +140,6 @@ dialog {
|
||||
flex-direction: column;
|
||||
max-width: 15em;
|
||||
}
|
||||
.menu_username {
|
||||
text-align: center;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
.separator {
|
||||
height: 1px;
|
||||
margin: 2px 0;
|
||||
@@ -127,7 +155,7 @@ dialog {
|
||||
|
||||
/* Hide username on small screen */
|
||||
@media(max-width: 800px) {
|
||||
.button_username {
|
||||
.hide_name {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@@ -1,21 +1,23 @@
|
||||
<script>
|
||||
import Menu from "../filesystem/Menu.svelte";
|
||||
import Footer from "../layout/Footer.svelte";
|
||||
import AddressReputation from "./AddressReputation.svelte";
|
||||
import FeatureTable from "./FeatureTable.svelte";
|
||||
import ForCreators from "./ForCreators.svelte";
|
||||
import PolicyChange from "./PolicyChange.svelte";
|
||||
import UploadWidget from "./UploadWidget.svelte";
|
||||
import UploadLoginWall from "./UploadLoginWall.svelte";
|
||||
</script>
|
||||
|
||||
<div class="page_content">
|
||||
<header>
|
||||
<header class="header" style="text-align: initial">
|
||||
<div class="menu_button_container">
|
||||
<Menu no_login_label="Not logged in" hide_name={false} hide_logo/>
|
||||
</div>
|
||||
<div class="header_image_container"></div>
|
||||
<PolicyChange/>
|
||||
</header>
|
||||
|
||||
<AddressReputation/>
|
||||
|
||||
<UploadWidget/>
|
||||
<UploadLoginWall/>
|
||||
</div>
|
||||
|
||||
<div class="page_content">
|
||||
@@ -99,18 +101,19 @@ header > h1 {
|
||||
}
|
||||
|
||||
.header_image_container {
|
||||
text-align: initial;
|
||||
margin: auto;
|
||||
height: 200px;
|
||||
width: 750px;
|
||||
height: 150px;
|
||||
width: 500px;
|
||||
max-width: 100%;
|
||||
background-image: url("/res/img/header_orbitron_wide.webp");
|
||||
background-image: url("/res/img/header_orbitron.webp");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.header_image_container {
|
||||
background-image: url("/res/img/header_orbitron.webp");
|
||||
}
|
||||
.menu_button_container {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
</style>
|
||||
|
60
svelte/src/home_page/UploadLoginWall.svelte
Normal file
60
svelte/src/home_page/UploadLoginWall.svelte
Normal file
@@ -0,0 +1,60 @@
|
||||
<script>
|
||||
import Login from "../login/Login.svelte";
|
||||
import Register from "../login/Register.svelte";
|
||||
import UploadWidget from "./UploadWidget.svelte";
|
||||
|
||||
const finish_login = async e => {
|
||||
location.reload()
|
||||
}
|
||||
|
||||
let page = "login"
|
||||
</script>
|
||||
|
||||
{#if window.user && window.user.username && window.user.username !== ""}
|
||||
<UploadWidget/>
|
||||
{:else}
|
||||
<section>
|
||||
<p>
|
||||
Pixeldrain requires an account to upload files to. If you already
|
||||
have an account use the login form below to log in to your account.
|
||||
If not, use the right tab button to register a new account.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div class="tab_bar">
|
||||
<button on:click={() => page = "login"} class:button_highlight={page === "login"}>
|
||||
<i class="icon small">login</i>
|
||||
<span>Login</span>
|
||||
</button>
|
||||
|
||||
<button on:click={() => page = "register"} class:button_highlight={page === "register"}>
|
||||
<i class="icon small">how_to_reg</i>
|
||||
<span>Register</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{#if page === "login"}
|
||||
<section class="highlight_border">
|
||||
<Login on:login={finish_login}/>
|
||||
<p>
|
||||
If you have lost your password, you can <a
|
||||
href="password_reset">request a new password here</a>.
|
||||
</p>
|
||||
</section>
|
||||
{:else if page === "register"}
|
||||
<section class="highlight_border">
|
||||
<Register on:login={finish_login}/>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<br/>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.tab_bar > button {
|
||||
width: 40%;
|
||||
max-width: 10em;
|
||||
font-size: 1.3em;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
43
svelte/src/login/Login.svelte
Normal file
43
svelte/src/login/Login.svelte
Normal file
@@ -0,0 +1,43 @@
|
||||
<script>
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import Form from "./../util/Form.svelte"
|
||||
|
||||
let dispatch = createEventDispatcher()
|
||||
|
||||
let form = {
|
||||
name: "login",
|
||||
fields: [
|
||||
{
|
||||
name: "username",
|
||||
label: "Username",
|
||||
type: "username",
|
||||
}, {
|
||||
name: "password",
|
||||
label: "Password",
|
||||
type: "current_password",
|
||||
},
|
||||
],
|
||||
submit_label: `<i class="icon">send</i> Login`,
|
||||
on_submit: async fields => {
|
||||
const form = new FormData()
|
||||
form.append("username", fields.username)
|
||||
form.append("password", fields.password)
|
||||
form.append("app_name", "website_login")
|
||||
|
||||
const resp = await fetch(
|
||||
window.api_endpoint+"/user/login",
|
||||
{ method: "POST", body: form }
|
||||
);
|
||||
if(resp.status >= 400) {
|
||||
return {error_json: await resp.json()}
|
||||
}
|
||||
let jresp = await resp.json()
|
||||
|
||||
dispatch("login", {key: jresp.auth_key})
|
||||
|
||||
return {success: true, message: "Successfully logged in"}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<Form config={form}></Form>
|
109
svelte/src/login/Register.svelte
Normal file
109
svelte/src/login/Register.svelte
Normal file
@@ -0,0 +1,109 @@
|
||||
<script>
|
||||
import { createEventDispatcher, onMount } from "svelte";
|
||||
import Form from "../util/Form.svelte"
|
||||
|
||||
let dispatch = createEventDispatcher()
|
||||
|
||||
let form = {
|
||||
name: "register",
|
||||
fields: [
|
||||
{
|
||||
name: "username",
|
||||
label: "Username",
|
||||
type: "username",
|
||||
description: "Used for logging into your account",
|
||||
}, {
|
||||
name: "email",
|
||||
label: "E-mail address",
|
||||
type: "email",
|
||||
description: "Your e-mail address is only used for recovering lost passwords",
|
||||
}, {
|
||||
name: "password",
|
||||
label: "Password",
|
||||
type: "new_password",
|
||||
}, {
|
||||
name: "password2",
|
||||
label: "Password verification",
|
||||
type: "new_password",
|
||||
description: "You need to enter your password twice so we " +
|
||||
"can verify that no typing errors were made, which would " +
|
||||
"prevent you from logging into your new account"
|
||||
},
|
||||
],
|
||||
submit_label: `<i class="icon">send</i> Register`,
|
||||
on_submit: async fields => {
|
||||
if (fields.password !== fields.password2) {
|
||||
return {
|
||||
error_json: {
|
||||
value: "password_verification_failed",
|
||||
message: "Password verification failed. Please enter the same " +
|
||||
"password in both password fields"
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const form = new FormData()
|
||||
form.append("username", fields.username)
|
||||
form.append("email", fields.email)
|
||||
form.append("password", fields.password)
|
||||
if (fields.recaptcha_response) {
|
||||
console.log("resp", fields.recaptcha_response)
|
||||
form.append("recaptcha_response", fields.recaptcha_response)
|
||||
}
|
||||
|
||||
|
||||
const resp = await fetch(
|
||||
window.api_endpoint+"/user/register",
|
||||
{ method: "POST", body: form }
|
||||
);
|
||||
if(resp.status >= 400) {
|
||||
return {error_json: await resp.json()}
|
||||
}
|
||||
|
||||
// Register successful, now we will try logging in with the same
|
||||
// credentials
|
||||
|
||||
const login_form = new FormData()
|
||||
login_form.append("username", fields.username)
|
||||
login_form.append("password", fields.password)
|
||||
login_form.append("app_name", "website_login")
|
||||
|
||||
const login_resp = await fetch(
|
||||
window.api_endpoint+"/user/login",
|
||||
{ method: "POST", body: form }
|
||||
);
|
||||
if(login_resp.status >= 400) {
|
||||
return {error_json: await login_resp.json()}
|
||||
}
|
||||
let jresp = await login_resp.json()
|
||||
|
||||
dispatch("login", {key: jresp.auth_key})
|
||||
|
||||
return {success: true, message: "Successfully registered a new account"}
|
||||
},
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
const resp = await fetch(window.api_endpoint+"/misc/recaptcha");
|
||||
if(resp.status >= 400) {
|
||||
alert("Failed to get captcha key: " + await resp.text())
|
||||
return
|
||||
}
|
||||
let jresp = await resp.json()
|
||||
|
||||
form.fields.push({
|
||||
name: "recaptcha_response",
|
||||
label: "Captcha",
|
||||
type: "captcha",
|
||||
captcha_site_key: jresp.site_key,
|
||||
description: "The reCaptcha test verifies that you " +
|
||||
"are not an evil robot that is trying to flood the " +
|
||||
"website with fake accounts. Please click the white box " +
|
||||
"to prove that you're not a robot"
|
||||
})
|
||||
form.fields = form.fields
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<Form config={form}></Form>
|
@@ -34,6 +34,8 @@ let submit_result = {
|
||||
messages: null,
|
||||
}
|
||||
|
||||
let form_elem
|
||||
|
||||
let submit = async (event) => {
|
||||
loading = true
|
||||
event.preventDefault()
|
||||
@@ -49,6 +51,8 @@ let submit = async (event) => {
|
||||
}
|
||||
} else if (field.type === "description") {
|
||||
field_values[field.name] = ""
|
||||
} else if (field.type === "captcha") {
|
||||
field_values[field.name] = form_elem.getElementsByClassName("g-recaptcha-response")[0].value
|
||||
} else {
|
||||
field_values[field.name] = field.binding.value
|
||||
}
|
||||
@@ -107,7 +111,7 @@ let handle_errors = (response) => {
|
||||
}
|
||||
</script>
|
||||
|
||||
<form method="POST" on:submit={submit}>
|
||||
<form method="POST" on:submit={submit} bind:this={form_elem}>
|
||||
{#if submitted}
|
||||
{#if submit_result.messages}
|
||||
<div id="submit_result" class:highlight_green={submit_result.success} class:highlight_red={!submit_result.success}>
|
||||
|
Reference in New Issue
Block a user