Add page for connecting apps to your account
This commit is contained in:
6
go.mod
6
go.mod
@@ -5,7 +5,7 @@ go 1.17
|
||||
require (
|
||||
fornaxian.tech/config v0.0.0-20211108212237-6133aed90586
|
||||
fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640
|
||||
fornaxian.tech/pixeldrain_api_client v0.0.0-20211209211007-1632279aa965
|
||||
fornaxian.tech/pixeldrain_api_client v0.0.0-20211220185733-94b115cb883d
|
||||
fornaxian.tech/util v0.0.0-20211102152345-9a486dee9787
|
||||
github.com/julienschmidt/httprouter v1.3.0
|
||||
github.com/microcosm-cc/bluemonday v1.0.16
|
||||
@@ -19,7 +19,7 @@ require (
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/gorilla/css v1.0.0 // indirect
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
||||
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b // indirect
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
)
|
||||
|
8
go.sum
8
go.sum
@@ -9,6 +9,10 @@ fornaxian.tech/pixeldrain_api_client v0.0.0-20211128195924-7b5d3f7293df h1:eFpcI
|
||||
fornaxian.tech/pixeldrain_api_client v0.0.0-20211128195924-7b5d3f7293df/go.mod h1:uajB2ofEsefUtxjvs4m7SDyPVRlfrI3qzCSWcud47hY=
|
||||
fornaxian.tech/pixeldrain_api_client v0.0.0-20211209211007-1632279aa965 h1:QAzkcEwXfVopwc6Q8UBZoW7YYgP8jwk18mmbrcl2KfE=
|
||||
fornaxian.tech/pixeldrain_api_client v0.0.0-20211209211007-1632279aa965/go.mod h1:uajB2ofEsefUtxjvs4m7SDyPVRlfrI3qzCSWcud47hY=
|
||||
fornaxian.tech/pixeldrain_api_client v0.0.0-20211220172818-8db5ef7da837 h1:uM2Gu3RnsfXF646AA1SMzO1bj1SxPJr0SIOTXXu5GCE=
|
||||
fornaxian.tech/pixeldrain_api_client v0.0.0-20211220172818-8db5ef7da837/go.mod h1:uajB2ofEsefUtxjvs4m7SDyPVRlfrI3qzCSWcud47hY=
|
||||
fornaxian.tech/pixeldrain_api_client v0.0.0-20211220185733-94b115cb883d h1:BWmYoeL3InMJFD9iIMbq170yyJ07WObJBS3soi5VuVE=
|
||||
fornaxian.tech/pixeldrain_api_client v0.0.0-20211220185733-94b115cb883d/go.mod h1:uajB2ofEsefUtxjvs4m7SDyPVRlfrI3qzCSWcud47hY=
|
||||
fornaxian.tech/util v0.0.0-20211102152345-9a486dee9787 h1:9ujI8Qi6+FTL/YW6xQAS9DmWDMerHBe8foQvVD/G/i0=
|
||||
fornaxian.tech/util v0.0.0-20211102152345-9a486dee9787/go.mod h1:FqVgfghmxTGR3l9Zx4MOMeZ9KHjiEFl3s3C0BSTvBwk=
|
||||
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
|
||||
@@ -49,6 +53,8 @@ golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSE
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b h1:QAqMVf3pSa6eeTsuklijukjXBlj7Es2QQplab+/RbQ4=
|
||||
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
@@ -56,6 +62,8 @@ golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X
|
||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM=
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
BIN
res/static/img/jdownloader.png
Normal file
BIN
res/static/img/jdownloader.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
@@ -38,9 +38,15 @@ const load_keys = async () => {
|
||||
const create_key = async () => {
|
||||
loading = true
|
||||
try {
|
||||
let form = new FormData()
|
||||
form.append("app_name", "Key generated by user")
|
||||
|
||||
const resp = await fetch(
|
||||
window.api_endpoint+"/user/session",
|
||||
{ method: "POST" }
|
||||
{
|
||||
method: "POST",
|
||||
body: form,
|
||||
}
|
||||
);
|
||||
if(resp.status >= 400) {
|
||||
throw new Error(await resp.text());
|
||||
@@ -82,6 +88,7 @@ const logout = async (key) => {
|
||||
<Spinner />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="limit_width">
|
||||
{#if !loaded}
|
||||
<div class="highlight_yellow">
|
||||
@@ -134,7 +141,22 @@ const logout = async (key) => {
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="5">User-Agent: {row.user_agent}</td>
|
||||
<td colspan="1">
|
||||
App:
|
||||
{#if row.app_name === "Pixeldrain Website"}
|
||||
<img src="/res/img/pixeldrain_32.png" alt="Pixeldrain logo" class="app_icon"/>
|
||||
Website
|
||||
{:else if row.app_name === "sharex"}
|
||||
<img src="/res/img/sharex.png" alt="ShareX logo" class="app_icon"/>
|
||||
ShareX
|
||||
{:else if row.app_name === "jdownloader"}
|
||||
<img src="/res/img/jdownloader.png" alt="JDownloader logo" class="app_icon"/>
|
||||
JDownloader
|
||||
{:else}
|
||||
{row.app_name}
|
||||
{/if}
|
||||
</td>
|
||||
<td colspan="4">User-Agent: {row.user_agent}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</table>
|
||||
@@ -157,4 +179,9 @@ const logout = async (key) => {
|
||||
}
|
||||
.toolbar > * { flex: 0 0 auto; }
|
||||
.toolbar_spacer { flex: 1 1 auto; }
|
||||
|
||||
.app_icon {
|
||||
height: 1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
199
svelte/src/user_home/ConnectApp.svelte
Normal file
199
svelte/src/user_home/ConnectApp.svelte
Normal file
@@ -0,0 +1,199 @@
|
||||
<script>
|
||||
import { onMount } from "svelte";
|
||||
import Spinner from "../util/Spinner.svelte";
|
||||
import { copy_text } from "../util/Util.svelte";
|
||||
|
||||
let loading = false
|
||||
let app_name = ""
|
||||
let api_key = ""
|
||||
|
||||
const create_key = async () => {
|
||||
loading = true
|
||||
try {
|
||||
let form = new FormData()
|
||||
form.append("app_name", app_name)
|
||||
|
||||
const resp = await fetch(
|
||||
window.api_endpoint+"/user/session",
|
||||
{
|
||||
method: "POST",
|
||||
body: form,
|
||||
}
|
||||
);
|
||||
if(resp.status >= 400) {
|
||||
throw new Error(await resp.text());
|
||||
}
|
||||
|
||||
api_key = (await resp.json()).auth_key
|
||||
} catch (err) {
|
||||
alert("Failed to create new API key! "+err)
|
||||
} finally {
|
||||
loading = false
|
||||
}
|
||||
}
|
||||
|
||||
let copied = false
|
||||
const copy_key = () => {
|
||||
if (copy_text(api_key)) {
|
||||
copied = true
|
||||
}
|
||||
}
|
||||
|
||||
let show_key = ""
|
||||
const toggle_show_key = () => {
|
||||
if (show_key === "") {
|
||||
show_key = api_key
|
||||
} else {
|
||||
show_key = ""
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
let app = new URL(window.location.href).searchParams.get("app")
|
||||
if (app) {
|
||||
app_name = app
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#if loading}
|
||||
<div class="spinner_container">
|
||||
<Spinner />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="limit_width">
|
||||
{#if app_name === "jdownloader"}
|
||||
<h2>
|
||||
Connect
|
||||
<img src="/res/img/jdownloader.png" alt="JDownloader logo" class="app_icon_small"/>
|
||||
JDownloader to your pixeldrain account
|
||||
</h2>
|
||||
<p>
|
||||
To connect JDownloader to pixeldrain you need to generate an API
|
||||
key and enter it in JDownloader's Account Manager.
|
||||
<br/>
|
||||
<strong>Do not show the generated key to anyone</strong>, it can
|
||||
be used to gain access to your pixeldrain account!
|
||||
</p>
|
||||
|
||||
{#if !api_key}
|
||||
<div class="center">
|
||||
<button class="button_highlight" on:click={create_key}>
|
||||
<i class="icon">add</i>
|
||||
Generate key
|
||||
</button>
|
||||
</div>
|
||||
{:else}
|
||||
<h3>Key created</h3>
|
||||
|
||||
<div class="copy_container indent">
|
||||
<button on:click={copy_key} class="copy_button" class:button_highlight={copied}>
|
||||
<i class="icon">content_copy</i>
|
||||
{#if copied}
|
||||
Copied!
|
||||
{:else}
|
||||
Copy key to clipboard
|
||||
{/if}
|
||||
</button>
|
||||
<button on:click={toggle_show_key} class="copy_button" class:button_highlight={show_key !== ""}>
|
||||
<i class="icon">visibility</i>
|
||||
{#if show_key === ""}
|
||||
Show key
|
||||
{/if}
|
||||
</button>
|
||||
<input bind:value={show_key} class="copy_textarea" type="text" placeholder="Your key will show up here" disabled={show_key === ""}/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<p>
|
||||
Paste the key in JDownloader to authenticate the app.
|
||||
</p>
|
||||
{:else if app_name === "sharex"}
|
||||
<h2>
|
||||
Connect
|
||||
<img src="/res/img/sharex.png" alt="ShareX logo" class="app_icon_small"/>
|
||||
ShareX to your pixeldrain account
|
||||
</h2>
|
||||
<p>
|
||||
ShareX is a Screen capture, file sharing and productivity tool.
|
||||
Pixeldrain is supported as a custom uploader. You can <a
|
||||
href="https://getsharex.com/" target="_blank">get ShareX
|
||||
here</a>.
|
||||
</p>
|
||||
<p>
|
||||
Here you can download our custom ShareX uploader which uses
|
||||
pixeldrain to upload your files. This uploader is configured to
|
||||
upload files to your personal pixeldrain account. <strong>Do not
|
||||
share the configuration file with anyone</strong>, it contains
|
||||
your account credentials.
|
||||
</p>
|
||||
|
||||
<div class="center">
|
||||
<a href="/misc/sharex/pixeldrain.com.sxcu" class="button button_highlight">
|
||||
<i class="icon small">save</i>
|
||||
Download ShareX Uploader
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h3>Setting pixeldrain as default uploader</h3>
|
||||
<p>
|
||||
Download the uploader config and choose 'Open file'
|
||||
<br/>
|
||||
<img src="/res/img/sharex_download.png" style="max-width: 100%;" alt=""/><br/>
|
||||
Set pixeldrain.com as active uploader. Choose Yes
|
||||
<br/>
|
||||
<img src="/res/img/sharex_default.png" style="max-width: 100%;" alt=""/><br/>
|
||||
</p>
|
||||
{:else}
|
||||
<h2>Connect an app to your pixeldrain account</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<button on:click={() => {app_name = "jdownloader"}}>
|
||||
<img src="/res/img/jdownloader.png" alt="JDownloader logo" class="app_icon"/>
|
||||
Connect JDownloader
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button on:click={() => {app_name = "sharex"}}>
|
||||
<img src="/res/img/sharex.png" alt="ShareX logo" class="app_icon"/>
|
||||
Connect ShareX
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.spinner_container {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.app_icon {
|
||||
height: 1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.app_icon_small {
|
||||
height: 1em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.copy_container {
|
||||
display: flex;
|
||||
}
|
||||
.copy_textarea {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.copy_button {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
</style>
|
@@ -5,6 +5,7 @@ import AccountSettings from "./AccountSettings.svelte";
|
||||
import APIKeys from "./APIKeys.svelte";
|
||||
import Transactions from "./Transactions.svelte";
|
||||
import Subscription from "./Subscription.svelte";
|
||||
import ConnectApp from "./ConnectApp.svelte";
|
||||
|
||||
let page = ""
|
||||
|
||||
@@ -74,14 +75,16 @@ onMount(() => {
|
||||
</div>
|
||||
|
||||
{#if page === "home"}
|
||||
<Home></Home>
|
||||
<Home/>
|
||||
{:else if page === "settings"}
|
||||
<AccountSettings></AccountSettings>
|
||||
<AccountSettings/>
|
||||
{:else if page === "api_keys"}
|
||||
<APIKeys></APIKeys>
|
||||
<APIKeys/>
|
||||
{:else if page === "connect_app"}
|
||||
<ConnectApp/>
|
||||
{:else if page === "transactions"}
|
||||
<Transactions></Transactions>
|
||||
<Transactions/>
|
||||
{:else if page === "subscription"}
|
||||
<Subscription></Subscription>
|
||||
<Subscription/>
|
||||
{/if}
|
||||
</div>
|
||||
|
@@ -17,7 +17,7 @@ func (wc *WebController) serveShareXConfig(w http.ResponseWriter, r *http.Reques
|
||||
|
||||
w.Header().Add("Content-Disposition", "attachment; filename=pixeldrain.com.sxcu")
|
||||
if templateData.Authenticated {
|
||||
sess, err := templateData.PixelAPI.PostUserSession()
|
||||
sess, err := templateData.PixelAPI.PostUserSession("sharex")
|
||||
if err != nil {
|
||||
log.Error("Failed to create user session: %s", err)
|
||||
wc.templates.Get().ExecuteTemplate(w, "500", templateData)
|
||||
|
@@ -197,6 +197,7 @@ func (wc *WebController) loginForm(td *TemplateData, r *http.Request) (f Form) {
|
||||
if session, err := td.PixelAPI.PostUserLogin(
|
||||
f.FieldVal("username"),
|
||||
f.FieldVal("password"),
|
||||
"Pixeldrain Website",
|
||||
); err != nil {
|
||||
log.Debug("Login failed: %s", err)
|
||||
formAPIError(err, &f)
|
||||
|
@@ -181,6 +181,7 @@ func New(
|
||||
{GET, "user/home" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
|
||||
{GET, "user/settings" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
|
||||
{GET, "user/api_keys" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
|
||||
{GET, "user/connect_app" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
|
||||
{GET, "user/transactions" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
|
||||
{GET, "user/subscription" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
|
||||
{GET, "user/confirm_email" /* */, wc.serveEmailConfirm},
|
||||
|
Reference in New Issue
Block a user