diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index d43d599..0000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "recommendations": [ - "wscats.eno", - "formulahendry.auto-rename-tag", - "yandeu.five-server", - "bungcip.better-toml" - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index a1c4910..28a51d5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "compile-hero.disable-compile-files-on-did-save-code": true + "compile-hero.disable-compile-files-on-did-save-code": false } \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d10e164 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Website +### [My website's](https://ari-web.netlify.app) source code. + +# Customising when self-hosting +See the `/content/styles/config` and `/content/js/config` directories. diff --git a/content/js/config/index.js b/content/js/config/index.js new file mode 100644 index 0000000..bcef4d7 --- /dev/null +++ b/content/js/config/index.js @@ -0,0 +1,47 @@ +const boot = document.getElementById('boot'); +const site_name = 'ari-web'; +const boot_message = { + 0: { + "type": 'ok', + "text": `Booting '${site_name}'...`, + "sleep_time": 0 + } +} +const do_sleep = false; +const locations = { + 0: { + "url": "https://github.com/TruncatedDinosour/website", + "desc": "The source code of this website", + "aliases": [ + "src","source", + "git", "github" + ] + }, + + 1: { + "url": "/", + "desc": "The home page", + "aliases": [ + "home","root", + "index" + ] + }, + + 2: { + "url": "/page/reset", + "desc": "Reset your account", + "aliases": [ + "reset","erase", + "del", "delete" + ] + }, + + 3: { + "url": "/page/minimal.txt", + "desc": "The minimal page", + "aliases": [ + "mini","minimal", + "txt" + ] + } +} diff --git a/content/js/generic/index.js b/content/js/generic/index.js new file mode 100644 index 0000000..3c54e61 --- /dev/null +++ b/content/js/generic/index.js @@ -0,0 +1,61 @@ +var root = false; + +add_boot_entry(boot_message) + +async function main() { + let is_logged_in = ( + localStorage.getItem('username') && + localStorage.getItem('password') + ) + + let tmp_boot_entries = { + 0: { + "type": 'error', + "text": 'No user account found' + }, + 1: { + "type": 'warning', + "text": 'Creating account', + "sleep_time": 500 + }, + 3: { + "type": 'ok', + "text": `Found user account: ${localStorage.getItem('username')}` + }, + 4: { + "type": 'ok', + "text": 'Loading HTML' + }, + 5: { + "type": 'ok', + "text": 'Loading a basic shell' + }, + 6: { + "type": 'ok', + "text": `'${site_name}' has been booted! enjoy` + } + } + + if (!is_logged_in) { + await add_boot_entry({0: tmp_boot_entries[0], 1: tmp_boot_entries[1]}); + await sleep(500); + user_account_create(); + + return 1; + } else { + await add_boot_entry({ + 0: tmp_boot_entries[3] + }); + await add_boot_entry({ + 0: tmp_boot_entries[4], + 1: tmp_boot_entries[5], + 2: tmp_boot_entries[6] + }); + + document.getElementById("shell").style.display = 'block'; + document.getElementById('prompt').focus(); + } +} + + +main(); diff --git a/content/js/handlers/user_account.js b/content/js/handlers/user_account.js new file mode 100644 index 0000000..c68dc8f --- /dev/null +++ b/content/js/handlers/user_account.js @@ -0,0 +1,45 @@ +async function user_account_create() { + let username = prompt(`Enter your username`); + let password = prompt(`Enter the password for '${username}'`); + let password_confirm = prompt(`Confirm the password for '${username}'`); + + let tmp_boot_entries = { + 0: { + "type": 'error', + "text": "User account not created: canceled by user", + "sleep_time": 0 + } + } + + let valid = ( + username && + password && + password_confirm && + password.length > 6 && + password == password_confirm + ) + + if (!valid) { + if (confirm('The credentials you entered are not valid, try again?')) { + user_account_create(); + return 1; + } + + add_boot_entry({0: tmp_boot_entries[0]}); + await sleep(2500); + window.location.reload(); + } else { + alert('The next popup will show your credentials, press OK to proceed') + let confirm_credentials = confirm(`Are these credentials correct?: + USER: ${username} + PASS: ${password}`); + + if (confirm_credentials) { + localStorage.setItem('username', username) + localStorage.setItem('password', hash(password)) + + alert('Credentials saved!') + window.location.reload(); + } + } +} diff --git a/content/js/helpers/index.js b/content/js/helpers/index.js new file mode 100644 index 0000000..c472e7f --- /dev/null +++ b/content/js/helpers/index.js @@ -0,0 +1,54 @@ +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + + +async function add_boot_entry(entry_object) { + for (const entry in entry_object) { + + if (do_sleep) { + let sleep_time; + if (typeof entry_object[entry]['sleep_time'] !== 'undefined') { + sleep_time = entry_object[entry]['sleep_time']; + } else { + sleep_time = Math.floor((Math.random() * 2000) + 500); + } + await sleep(sleep_time); + } + + + let new_entry = document.createElement('p'); + new_entry.innerHTML = entry_object[entry]['text']; + new_entry.classList.add("bmsg") + + let entry_class; + switch (entry_object[entry]['type']) { + case 'error': + entry_class = 'error'; + break; + + case 'warning': + entry_class = 'warn' + break; + + case 'ok': + entry_class = 'ok' + break; + + default: + throw `Type '${entry_object[entry]['type']}' not found.`; + } + + new_entry.setAttribute("bmsg_type", entry_class); + boot.appendChild(new_entry); + } +} + + +function hash(string){ + return string.split("").reduce( + function (a, b) { + a = ((a << 5) - a) + b.charCodeAt(0); + return a & a + }, 0); +} diff --git a/content/js/shell/commands.js b/content/js/shell/commands.js new file mode 100644 index 0000000..9517746 --- /dev/null +++ b/content/js/shell/commands.js @@ -0,0 +1,102 @@ +var commands = { + "clear": { + "func": clear, + "root_only": false, + "help": { + "desc": "A command to clear the screen", + "short_desc": "Clear the screen", + "examples": [ + "clear" + ] + } + }, + + "reboot": { + "func": reboot, + "root_only": true, + "help": { + "desc": "A command to reboot", + "short_desc": "Reboot", + "examples": [ + "reboot" + ] + } + }, + + "help": { + "func": help, + "root_only": false, + "help": { + "desc": "A command to print help", + "short_desc": "Print help", + "examples": [ + "help", + "help help" + ] + } + }, + + "show": { + "func": show, + "root_only": false, + "help": { + "desc": "A command to show pages", + "short_desc": "Show page", + "examples": [ + "show", + "show src" + ] + } + }, + + "goto": { + "func": goto, + "root_only": false, + "help": { + "desc": "A command to go to pages", + "short_desc": "Goto a page", + "examples": [ + "goto", + "goto src" + ] + } + }, + + "ls": { + "func": list, + "root_only": false, + "help": { + "desc": "A command to list available pages", + "short_desc": "List pages", + "examples": [ + "ls", + "ls src" + ] + } + }, + + "su": { + "func": su, + "root_only": false, + "help": { + "desc": "A command to run commands as root, use 'su .' to switch between the users.", + "short_desc": "Run as root", + "examples": [ + "su .", + "su reboot" + ] + } + }, + + "passwd": { + "func": passwd, + "root_only": true, + "help": { + "desc": "A command to change your password", + "short_desc": "Change password", + "examples": [ + "passwd" + ] + } + }, +} diff --git a/content/js/shell/func.js b/content/js/shell/func.js new file mode 100644 index 0000000..da9b899 --- /dev/null +++ b/content/js/shell/func.js @@ -0,0 +1,145 @@ +function clear() { + document.getElementById('command_output').innerHTML = ''; + document.getElementById('cmd_hist').innerHTML = ''; + document.getElementById('content').innerHTML = ''; + + return ''; +} + +function reboot() { + window.location.reload(); + return 'Rebooting...'; +} + +function help(cmd) { + let help_page = ''; + let help_cmd = cmd[0]; + + if (help_cmd && !commands[help_cmd]) { + return `Help page for '${help_cmd}' does not exist` + } + + if (help_cmd) { + let cmd_help = commands[help_cmd]['help'] + + help_page += `NAME: ${help_cmd}
`; + help_page += `SUID: ${commands[help_cmd]['root_only']}
`; + help_page += `DESCRIPTION: ${cmd_help['desc']}
`; + help_page += `EXAMPLES:
`; + + for (const example in cmd_help['examples']) { + help_page += `$ ${cmd_help['examples'][example]}
` + } + } else { + for (const h in commands) { + let cmd_help = commands[h]['help'] + + help_page += `NAME: ${h}
` + help_page += `SUID: ${commands[h]['root_only']}
`; + help_page += `DESCRIPTION: ${cmd_help['short_desc']}
` + help_page += `EXAMPLE: ${cmd_help['examples'][0]}
` + help_page += `
` + } + } + + return help_page; +} + +function show(dest) { + let dst = dest[0]; + let iframe = document.createElement('iframe'); + iframe.setAttribute('class', 'iframe'); + + if (!dst) { + return help(['show']); + } else { + for (const l in locations) { + if (locations[l]['aliases'].includes(dst)) { + iframe.setAttribute('src', locations[l]['url']); + break; + } + } + } + + if (iframe.src) { + return iframe.outerHTML; + } else { + return `Page '${dst}' not found`; + } +} + +function goto(dest) { + let dst = dest[0]; + + if (!dst) { + window.location = '/'; + return 'Returning to the home page' + } else { + for (const l in locations) { + if (locations[l]['aliases'].includes(dst)) { + window.location = locations[l]['url']; + return `Going to ${locations[l]['url']}` + } + } + } + + return `Page ${dst} does not exist` +} + +function list() { + let locs = ''; + + for (const l in locations) { + let loc = locations[l]; + locs += `URL: ${loc['url']}
` + locs += `DESCRIPTION: ${loc['desc']}
` + locs += `ALISES: ${loc['aliases'].join(", ")}
` + locs += `
` + } + + return locs; +} + +function su(cmd) { + let password_hash; + if (!root) { + password_hash = hash(prompt('Enter your password')); + } + + if (!password_hash) { + return 'Not authenticated. (empty password)' + } + + if (password_hash != localStorage.getItem('password') && !root) { + return 'Wrong password.'; + } + + if (cmd[0]) { + if (cmd[0] == '.') { + root = !root + return `Switched to the ${root ? 'root' : localStorage.getItem('username')} user.` + } else { + return commands[cmd[0]]['func'](cmd.slice(1)); + } + } else { + return help(['su']); + } +} + + +function passwd() { + let current_password = hash(prompt("Current password")); + let password1 = prompt("New password"); + let password2 = prompt("Confirm new password"); + + if (current_password == localStorage.getItem('password')) { + if (password1 === password2) { + localStorage.setItem("password", bash(password1)) + alert(`password set to '${password1}'`); + } else { + return "Passwords don't match" + } + } else { + return 'Wrong password' + } +} diff --git a/content/js/shell/index.js b/content/js/shell/index.js new file mode 100644 index 0000000..fa9f6c8 --- /dev/null +++ b/content/js/shell/index.js @@ -0,0 +1,63 @@ +let cmd_prompt = document.getElementById('prompt'); +let cmd_output = document.getElementById('command_output'); +let cmd_history = document.getElementById('cmd_hist'); +let shell = document.getElementById('shell'); +var is_root = false; + +function main() { + cmd_prompt.onkeypress = (e) => { + if (!cmd_prompt.value) return; + + let code = (e.keyCode ? e.keyCode : e.which); + if (code == 13) { + let command_list = cmd_prompt.value.split(' '); + let command = command_list[0]; + let argv = command_list.slice(1); + + + if (commands[command]) { + if (commands[command]['root_only'] && !root) { + cmd_output.innerHTML = `'${command}' can only be ran as root. see help su` + } else { + cmd_output.innerHTML = commands[command]['func'](argv); + } + } else { + cmd_output.innerHTML = `${command}: command not found` + } + + + if (cmd_output.innerHTML.toString().replace(/\s/g, '')) { + let shell_old = document.createElement('div'); + shell_old.setAttribute('class', 'shell'); + shell_old.setAttribute('prompt', shell.getAttribute('prompt')); + + let cmd = document.createElement('input'); + cmd.setAttribute('class', 'prompt'); + cmd.setAttribute('value', cmd_prompt.value); + cmd.setAttribute('readonly', ''); + + let output = document.createElement('div'); + output.setAttribute('class', 'output') + output.innerHTML = cmd_output.innerHTML; + + shell_old.appendChild(cmd); + shell_old.appendChild(output); + + cmd_history.appendChild(shell_old); + } + + cmd_prompt.value = ''; + cmd_output.innerHTML = ''; + + window.scrollTo(0, document.body.scrollHeight); + + if (root) { + shell.setAttribute('prompt', 'root') + } else { + shell.setAttribute('prompt', '') + } + } + }; +} + +main() diff --git a/content/styles/boot/main.css b/content/styles/boot/main.css new file mode 100644 index 0000000..57e5a33 --- /dev/null +++ b/content/styles/boot/main.css @@ -0,0 +1,44 @@ +.boot { + margin: 1em 0em 1em 1em; + font-size: 1.5em; +} +.boot #bootver { + color: #9acd32; + margin-left: 1.12em; + /* makes it that it aligns with 'boot' messages */ +} +.boot #bootver::before { + content: "WEBrc version " "1.0"; +} +.boot .bmsg[bmsg_type=ok]::after { + content: "[OK]"; + float: right; + color: #0fd30f; +} +.boot .bmsg[bmsg_type=ok]::before { + content: " * "; + color: #0fd30f; +} +.boot .bmsg[bmsg_type=warn]::after { + content: "[WARNING]"; + float: right; + color: #ffff00; +} +.boot .bmsg[bmsg_type=warn]::before { + content: " * "; + color: #ffff00; +} +.boot .bmsg[bmsg_type=error]::after { + content: "[ERROR]"; + float: right; + color: #ff0000; +} +.boot .bmsg[bmsg_type=error]::before { + content: " * "; + color: #ff0000; +} +.boot .bmsg { + text-transform: capitalize; + word-wrap: break-word; + word-break: break-all; +} \ No newline at end of file diff --git a/content/styles/boot/main.scss b/content/styles/boot/main.scss new file mode 100644 index 0000000..9407f43 --- /dev/null +++ b/content/styles/boot/main.scss @@ -0,0 +1,61 @@ +@import '../config/main'; + +.boot { + margin: 1em 0em 1em 1em; + font-size: 1.5em; + + #bootver { + color: $boot_header_colour; + margin-left: 1.12em; /* makes it that it aligns with 'boot' messages */ + } + + #bootver::before { + content: 'WEBrc version ' $boot_ver; + } + + .bmsg[bmsg_type=ok] { + &::after { + content: '[OK]'; + float: right; + color: $ok_colour; + } + + &::before { + content: ' * '; + color: $ok_colour; + } + } + + + .bmsg[bmsg_type=warn] { + &::after { + content: '[WARNING]'; + float: right; + color: $warn_colour; + } + + &::before { + content: ' * '; + color: $warn_colour; + } + } + + .bmsg[bmsg_type=error] { + &::after { + content: '[ERROR]'; + float: right; + color: $error_colour; + } + + &::before { + content: ' * '; + color: $error_colour; + } + } + + .bmsg { + text-transform: capitalize; + word-wrap: break-word; + word-break: break-all; + } +} diff --git a/content/styles/config/_main.css b/content/styles/config/_main.css new file mode 100644 index 0000000..e69de29 diff --git a/content/styles/config/_main.scss b/content/styles/config/_main.scss new file mode 100644 index 0000000..3ae0396 --- /dev/null +++ b/content/styles/config/_main.scss @@ -0,0 +1,10 @@ +$ok_colour: #0fd30f; +$warn_colour: #ffff00; +$error_colour: #ff0000; +$bg_colour: #070707; +$default_content_colour: #ffffff; +$boot_header_colour: #9acd32; +$font_default: monospace; +$boot_ver: '1.0'; +$shell_colour: $ok_colour; +$shell_font_size: 1.7em; diff --git a/content/styles/generic/main.css b/content/styles/generic/main.css new file mode 100644 index 0000000..7860356 --- /dev/null +++ b/content/styles/generic/main.css @@ -0,0 +1,18 @@ +* { + box-sizing: border-box; + padding: 0; + margin: 0; + font-family: monospace; + color: #ffffff; +} + +html, body { + background-color: #070707; + margin-bottom: 2em; +} + +.iframe { + width: 50%; + min-width: 300px; + max-width: 1000px; +} \ No newline at end of file diff --git a/content/styles/generic/main.scss b/content/styles/generic/main.scss new file mode 100644 index 0000000..56b5e83 --- /dev/null +++ b/content/styles/generic/main.scss @@ -0,0 +1,23 @@ +@import '../config/main'; + + +* { + box-sizing: border-box; + padding: 0; + margin: 0; + + font-family: $font_default; + color: $default_content_colour; +} + +html, body { + background-color: $bg_colour; + margin-bottom: 2em; +} + + +.iframe { + width: 50%; + min-width: 300px; + max-width: 1000px; +} diff --git a/content/styles/shell/main.css b/content/styles/shell/main.css new file mode 100644 index 0000000..14c6b93 --- /dev/null +++ b/content/styles/shell/main.css @@ -0,0 +1,26 @@ +.shell { + margin: 2em; +} +.shell .prompt { + color: #0fd30f; + background-color: #070707; + border: none; + font-size: 1.7em; + width: 90%; + padding: 0 0 1.2em 0; +} +.shell .output { + font-size: 1.4166666667em; +} + +.shell::before { + content: "$ "; + font-size: 1.7em; + color: #ffffff; +} + +.shell[prompt=root]::before { + content: "# "; + font-size: 1.7em; + color: #ffffff; +} \ No newline at end of file diff --git a/content/styles/shell/main.scss b/content/styles/shell/main.scss new file mode 100644 index 0000000..13dcac9 --- /dev/null +++ b/content/styles/shell/main.scss @@ -0,0 +1,32 @@ +@import '../config/main'; + + +.shell { + margin: 2em; + + .prompt { + color: $shell_colour; + background-color: $bg_colour; + border: none; + + font-size: $shell_font_size; + width: 90%; + padding: 0 0 1.2em 0; + } + + .output { + font-size: $shell_font_size / 1.2; + } +} + +.shell::before { + content: '$ '; + font-size: $shell_font_size; + color: $default_content_colour; +} + +.shell[prompt=root]::before { + content: '# '; + font-size: $shell_font_size; + color: $default_content_colour; +} \ No newline at end of file diff --git a/git.sh b/git.sh new file mode 100755 index 0000000..2fccf02 --- /dev/null +++ b/git.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +git add . +git commit -m "update @ $(date)" +git push -u origin terminal diff --git a/index.html b/index.html new file mode 100644 index 0000000..41bad40 --- /dev/null +++ b/index.html @@ -0,0 +1,47 @@ + + + + + + + + Ari::web -> Index + + + + + + + + + + + + + + + + + + +
+
+

+ +
+
+ +
+
+ + + + + diff --git a/page/minimal.txt b/page/minimal.txt new file mode 100644 index 0000000..c293083 --- /dev/null +++ b/page/minimal.txt @@ -0,0 +1,69 @@ +[*] WELCOME TO THE I N T E R N E T... + + +=================== WHY DOES THIS PAGE EVEN EXIST? =====================+ +|| For short: to fill up my website. || +|| || +|| This page is completely accesible to anyone, any system can handle text. || +|| Sometimes I wanna get a break from all of those and CSS and stuff. || +|| I also want more content on this website so I decided to make this. || +|| People using a browser like links can also easily view this page. || +|| || +|| This page isn't meant to look pretty, it's just meant to.. do almost nothing, || +|| that's the point of this page. || +|| I will try to keep updating this page when I'm out of ideas heh. || + +=================================================================================+ + + +-**********************************- [BLOGS] -**********************************- + + 2021.08.07, 17:35 EEST [YYYY/MM/DD] +Hey, sorry for not updating y'all, today was a very calm day. It's cold here. +I like days like this, I've been laying in bed all day hah.. +To be honest it's so weird talking about myself, I don't really know what to say lol, +I'm really boring haha. to be honest I'm thinking of remaking this site with a backend, +or maybe I'll just add a space for comments using disqus, but I'm worries about y'all's privacy +and in general bloat. If you'd like me to add it make a new issue in https://github.com/TruncatedDinosour/website/issues +and I'll add it :). + +I have been not wanting to code lately, I just have been watching some youtuve videos hah, +though for the past two days I wanted to do these two things in C++: + * "Play with memory" game + * Playing around with classes w/ fake crypto currency +it sounds kinda fun hah. + +I restyled the minimal page and I think it looks pretty good now hah, it's nice. +well have a nice day and listen to what the little cow says: + ______________________________________ + / Stay healthy, wear a mask and have a \ + \ nice day :) / + -------------------------------------- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + - Ari + +--------------------------------------------------------------------------------- + + 2021.08.10, 17:00 EEST [YYYY/MM/DD] +Hey, my site is now on wiby! wiby is a search engine for minimal sites and one of them +is mine :) you can find my pages by looking up "ari-web" on wiby: https://wiby.me/?q=ari%2Dweb . +It's quite a cool thing and you can discover nice and intresting things there hah. + +The web was supposed to be minimal and now as we have more resources developers +don't care as much to make it minimal, wiby tries to accomplish this and it's doing a good job at it. + +I also have discoved few minimal protocols: gopher and gemini. +Gopher is a text-only minimal protocol and is faily old, even older than http and https, +it's really light, but it really lacks some stuff like pictures for example, but +that's where gemini comes in, it has more support for "fancy" stuff when still staying pretty light +and it's also faily new, it came out in 2019 and it's still being developed, I'd suggest you to try it. +A good browser I found for gopher, http, https and gemini is kristall, it's pretty cool. + +anyway, Try to keep the web minimal and use as little as you can until you make it look the way you want, +have a nice day. + + - Ari + +-**********************************-_________-**********************************- diff --git a/page/reset/index.html b/page/reset/index.html new file mode 100644 index 0000000..59d0411 --- /dev/null +++ b/page/reset/index.html @@ -0,0 +1,47 @@ + + + + + + + + Ari::web -> Reset + + + + + + + + + + + + + +

Do you want to reset your account?

+
+ +
+ +