mirror of
https://github.com/JonasunderscoreJones/dash.jonasjones.dev.git
synced 2025-10-24 14:19:20 +02:00
Compare commits
14 commits
a4e42be994
...
53eeebaf0a
| Author | SHA1 | Date | |
|---|---|---|---|
| 53eeebaf0a | |||
| 9877879ba6 | |||
| 236777e7f3 | |||
| f75c99a571 | |||
| 6dcce58635 | |||
| d1d25ee292 | |||
| 31ad9c36d6 | |||
| 218d53fb92 | |||
| 01da5efe2f | |||
| f0eedba287 | |||
| e5c9c351e7 | |||
| 10cc36000c | |||
| e032477540 | |||
| 9a2d157d37 |
12 changed files with 147 additions and 105 deletions
53
README.md
53
README.md
|
|
@ -1,38 +1,21 @@
|
|||
# sv
|
||||
# Jonas_Jones Dashboard
|
||||
This Dashboard connects the settings and configurations of most of the services of my ecosystem
|
||||
|
||||
Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
|
||||
## Accounts
|
||||
It is possible for everyone to signup and get access to the settings, however most user scopes aren't available to the default user and need to be granted by an admin user.
|
||||
|
||||
## Creating a project
|
||||
## Settings and Configurations
|
||||
The following are services that can be configured from the dashboard:
|
||||
|
||||
If you're seeing this, you've probably already done this step. Congrats!
|
||||
|
||||
```bash
|
||||
# create a new project in the current directory
|
||||
npx sv create
|
||||
|
||||
# create a new project in my-app
|
||||
npx sv create my-app
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
|
||||
# or start the server and open the app in a new browser tab
|
||||
npm run dev -- --open
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
To create a production version of your app:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
You can preview the production build with `npm run preview`.
|
||||
|
||||
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
|
||||
| Service Name | Description | Implemented |
|
||||
| ------------ | ----------- | ----------- |
|
||||
| accouts.jonasjones.dev | Account Management (scopes, deletion, creation, etc...) | No |
|
||||
| jonasjones.dev (Projects) | Project Management (update, add, delete) | No |
|
||||
| Analytics (stats.jonasjones.dev) | Management (delete, graphs) | No |
|
||||
| Rick-Roll-Tracker | Management (graphs) | No |
|
||||
| kcomebacks.jonasjones.dev | run scraper, graphs, etc... | No |
|
||||
| builds.jonasjones.dev | Add, remove, update | No |
|
||||
| blogs.jonasjones.dev | create, edit, delete Posts | No |
|
||||
| rss.jonasjones.dev | add, edit, delete entries | No |
|
||||
| API scripts | run, (probably not much more because security issues like remote code execution etc.) | No |
|
||||
| aka.jonasjones.dev | add, remove, edit aka entries | No |
|
||||
|
|
|
|||
32
src/lib/components/AlphaNotice.svelte
Normal file
32
src/lib/components/AlphaNotice.svelte
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<div class="alpha-notice">
|
||||
<h2><b>This is an Alpha Version</b></h2>
|
||||
<p>
|
||||
Note that this Dashboard is in an alpha state. This means that there are bugs and missing features.
|
||||
Please report any bugs or issues to the
|
||||
<a href="https://github.com/JonasunderscoreJones/dash.jonasjones.dev/issues">GitHub repository</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.alpha-notice {
|
||||
background-color: #c48900;
|
||||
color: #721c24;
|
||||
padding: 1rem;
|
||||
border: 1px solid #533300;
|
||||
border-radius: 0.25rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.alpha-notice h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.alpha-notice a {
|
||||
color: #721c24;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.alpha-notice a:hover {
|
||||
color: #560009;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
export const ACCOUNTS_WORKER_URL = 'https://accounts.jonasjones.dev';
|
||||
|
||||
export function getSessionKey() {
|
||||
const match = document.cookie.match(/(^| )sessionKey=([^;]+)/);
|
||||
return match ? match[2] : null;
|
||||
|
|
@ -12,6 +14,20 @@ export function redirectToLogin() {
|
|||
window.location.href = `/login?returnUrl=${currentPath}`;
|
||||
}
|
||||
|
||||
export function resetSession() {
|
||||
document.cookie = `sessionKey=; path=/; max-age=0`;
|
||||
window.location.href = '/login';
|
||||
}
|
||||
|
||||
export function redirectToHome() {
|
||||
if (getSessionKey()) {
|
||||
window.location.href = new URLSearchParams(window.location.search).get('returnUrl') || '/';
|
||||
console.log(new URLSearchParams(window.location.search).get('returnUrl') || '/')
|
||||
} else {
|
||||
console.log(getSessionKey())
|
||||
}
|
||||
}
|
||||
|
||||
export function ensureAuthenticated() {
|
||||
if (!getSessionKey()) {
|
||||
redirectToLogin();
|
||||
|
|
@ -6,6 +6,11 @@
|
|||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
<head>
|
||||
<!-- Include Font Awesome CDN -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<div class="app">
|
||||
<Header />
|
||||
|
||||
|
|
@ -22,33 +27,4 @@
|
|||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1rem;
|
||||
width: 100%;
|
||||
max-width: 64rem;
|
||||
margin: 0 auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
footer a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media (min-width: 480px) {
|
||||
footer {
|
||||
padding: 12px 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { ensureAuthenticated } from '../utils/session.js';
|
||||
|
||||
import { ensureAuthenticated } from '$lib/session.js';
|
||||
onMount(() => {
|
||||
ensureAuthenticated(); // This will check the session key and redirect if necessary
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
<head>
|
||||
<!-- Include Font Awesome CDN -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<div class="footer">
|
||||
<div class="footer-left">
|
||||
<a href="https://github.com/JonasunderscoreJones" target="_blank"><i class="fab fa-github" /></a>
|
||||
<a href="https://www.youtube.com/channel/UCVIxvKBIMSMgurYS8pK7fSg" target="_blank"><i class="fab fa-youtube" /></a>
|
||||
<a href="https://discord.gg/V2EsuUVmWh" target="_blank"><i class="fab fa-discord" /></a>
|
||||
<a href="mailto:me@jonasjones.dev" target="_blank"><i class="fas fa-envelope" /></a>
|
||||
<a href="https://github.com/JonasunderscoreJones" target="_blank" aria-label="GitHub Link"><i class="fab fa-github"></i></a>
|
||||
<a href="https://www.youtube.com/channel/UCVIxvKBIMSMgurYS8pK7fSg" target="_blank" aria-label="YouTube Link"><i class="fab fa-youtube"></i></a>
|
||||
<a href="https://discord.gg/V2EsuUVmWh" target="_blank" aria-label="Discord Link"><i class="fab fa-discord"></i></a>
|
||||
<a href="mailto:me@jonasjones.dev" target="_blank" aria-label="Email Link"><i class="fas fa-envelope"></i></a>
|
||||
</div>
|
||||
|
||||
<p>Website by Jonas_Jones 2021 - <script>document.write(new Date().getFullYear());</script></p>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
<script>
|
||||
import { page } from '$app/state';
|
||||
import logo from '$lib/images/logo.png';
|
||||
import { getSessionKey } from '$lib/session.js';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let sessionKey;
|
||||
onMount(() => {
|
||||
sessionKey = getSessionKey();
|
||||
});
|
||||
</script>
|
||||
|
||||
<header>
|
||||
|
|
@ -15,13 +22,16 @@
|
|||
<path d="M0,0 L1,2 C1.5,3 1.5,3 2,3 L2,0 Z" />
|
||||
</svg>
|
||||
<ul>
|
||||
{#if ['/login', '/signup', '/register'].includes(page.url.pathname)}
|
||||
{#if sessionKey === null}
|
||||
<li aria-current={page.url.pathname === '/login' ? 'page' : undefined}>
|
||||
<a href="/login{page.url.search}">Login</a>
|
||||
</li>
|
||||
<li aria-current={page.url.pathname === '/signup' ? 'page' : undefined}>
|
||||
<a href="/signup{page.url.search}">Signup</a>
|
||||
</li>
|
||||
<li aria-current={page.url.pathname === '/about' ? 'page' : undefined}>
|
||||
<a href="/about">About</a>
|
||||
</li>
|
||||
{:else}
|
||||
<li aria-current={page.url.pathname === '/' ? 'page' : undefined}>
|
||||
<a href="/">Home</a>
|
||||
|
|
@ -29,6 +39,9 @@
|
|||
<li aria-current={page.url.pathname === '/about' ? 'page' : undefined}>
|
||||
<a href="/about">About</a>
|
||||
</li>
|
||||
<li aria-current={page.url.pathname === '/logout' ? 'page' : undefined}>
|
||||
<a href="/logout">Logout</a>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
<svg viewBox="0 0 2 3" aria-hidden="true">
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
import { dev } from '$app/environment';
|
||||
|
||||
// we don't need any JS on this page, though we'll load
|
||||
// it in dev so that we get hot module replacement
|
||||
export const csr = dev;
|
||||
|
||||
// since there's no dynamic data here, we can prerender
|
||||
// it so that it gets served as a static asset in production
|
||||
export const prerender = true;
|
||||
|
|
@ -1,21 +1,37 @@
|
|||
<script>
|
||||
import AlphaNotice from "$lib/components/AlphaNotice.svelte";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>About</title>
|
||||
<meta name="description" content="About this app" />
|
||||
</svelte:head>
|
||||
|
||||
<div class="text-column">
|
||||
<h1>About this app</h1>
|
||||
<h1>About this Dashboard</h1>
|
||||
|
||||
<AlphaNotice />
|
||||
|
||||
<p>
|
||||
This is a <a href="https://svelte.dev/docs/kit">SvelteKit</a> app. You can make your own by typing
|
||||
the following into your command line and following the prompts:
|
||||
This is a Dashboard app for my Ecosystem's services.
|
||||
The list and roadmap of supported services can be viewed in the
|
||||
<a href="https://github.com/JonasunderscoreJones/dash.jonasjones.dev/blob/main/README.md">README.md</a>
|
||||
page of the github repository. Thus, the Dashboard is opensource in the same repository.
|
||||
</p>
|
||||
|
||||
<pre>npx sv create</pre>
|
||||
<p>
|
||||
Signups are allowed to anyone. This is because the default user scope currently has no permissions.
|
||||
However, the Dashboard is designed to be used with a user scope system. This means that the user scope
|
||||
will be able to access services that are only available to them. Scopes are granted by an admin account.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The page you're looking at is purely static HTML, with no client-side interactivity needed.
|
||||
Because of that, we don't need to load any JavaScript. Try viewing the page's source, or opening
|
||||
the devtools network panel and reloading.
|
||||
Further are the accounts not limited to the Dashboard. They are their own entity, hosted on cloudflare workers.
|
||||
Thus, the accounts are available to be used in other projects as well. The accounts are also opensource in the
|
||||
<a href="https://github.com/JonasunderscoreJones/accounts.jonasjones.dev/">github repository</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Tldr; Dashboard is opensource and signup is public but has no permissions, unless explicitly granted by an admin.
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,21 @@
|
|||
<script>
|
||||
import { navigate } from 'svelte-routing';
|
||||
import { setSessionKey } from '../../utils/session.js';
|
||||
import { onMount } from 'svelte';
|
||||
import { setSessionKey, redirectToHome, ACCOUNTS_WORKER_URL } from '$lib/session.js';
|
||||
import { page } from '$app/state';
|
||||
import AlphaNotice from '$lib/components/AlphaNotice.svelte';
|
||||
let email = '';
|
||||
let password = '';
|
||||
let errorMessage = '';
|
||||
let showPassword = false;
|
||||
|
||||
onMount(() => {
|
||||
redirectToHome(); // This will check the session key and redirect if necessary
|
||||
});
|
||||
|
||||
const handleLogin = async () => {
|
||||
try {
|
||||
const response = await fetch('https://accounts.jonasjones.dev/login', {
|
||||
const response = await fetch(ACCOUNTS_WORKER_URL + '/login', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ email, password }),
|
||||
headers: {
|
||||
|
|
@ -38,6 +44,8 @@
|
|||
<div class="login-prompt">
|
||||
<h1>Login</h1>
|
||||
|
||||
<AlphaNotice />
|
||||
|
||||
{#if errorMessage}
|
||||
<p style="color: red;">{errorMessage}</p>
|
||||
{/if}
|
||||
|
|
@ -73,12 +81,11 @@
|
|||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
left: 0;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
height: 80vh;
|
||||
width: 100vw;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.login-prompt {
|
||||
|
|
|
|||
12
src/routes/logout/+page.svelte
Normal file
12
src/routes/logout/+page.svelte
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<script>
|
||||
import { goto } from '$app/navigation';
|
||||
import { resetSession } from '$lib/session.js';
|
||||
|
||||
resetSession();
|
||||
goto('/login');
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<h1>Logging out...</h1>
|
||||
<p>Redirecting to the login page...</p>
|
||||
</div>
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
<script>
|
||||
import { navigate } from 'svelte-routing';
|
||||
import { setSessionKey } from '../../utils/session.js';
|
||||
import { setSessionKey, ACCOUNTS_WORKER_URL } from '$lib/session.js';
|
||||
import { page } from '$app/state';
|
||||
import AlphaNotice from '$lib/components/AlphaNotice.svelte';
|
||||
let username = '';
|
||||
let firstname = '';
|
||||
let lastname = '';
|
||||
|
|
@ -12,7 +13,7 @@
|
|||
|
||||
const handleLogin = async () => {
|
||||
try {
|
||||
const response = await fetch('https://accounts.jonasjones.dev/register', {
|
||||
const response = await fetch(ACCOUNTS_WORKER_URL + '/register', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ email, password, username, firstname, lastname }),
|
||||
headers: {
|
||||
|
|
@ -41,6 +42,8 @@
|
|||
<div class="login-prompt">
|
||||
<h1>Signup</h1>
|
||||
|
||||
<AlphaNotice />
|
||||
|
||||
{#if errorMessage}
|
||||
<p style="color: red;">{errorMessage}</p>
|
||||
{/if}
|
||||
|
|
@ -83,12 +86,11 @@
|
|||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
left: 0;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
height: 80vh;
|
||||
width: 100vw;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.login-prompt {
|
||||
|
|
@ -141,7 +143,7 @@
|
|||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #0056b3;
|
||||
background-color: var(--color-theme-2);
|
||||
}
|
||||
|
||||
p {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue