Compare commits

...

14 commits

12 changed files with 147 additions and 105 deletions

View file

@ -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 |

View 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>

View file

@ -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();

View file

@ -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>

View file

@ -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
});

View file

@ -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>

View file

@ -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">

View file

@ -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;

View file

@ -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>

View file

@ -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 {

View 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>

View file

@ -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 {