Rip out everything

Deleted every file for a full rewrite.
This commit is contained in:
bye 2024-06-27 18:48:09 +01:00
parent 5436336b5d
commit 359471da6b
120 changed files with 0 additions and 23332 deletions

1
.github/FUNDING.yml vendored
View file

@ -1 +0,0 @@
github: byemc

View file

@ -1,3 +0,0 @@
<h1>404</h1>
<p>Sorry, that page couldn't be found.</p>

View file

@ -1,24 +0,0 @@
# id
OAuth authentication service for ByeCorps &amp; other services
## Development & deployment
## FAQ
### What is a ByeCorps ID?
A ByeCorps ID (BCID) is a seven digit alphanumeric (non-case sensitive) code used to identify a person. It is used to reduce the need of multiple accounts across ByeCorps services, as well as third-party services using OAuth (though a password alternative is recommended instead of BCID only)
Example of a BCID:
```txt
123 ABC4
```
## Canonical domain names
Only input your BCID on the following domain names ONLY on a HTTPS connection:
- https://id.byecorps.com
Any other domain name or an insecure connection might be a phishing attempt, so be careful. **NEVER** input your BCID password on any other domain.

View file

@ -1,143 +0,0 @@
<?php
if (!$_SESSION['auth']) {
header('Location: /signin?callback=/account');
exit;
}
function get_gravatar_url( $email ) {
// Trim leading and trailing whitespace from
// an email address and force all characters
// to lower case
$address = strtolower( trim( $email ) );
// Create an SHA256 hash of the final string
$hash = hash( 'sha256', $address );
// Grab the actual image URL
return 'https://www.gravatar.com/avatar/' . $hash;
}
$stmt = $pdo->prepare('SELECT * FROM accounts WHERE id = ? LIMIT 1');
$stmt->execute([$_SESSION['id']]);
$user = $stmt->fetch();
if ($_SERVER['REQUEST_METHOD'] == "POST") {
if (isset($_POST["old_password"]) && $_POST["old_password"] != "") {
// means password reset is wanted.
if (!password_verify($_POST["old_password"], $user["password"])) {
$password_error = "Incorrect password. (Error 901)";
}
if (password_verify($_POST['new_password'], $user["password"])) {
$password_error = "New password may not be same as old password. (Error 902)";
}
if ($_POST['new_password'] != $_POST['repeat_new_password']) {
$password_error = "The passwords must match. (Error 900)";
}
if (isset($password_error)) {
$message = $password_error;
goto skip_submit;
}
$new_password = password_hash($_POST["new_password"], PASSWORD_DEFAULT);
$sql = "UPDATE accounts SET password = ? WHERE id = ?";
$pdo->prepare($sql)->execute([$new_password, $user["id"]]);
}
if (isset($_POST["display_name"])) {
$sql = "UPDATE accounts SET display_name = ? WHERE id = ?";
$pdo->prepare($sql)->execute([$_POST["display_name"], $user["id"]]);
}
$message = "Updated sucessfully. Changes might take a few minutes to take effect.";
header('Location: /profile');
die("Redirecting...");
}
skip_submit:
?>
<h1>Your account</h1>
<?php
if (isset($message )) {
echo "<div class='flash'>".$message."</div>";
}
?>
<div id="wrapper">
<div id="mini_profile">
<img src="<?= get_gravatar_url($user['email']); ?>">
<div class="details">
<span class="displayname"><?= $user['display_name'] ?></span>
<span class="bcid"><?= format_bcid($user['id']); ?></span>
<time datetime="<?= $user["created_date"] ?>">Since <?= $user["created_date"]; ?></time>
</div>
</div>
<aside>
<form method="post">
<fieldset>
<legend>Profile</legend>
<div class="container">
<label>BCID</label>
<input type="text" disabled value="<?= format_bcid($user['id']) ?>">
</div>
<div class="container">
<input type="checkbox" disabled checked="<?= $user['verified'] ?>" >
<label> Verified email</label>
</div>
<div class="container">
<label for="email">Email address</label>
<input type="email" name="email" id="email" value="<?= $user['email'] ?>">
</div>
<div class="container">
<label for="display_name">Display name</label>
<input type="text" name="display_name" id="display_name" value="<?= $user['display_name'] ?>">
</div>
</fieldset>
<fieldset>
<legend>Password</legend>
<p>You only need to insert values here if you're resetting your password.</p>
<div class="container">
<label for="old_password">Current password</label>
<input type="password" name="old_password" id="old_password">
</div>
<div class="container">
<label for="new_password">New password</label>
<input type="password" name="new_password" id="new_password">
</div>
<div class="container">
<label for="repeat_new_password">Repeat new password</label>
<input type="password" name="repeat_new_password" id="repeat_new_password">
</div>
</fieldset>
<button class="primary" type="submit"><i class="fa-fw fa-solid fa-floppy-disk"></i> Save</button>
</form>
<div class="dangerzone">
<h2>Danger Zone</h2>
<p><a href="/signout" class="button"><i class="fa-fw fa-solid fa-person-through-window"></i> Sign out</a>
<a href="/dangerous/delete_account" class="button danger"><i class="fa-fw fa-solid fa-trash"></i> Delete account</a></p>
</div>
</aside>
</div>

View file

@ -1,218 +0,0 @@
<?php
// This file carries functions related to accounts.
function get_avatar_url($bcid):string {
$exists = db_execute('SELECT public FROM avatars WHERE id = ? LIMIT 1', [$bcid]);
if (empty($exists)) {
return '/assets/default.png';
}
return '/public/avatars/' . $bcid;
}
function get_display_name($bcid, $use_bcid_fallback=true, $put_bcid_in_parenthesis=false, $format_bcid=false):string {
$display_name = db_execute("SELECT display_name FROM accounts WHERE id = ?", [$bcid])['display_name'];
if (!empty($display_name)) {
if ($put_bcid_in_parenthesis) {
return $display_name . " ($bcid)";
}
return $display_name;
}
if ($use_bcid_fallback) {
return $bcid;
}
return "";
}
// Tokens so apps can get VERY BASIC information
function generate_basic_access_token($bcid, $application_id=""): array
{
// Returns an access token, a refresh token and an expiry timestamp.
$access_token = md5(uniqid(more_entropy: true).rand(1000000, 9999999));
$refresh_token = md5(uniqid("rfish").rand(1000000, 9999999));
$valid_time = 12; // in hours
$expiry = time() + ($valid_time * 60 * 60);
// echo $access_token . ":" . $refresh_token;
if ($application_id) {
db_execute(
"INSERT INTO tokens (access_token, refresh_token, expiry, owner_id, application_id, permissions) VALUES (?,?,?,?,?, (1<<0 | 1<<1))",
[$access_token, $refresh_token, $expiry, $bcid, $application_id]
);
} else {
db_execute(
"INSERT INTO tokens (access_token, refresh_token, expiry, owner_id, permissions) VALUES (?,?,?,?, (1<<0 | 1<<1))",
[$access_token, $refresh_token, $expiry, $bcid]
);
}
return [
"access" => $access_token,
"refresh" => $refresh_token,
"expiry" => $expiry,
"id" => $bcid
];
}
function generate_token($bcid, $application_id=null, $permissions=0): array {
$access_token = md5(uniqid(more_entropy: true).rand(1000000, 9999999));
$refresh_token = md5(uniqid("rfish").rand(1000000, 9999999));
$valid_time = 12; // in hours
$expiry = time() + ($valid_time * 60 * 60);
db_execute(
"INSERT INTO tokens (access_token, refresh_token, expiry, owner_id, application_id, permissions, type) VALUES (?,?,?,?,?,?, 'oauth')",
[$access_token, $refresh_token, $expiry, $bcid, $application_id, $permissions]
);
return [
"access" => $access_token,
"refresh" => $refresh_token,
"permissions" => $permissions,
"expiry" => $expiry,
"id" => $bcid
];
}
function generate_cookie_access_token($bcid) {
$access_token = md5(uniqid(prefix: "COOKIECOOKIECOOKIE", more_entropy: true).rand(1000000, 9999999));
$valid_time = 365 * 24; // 1 year
$expiry = time() + ($valid_time * 60 * 60);
// echo $access_token . ":" . $refresh_token;
db_execute(
"INSERT INTO tokens (access_token, expiry, owner_id, type) VALUES (?,?,?,'cookie')",
[$access_token, $expiry, $bcid]
);
return [
"access" => $access_token,
"expiry" => $expiry,
"id" => $bcid
];
}
function validate_access_token($access_token): bool
{
$token_details = db_execute("SELECT * FROM tokens WHERE access_token = ?", [$access_token]);
if (null == $token_details) {
return false;
}
if (time() > $token_details['expiry']) {
db_execute("DELETE FROM tokens where access_token = ?", [$access_token]);
return false;
}
return true;
}
// Password resets
const PASSWORD_RESET_VALIDITY = 300; // in seconds.
function create_password_reset($bcid):string {
// Returns a password reset link.
global $pdo;
$reset_time = time() + PASSWORD_RESET_VALIDITY;
$auth_token = generateRandomString(65);
$sql = 'INSERT INTO `password_resets` (auth_id, owner_id, expiration) VALUES (?, ?, ?)';
try{
$stmt = $pdo->prepare($sql);
$stmt->execute([$auth_token, $bcid, $reset_time]);
$reset_id = $pdo->lastInsertId();
} catch (PDOException $e) {
http_response_code(500);
die("An error occurred with the database. (12)");
}
return BASE_URL.'/reset/password?reset_id='.$reset_id.'&reset_token='.$auth_token;
}
function validate_password_reset($reset_id, $reset_token):bool {
global $pdo;
$sql = 'SELECT * FROM password_resets WHERE id = ?';
try {
$stmt = $pdo->prepare($sql);
$stmt->execute([$reset_id]);
$result = $stmt->fetch();
} catch (PDOException $e) {
http_response_code(500);
die("An error occurred fetching data from the database. (11)
$e");
}
if (empty($result)) {
echo "<pre>";
throw new Exception('Todokete setsuna sa ni wa
Namae wo tsukeyou ka "Snow halation"
Omoi ga kasanaru made matezu ni
Kuyashii kedo sukitte junjou
Binetsu no naka tameratte mo dame da ne
Tobikomu yuuki ni sansei mamonaku start!');
}
if ($result['auth_id'] == $reset_token && !hasTimePassed($result['expiration'])) {
return true;
} elseif ($result['auth_id'] == $reset_token && hasTimePassed($result['expiration'])) {
$sql = 'DELETE FROM password_resets WHERE id = ?';
try {
$stmt = $pdo -> prepare(($sql));
$stmt->execute([$reset_id]);
die("Sorry, that link expired. Please request a new one.");
} catch (PDOException $e) {
http_response_code(500);
die("An error occurred deleting data from the database. That link was expired anyway, so request a new one. (13b)
$e");
}
}
return false;
}
function get_id_for_password_reset($reset_id, $reset_token):string {
global $pdo;
$sql = 'SELECT * FROM password_resets WHERE id = ?';
try {
$stmt = $pdo->prepare($sql);
$stmt->execute([$reset_id]);
$result = $stmt->fetch();
} catch (PDOException $e) {
http_response_code(500);
die("An error occurred fetching data from the database. (11)
$e");
}
return $result['owner_id'];
}
function delete_password_reset($reset_id, $reset_token): void
{
global $pdo;
$sql = 'DELETE FROM password_resets WHERE id = ?';
try {
$stmt = $pdo->prepare(($sql));
$stmt->execute([$reset_id]);
header("Location: /signin");
die();
} catch (PDOException $e) {
http_response_code(500);
die("An error occurred deleting data from the database. (13)
$e");
}
}

View file

@ -1,31 +0,0 @@
<h1>Admin panel</h1>
<p>If you're not Bye and you're seeing this, I'm fucked!</p>
<h2>Accounts</h2>
<ul>
<li>
<a href="/admin/list/accounts">List of accounts</a>
</li>
</ul>
<h2>Apps</h2>
<ul>
<li>
<a href="/admin/list/apps">List of applications</a>
</li>
<li>
<a href="/admin/create/app">App creator</a>
</li>
</ul>
<h2>API</h2>
<ul>
<li><a href="/admin/create/token">Token generator</a></li>
</ul>
<h2>Init</h2>
<ul>
<li>
<a href="/admin/init/database">Init database</a>
</li>
</ul>

View file

@ -1,29 +0,0 @@
<?php
$sql = "SELECT * FROM accounts";
$result = $pdo-> query($sql);
if (!$result) {
http_response_code(500);
die("<img src='https://http.cat/500.jpg'>");
}
$count_req = $pdo->query("SELECT COUNT(*) FROM accounts");
$count = $count_req->fetchColumn();
?>
<h1>Accounts</h1>
<p>There is currently <?= $count ?> accounts registered.</p>
<ul>
<?php
foreach ($result as $row) {
echo "<li>";
echo $row['id'];
echo "<p><a href='/admin/signinas?id=".$row['id']."'>Sign in as ".htmlspecialchars($row['display_name'])."</a></li>";
}
?>
</ul>

View file

@ -1,23 +0,0 @@
<?php
$result = db_query("SELECT * FROM apps");
$count_req = db_query("SELECT COUNT(*) FROM apps");
$count = $count_req->fetchColumn();
?>
<h1>Apps</h1>
<p>There is currently <?= $count ?> apps registered.</p>
<ul>
<?php
foreach ($result as $row) {
echo "<li><pre>";
print_r($row);
echo "</li>";
}
?>
</ul>

View file

@ -1,50 +0,0 @@
<?php
function generate_app_id(): int
{
return mt_rand(100000000, 999999999);
}
function check_app_id($app_id): bool
{
$app = db_execute("SELECT * FROM apps WHERE id = ? LIMIT 1", [$app_id]);
return empty($app);
}
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$app_id = generate_app_id();
db_execute("INSERT INTO apps (id, owner_id, title, description, type, callback) VALUES (?, ?, ?, ?, ?, ?)", [$app_id, $_POST['owner'], $_POST['title'], $_POST['description'], $_POST['type'], $_POST['callback']]);
die();
}
?>
<h1>App Creator</h1>
<form method="post">
<label for="title">Title</label>
<input type="text" required name="title" id="title">
<label for="description">Description</label>
<textarea name="description" id="description" cols="30" rows="10"></textarea>
<label for="owner">App owner</label>
<select name="owner" required id="owner">
<?php
$users = db_query("SELECT * FROM accounts");
foreach ($users as $row) {
echo "<option value='".$row['id']."'>".get_display_name($row['id'])." (".$row['id'].") </option>";
}
?>
</select>
<label for="type">App type</label>
<select name="type" required id="type">
<option value="null">None</option>
<option value="basic_login">Basic login</option>
</select>
<label for="app_icon">App icon</label>
<input type="file" id="app_icon" name="app_icon" />
<label for="callback">Callback</label>
<input type="url" id="callback" name="callback" />
<button type="submit" class="primary">Create app</button>
</form>

View file

@ -1,86 +0,0 @@
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
echo "<pre>";
print_r($_POST);
echo "</pre>";
$token = generate_token($_POST['owner'], $_POST['application'], $_POST['permissions']);
echo "<p>Created token. Access token: <code>". $token['access'] ."</code></p>";
}
?>
<h1>Token generator</h1>
<form method="post">
<div class="container">
<label for="owner">Token owner</label>
<select name="owner" required id="owner">
<?php
$users = db_query("SELECT * FROM accounts");
foreach ($users as $row) {
echo "<option value='".$row['id']."'>".get_display_name($row['id'])." (".$row['id'].") </option>";
}
?>
</select>
</div>
<div class="container">
<label for="app">Token app</label>
<select name="app" id="app">
<option value="null">None</option>
<?php
$users = db_query("SELECT * FROM apps");
foreach ($users as $row) {
echo "<option value='".$row['id']."'>". $row['title'] ."</option>";
}
?>
</select>
</div>
<input type="hidden" id="permissions" name="permissions" value="0" />
<h2>Permissions</h2>
<p>Permission number: <span id="permissionnumber"></span></p>
<div class="checkboxes container">
<input type="checkbox" id="account.email" value="1" /><label for="account.email"><code>account.email</code></label>
<input type="checkbox" id="account.settings" value="2" /><label for="account.settings"><code>account.settings</code></label>
</div>
<button type="submit">Generate!</button>
</form>
<style>
form .container {
display: unset;
}
</style>
<script>
const displayNumber = document.getElementById("permissionnumber");
const permissionsInput = document.getElementById("permissions");
const checkboxes = document.querySelectorAll("input[type='checkbox']");
console.log(checkboxes);
function updateCheckboxes() {
let permissions = 0;
for (let checkbox of checkboxes) {
if (checkbox.checked) {
permissions += Number(checkbox.value);
}
}
displayNumber.innerText = permissions.toString();
permissionsInput.value = permissions;
}
for (let checkbox of checkboxes) {
checkbox.onchange = updateCheckboxes;
}
updateCheckboxes();
</script>

View file

@ -1,152 +0,0 @@
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if ($_POST['init'] == 'Init') {
echo("<p>Initialising DB...");
echo "<p>Create table `accounts`";
$stmt = $pdo->prepare('create table accounts
(
id varchar(7) not null
primary key,
email text not null,
created_date datetime default current_timestamp() not null,
display_name text null,
password text not null,
verified tinyint(1) default 0 not null,
has_pfp tinyint(1) default 0 not null,
is_admin tinyint(1) default 0 not null,
constraint email
unique (email) using hash
);');
try {
$stmt->execute();
} catch (PDOException $e) {
echo('<p>An error occurred: '. $e->getMessage() .'. Will skip. (Most likely the table already exists.)');
}
echo '<p>Create the `password_resets` table';
$stmt = $pdo->prepare('create table password_resets
(
id int auto_increment
primary key,
auth_id tinytext not null,
owner_id varchar(7) not null,
expiration int not null,
constraint password_resets_ibfk_1
foreign key (owner_id) references accounts (id)
);');
try {
$stmt->execute();
} catch (PDOException $e) {
echo('<p>An error occurred: '. $e->getMessage() .'. Most likely this is already set.');
}
echo '<p>Create the `apps` table';
try {
db_execute('create table apps (
id int auto_increment
primary key,
owner_id varchar(7) not null,
title text not null,
description text,
image text default "https://id.byecorps.com/assets/default.png" not null,
type text null,
callback text null,
constraint apps_ibfk_1
foreign key (owner_id) references accounts (id)
);');
} catch (PDOException $e) {
echo('<p>An error occurred: '. $e->getMessage() .'. Most likely this is already set.');
}
echo '<p>Create the `badges` table';
try {
db_execute('create table badges (
id int auto_increment
primary key,
app_id int not null,
title text not null,
description text,
image text default "https://id.byecorps.com/assets/default.png" not null,
type text null,
callback text null,
constraint badges_ibfk_1
foreign key (app_id) references apps (id)
);');
} catch (PDOException $e) {
echo('<p>An error occurred: '. $e->getMessage() .'. Most likely this is already set.');
}
echo '<p>Create the `profiles` table';
try {
db_execute('create table profiles (
id varchar(7)
primary key,
description text null,
public_avatar tinyint(1) default 0,
public_display_name tinyint(1) default 0,
constraint profiles_ibfk_1
foreign key (id) references accounts (id)
);');
} catch (PDOException $e) {
echo('<p>An error occurred: '. $e->getMessage() .'. Most likely this is already set.');
}
echo '<p>Create the `tokens` table';
try {
db_execute('create table tokens (
id int auto_increment primary key,
access_token text unique,
refresh_token text null,
expiry int not null,
owner_id varchar(7),
application_id int(10) null,
constraint tokens_application_id
foreign key (application_id) references apps (id),
constraint tokens_owner_id
foreign key (owner_id) references accounts (id)
);');
} catch (PDOException $e) {
echo('<p>An error occurred: '. $e->getMessage() .'. Most likely this is already set.');
}
echo '<p>Create the `tokens` table';
try {
db_query('CREATE TABLE `badge_owners` (
`badge_id` int(11) NOT NULL,
`owner_id` varchar(7) NOT NULL,
`earned` timestamp NULL DEFAULT current_timestamp(),
`info` text DEFAULT NULL COMMENT \'App may attach more info about how the badge was won (Killed "CoolGamer69 in battle!")\',
constraint badges_owners_badge
foreign key (badge_id) references badges (id),
constraint badges_owners_owner
foreign key (owner_id) references accounts (id)
);');
} catch (PDOException $e) {
echo('<p>An error occurred: ' . $e->getMessage() . '. Most likely this is already set.');
}
echo "<p>Database initialised.</p>";
}
}
?>
<h1>Init database</h1>
<p>Assuming you have the database config configured, you can click this button to create the tables required for this thing to function.</p>
<form method="post">
<button name="init" value="Init" class="primary">Init DB</button>
</form>

View file

@ -1,29 +0,0 @@
<?php
if ($_SERVER['REQUEST_METHOD'] == "POST") {
if ($_POST['purge'] == 'purge') {
db_execute("DELETE FROM `password_resets` WHERE expiration < ?", [time()]);
db_execute("DELETE FROM `tokens` WHERE expiry < ?", [time()]);
}
}
$expired_password_resets = db_execute("SELECT * FROM `password_resets` WHERE expiration < ?", [time()]);
$expired_tokens = db_execute("SELECT * FROM `tokens` WHERE expiry < ?", [time()]);
?>
<h1>Purge</h1>
<form method="post">
<p>
<button name="purge" value="purge" type="submit" class="primary">Purge</button>
</p>
</form>
<h2>Expired password resets</h2>
<pre><?php print_r($expired_password_resets) ?></pre>
<h2>Expired Login tokens</h2>
<pre><?php print_r($expired_tokens) ?></pre>

View file

@ -1,198 +0,0 @@
<?php
$output_format = "json";
header('Content-type: application/json');
if (array_key_exists('HTTP_AUTHORIZATION', $_SERVER)) {
$access_token = str_replace("Bearer ", "", $_SERVER['HTTP_AUTHORIZATION']);
}
if (!empty($access_token)) {
// Check who the access token belongs to
$token = db_execute("SELECT * FROM tokens WHERE access_token = ?", [$access_token]);
// if the token doesn't exist...
if (empty($token)) {
$invalid_token = true; // We won't tell this to the end-user immediately because I'd prefer to tell them about
// 404 first.
} else {
$token_owner = $token['owner_id'];
}
}
function check_authorisation($token=""): int
{
global $token_owner;
// Validate token
if (!validate_access_token($token) && "" != $token) {
return 0; // Unauthorised
}
// Check the type of token
$token_row = db_execute("SELECT * FROM tokens WHERE access_token = ?", [$token]);
if (null == $token_row) {
if (array_key_exists('auth', $_SESSION)) {
if ($_SESSION['auth']) {
$token_row = [
"type" => "dangerous"
];
$token_owner = $_SESSION['id'];
} else {
return 0;
}
} else {
return 0;
}
}
return match ($token_row['type']) {
"dangerous" => 1<<0 | 1<<1, // Everything
"basic" => 1<<1, // Basic
"oauth" => $token_row['permissions'],
default => 0,
};
}
// Misc (unauthorised)
function redirect_to_documentation(): void
{
header('Location: /docs/api');
}
// Health check
function api_health_check(): array
{
return ["message" => "Science compels us to explode the sun!", "time" => time(), "response_code" => 200];
}
// Potentially authenticated image endpoints
function get_avatar(): array
{
if (!array_key_exists('id', $query)) {
return [
'response_code' => 404,
'message' => 'ID not assigned/found'
];
}
$user_id = $query['id'];
return [];
}
// User (REQUIRES AUTHORISATION)
function api_user_info(): array
{
global $access_token, $token_owner;
// Authorisation levels:
// `display_name` = 1 (basic)
// `id` = 1 (basic)
// `email` = 1 (basic)
$level = check_authorisation($access_token);
$data = null;
if ($level & (1 << 0)) {
$data = db_execute("SELECT id, email, display_name FROM accounts WHERE id = ? LIMIT 1", [$token_owner]);
} else {
$data = db_execute("SELECT id, display_name FROM accounts WHERE id = ? LIMIT 1", [$token_owner]);
}
if (null != $data) {
return [
"response_code" => 200,
"data" => $data
];
}
http_response_code(401);
return [
"response_code" => 401,
"message" => "Unauthorized."
];
}
function api_settings(): array
{
// GET: Return all settings
// POST/PATCH: Update settings
global $access_token, $token_owner;
$level = check_authorisation($access_token);
if (!($level & (1 << 1))) { // account.settings
http_response_code(401);
return [
"response_code" => 401,
"message" => "Unauthorized."
];
}
if ($_SERVER['REQUEST_METHOD'] === "POST") {
// Now for the fucking worstest code ever
$settings_changed = json_decode(file_get_contents('php://input'), true);
if (isset($settings_changed['account'])) {
if (isset($settings_changed['account']['display_name'])) {
$display_name = db_execute('UPDATE accounts SET display_name = ? WHERE id = ?',
[$settings_changed['account']['display_name'], $token_owner]);
}
}
}
// Get account settings
$display_name = db_execute('SELECT display_name FROM accounts WHERE id = ?', [$token_owner])["display_name"];
return [
"response_code" => 200,
"settings" => [
"account" => [
"display_name" => $display_name,
]
]
];
}
$api_routes = [ // base url is base_url.'/api'
// "/path" => "function_name"
// Misc
"" => "redirect_to_documentation",
"/status" => "api_health_check",
// Account stuff
"/account/me" => "api_user_info",
// Settings
"/settings" => "api_settings",
// Get avatar
"/avatars/get" => "get_avatar"
];
$path = str_replace("/api", "", $path);
if (isset($api_routes[$path])) {
if (isset($invalid_token)) {
http_response_code(498);
echo (json_encode([
"response_code" => "498",
"message" => "Token expired or invalid."
]));
exit();
}
$response = $api_routes[$path]();
if (array_key_exists('response_code', $response)) {
http_response_code($response['response_code']);
}
echo json_encode($response);
} else {
http_response_code(404);
echo (json_encode([
"response_code" => "404",
"message" => "Route not found."
]));
}

View file

@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -0.5 32 32" shape-rendering="crispEdges">
<metadata>Made with Pixels to Svg https://codepen.io/shshaw/pen/XbxvNj</metadata>
<path stroke="#cbdbfc" d="M2 4h28M2 5h1M29 5h1M0 6h3M29 6h3M0 7h1M31 7h1M0 8h1M31 8h1M0 9h1M31 9h1M0 10h1M31 10h1M0 11h1M31 11h1M0 12h1M31 12h1M0 13h1M31 13h1M0 14h1M31 14h1M0 15h1M31 15h1M0 16h1M31 16h1M0 17h1M31 17h1M0 18h1M31 18h1M0 19h1M31 19h1M0 20h1M31 20h1M0 21h1M31 21h1M0 22h1M31 22h1M0 23h1M31 23h1M0 24h1M31 24h1M0 25h3M29 25h3M2 26h1M29 26h1M2 27h28" />
<path stroke="#ffffff" d="M3 5h26M3 6h26M1 7h30M1 8h30M1 9h30M1 10h6M8 10h1M10 10h6M21 10h1M25 10h6M1 11h7M9 11h9M19 11h3M23 11h2M26 11h5M1 12h6M12 12h6M19 12h3M23 12h2M26 12h5M1 13h6M12 13h6M19 13h3M23 13h2M26 13h5M1 14h6M12 14h6M19 14h3M23 14h2M26 14h5M1 15h6M12 15h6M19 15h3M23 15h2M26 15h5M1 16h15M21 16h1M25 16h6M1 17h6M12 17h19M1 18h5M13 18h18M1 19h5M13 19h3M24 19h1M26 19h5M1 20h5M13 20h18M1 21h5M13 21h3M17 21h1M21 21h1M26 21h5M1 22h30M1 23h30M1 24h30M3 25h26M3 26h26" />
<path stroke="#000000" d="M7 10h1M9 10h1M16 10h5M22 10h3M8 11h1M18 11h1M22 11h1M25 11h1M7 12h5M18 12h1M22 12h1M25 12h1M7 13h5M18 13h1M22 13h1M25 13h1M7 14h5M18 14h1M22 14h1M25 14h1M7 15h5M18 15h1M22 15h1M25 15h1M16 16h5M22 16h3M7 17h5M6 18h7M6 19h7M16 19h8M25 19h1M6 20h7M6 21h7M16 21h1M18 21h3M22 21h4" />
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1,88 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="300.858"
height="50"
viewBox="0 0 79.602012 13.229167"
version="1.1"
id="svg1"
xml:space="preserve"
inkscape:export-filename="bitmap.png"
inkscape:export-xdpi="192"
inkscape:export-ydpi="192"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
sodipodi:docname="bcidsignin.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="true"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="true"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showborder="false"
labelstyle="default"
inkscape:zoom="2.8649832"
inkscape:cx="165.446"
inkscape:cy="-36.300388"
inkscape:window-width="1920"
inkscape:window-height="1008"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" /><defs
id="defs1" /><g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2"><rect
style="display:inline;opacity:1;fill:#efdd8d;fill-opacity:1;stroke:#dcc455;stroke-width:0.261525;stroke-dasharray:none;stroke-opacity:1"
id="rect35"
width="79.340492"
height="12.967643"
x="0.13076229"
y="0.13076213"
ry="2.0748229"
rx="2.1097128"
inkscape:label="Background" /><g
style="shape-rendering:crispEdges"
id="g32"
transform="matrix(0.52916667,0,0,0.52916667,9.5250001,3.7041667)"
inkscape:label="BCID person"><g
id="layer1-5"
inkscape:label="BCID logo"><g
id="g27"
inkscape:label="Body"
style="opacity:1"><path
id="rect26"
style="opacity:1;fill:#000000;fill-opacity:1"
d="M 1.0058594,6.5 C 1.0026133,6.5 1,6.5026133 1,6.5058594 V 7.4941406 C 1,7.4973867 1.0026133,7.5 1.0058594,7.5 H 0.00585938 C 0.00261328,7.5 0,7.5026133 0,7.5058594 V 11.494141 C 0,11.497387 0.00261328,11.5 0.00585938,11.5 H 7.9941406 C 7.9973867,11.5 8,11.497387 8,11.494141 V 7.5058594 C 8,7.5026133 7.9973867,7.5 7.9941406,7.5 h -1 C 6.9973867,7.5 7,7.4973867 7,7.4941406 V 6.5058594 C 7,6.5026133 6.9973867,6.5 6.9941406,6.5 Z"
inkscape:label="Body" /></g><g
id="g31"
inkscape:label="Head"><path
id="rect28"
style="opacity:1;fill:#000000;fill-opacity:1"
d="M 1.0058594,-0.5 C 1.0026133,-0.5 1,-0.49738672 1,-0.49414062 V 0.49414062 C 1,0.49738672 1.0026133,0.5 1.0058594,0.5 H 1.9941406 C 1.9973867,0.5 2,0.49738672 2,0.49414062 V -0.49414062 C 2,-0.49738672 1.9973867,-0.5 1.9941406,-0.5 Z m 2,0 C 3.0026133,-0.5 3,-0.49738672 3,-0.49414062 V 0.49414062 C 3,0.49738672 3.0026133,0.5 3.0058594,0.5 H 4.9941406 C 4.9973867,0.5 5,0.49738672 5,0.49414062 V -0.49414062 C 5,-0.49738672 4.9973867,-0.5 4.9941406,-0.5 Z m -1,1 C 2.0026133,0.5 2,0.50261328 2,0.50585938 V 1.4941406 C 2,1.4973867 2.0026133,1.5 2.0058594,1.5 h -1 C 1.0026133,1.5 1,1.5026133 1,1.5058594 V 5.4941406 C 1,5.4973867 1.0026133,5.5 1.0058594,5.5 H 6.9941406 C 6.9973867,5.5 7,5.4973867 7,5.4941406 V 1.5058594 C 7,1.5026133 6.9973867,1.5 6.9941406,1.5 h -4 C 2.9973867,1.5 3,1.4973867 3,1.4941406 V 0.50585938 C 3,0.50261328 2.9973867,0.5 2.9941406,0.5 Z"
inkscape:label="Head" /></g></g></g><g
id="text32"
style="font-weight:500;font-size:4.58611px;font-family:Montserrat;-inkscape-font-specification:'Montserrat, Medium';letter-spacing:-0.079375px;word-spacing:0.0926042px;stroke-width:0;stroke-miterlimit:8.7"
inkscape:label="Sign in"
transform="scale(0.95030748,1.052291)"
aria-label="Sign in with ByeCorps ID"><path
style="font-weight:normal;-inkscape-font-specification:'Montserrat, Normal';opacity:1"
d="m 19.328294,7.9399255 c 0.820914,0 1.196975,-0.4035777 1.196975,-0.875947 0,-1.1694581 -1.976613,-0.6374693 -1.976613,-1.5180025 0,-0.3210277 0.261408,-0.582436 0.84843,-0.582436 0.284339,0 0.605367,0.087136 0.880533,0.2659944 L 20.392272,4.9589539 C 20.13545,4.7800956 19.759389,4.6746151 19.397086,4.6746151 c -0.816327,0 -1.183216,0.4081638 -1.183216,0.8805331 0,1.1878025 1.976613,0.6466416 1.976613,1.5271747 0,0.3164416 -0.261408,0.5686777 -0.862189,0.5686777 -0.421922,0 -0.830085,-0.1651 -1.059391,-0.3898194 l -0.132997,0.2614083 c 0.238478,0.2476499 0.710847,0.417336 1.192388,0.417336 z m 1.952271,-2.9672133 c 0.137584,0 0.238478,-0.1054805 0.238478,-0.2384777 0,-0.123825 -0.105481,-0.2247194 -0.238478,-0.2247194 -0.132997,0 -0.238477,0.1054806 -0.238477,0.2293055 0,0.1284111 0.10548,0.2338916 0.238477,0.2338916 z m 0.160514,2.9396966 V 5.5001149 H 21.115465 V 7.9124088 Z M 24.19133,5.963312 C 23.989541,5.6468704 23.640997,5.4817705 23.237419,5.4817705 c -0.687917,0 -1.210733,0.4723693 -1.210733,1.1648719 0,0.6925027 0.522816,1.1740442 1.210733,1.1740442 0.394405,0 0.738364,-0.1605138 0.940153,-0.4677832 v 0.3072694 c 0,0.5961943 -0.279753,0.875947 -0.889706,0.875947 -0.371475,0 -0.720019,-0.123825 -0.949325,-0.3301999 l -0.1651,0.2476499 c 0.252236,0.2384777 0.683331,0.3714749 1.123597,0.3714749 0.797984,0 1.206147,-0.376061 1.206147,-1.2061469 V 5.5001149 H 24.19133 Z m -0.921808,1.5684497 c -0.531989,0 -0.912636,-0.3623027 -0.912636,-0.8851193 0,-0.5228165 0.380647,-0.8805331 0.912636,-0.8805331 0.531989,0 0.917222,0.3577166 0.917222,0.8805331 0,0.5228166 -0.385233,0.8851193 -0.917222,0.8851193 z m 3.296006,-2.0499912 c -0.417336,0 -0.74295,0.169686 -0.917222,0.4631971 V 5.5001149 H 25.33645 v 2.4122939 h 0.325614 V 6.6466424 c 0,-0.5503332 0.325614,-0.8713609 0.843844,-0.8713609 0.458611,0 0.724606,0.2614083 0.724606,0.7704665 v 1.3666608 h 0.325614 V 6.5136452 c 0,-0.6925026 -0.403578,-1.0318747 -0.9906,-1.0318747 z m 3.17623,-0.5090583 c 0.137583,0 0.238478,-0.1054805 0.238478,-0.2384777 0,-0.123825 -0.105481,-0.2247194 -0.238478,-0.2247194 -0.132997,0 -0.238478,0.1054806 -0.238478,0.2293055 0,0.1284111 0.105481,0.2338916 0.238478,0.2338916 z m 0.160514,2.9396966 V 5.5001149 H 29.576658 V 7.9124088 Z M 31.96002,5.4817705 c -0.417336,0 -0.74295,0.169686 -0.917222,0.4631971 V 5.5001149 h -0.311856 v 2.4122939 h 0.325614 V 6.6466424 c 0,-0.5503332 0.325614,-0.8713609 0.843844,-0.8713609 0.458611,0 0.724606,0.2614083 0.724606,0.7704665 V 7.9124088 H 32.95062 V 6.5136452 c 0,-0.6925026 -0.403578,-1.0318747 -0.9906,-1.0318747 z M 37.447649,7.5501061 36.677182,5.5001149 H 36.397429 L 35.622377,7.5501061 34.865669,5.5001149 h -0.311856 l 0.90805,2.4122939 h 0.307269 l 0.761295,-1.9766134 0.761294,1.9766134 h 0.307269 l 0.912636,-2.4122939 h -0.298097 z m 1.640415,-2.5773939 c 0.137583,0 0.238477,-0.1054805 0.238477,-0.2384777 0,-0.123825 -0.10548,-0.2247194 -0.238477,-0.2247194 -0.132998,0 -0.238478,0.1054806 -0.238478,0.2293055 0,0.1284111 0.10548,0.2338916 0.238478,0.2338916 z m 0.160514,2.9396966 V 5.5001149 h -0.325614 v 2.4122939 z m 1.984371,-0.3806471 c -0.09172,0.08255 -0.224719,0.123825 -0.357717,0.123825 -0.27058,0 -0.417336,-0.1559278 -0.417336,-0.4402666 V 5.7752815 h 0.733778 V 5.5001149 H 40.457896 V 4.9727122 h -0.325614 v 0.5274027 h -0.431094 v 0.2751666 h 0.431094 v 1.458383 c 0,0.4448527 0.252237,0.7016749 0.706261,0.7016749 0.188031,0 0.380648,-0.055033 0.509059,-0.1696861 z m 1.855963,-2.0499912 c -0.408164,0 -0.724606,0.1605138 -0.903464,0.4402665 V 4.5095151 h -0.325614 v 3.4028937 h 0.325614 V 6.6466424 c 0,-0.5503332 0.325614,-0.8713609 0.843844,-0.8713609 0.458611,0 0.724606,0.2614083 0.724606,0.7704665 v 1.3666608 h 0.325614 V 6.5136452 c 0,-0.6925026 -0.403578,-1.0318747 -0.9906,-1.0318747 z"
id="path40" /><path
style="font-weight:bold;-inkscape-font-specification:'Montserrat, Bold'"
d="m 48.383925,6.2430647 c 0.261408,-0.1375833 0.426508,-0.3852332 0.426508,-0.7062609 0,-0.499886 -0.41275,-0.8346721 -1.215319,-0.8346721 h -1.56845 v 3.2102771 h 1.660172 c 0.843844,0 1.284111,-0.3210277 1.284111,-0.875947 0,-0.4035777 -0.229306,-0.6787443 -0.587022,-0.7933971 z M 47.503392,5.2616372 c 0.362302,0 0.559505,0.123825 0.559505,0.376061 0,0.2522361 -0.197203,0.3806472 -0.559505,0.3806472 H 46.765028 V 5.2616372 Z M 46.765028,7.3529034 V 6.5595063 h 0.866775 c 0.385233,0 0.591608,0.1284111 0.591608,0.3989916 0,0.2751666 -0.206375,0.3944055 -0.591608,0.3944055 z M 50.469192,7.1190118 49.776689,5.4450816 h -0.738364 l 1.068564,2.4856717 -0.0092,0.022931 c -0.09631,0.2201333 -0.206375,0.3072694 -0.403578,0.3072694 -0.142169,0 -0.293511,-0.059619 -0.403578,-0.1559277 l -0.261408,0.5090582 c 0.160514,0.1421694 0.43568,0.2247194 0.687917,0.2247194 0.444852,0 0.784224,-0.1788583 1.022702,-0.7750526 L 51.854197,5.4450816 H 51.16628 Z m 3.947232,-0.4310944 c 0,-0.793397 -0.559506,-1.2795247 -1.284111,-1.2795247 -0.752122,0 -1.316214,0.5319888 -1.316214,1.2703525 0,0.7337776 0.55492,1.2703525 1.407936,1.2703525 0.444853,0 0.788811,-0.1375833 1.018117,-0.3989916 L 53.861505,7.1373562 c -0.169686,0.1605139 -0.357717,0.2384777 -0.619125,0.2384777 -0.376061,0 -0.63747,-0.1880305 -0.706261,-0.4952998 h 1.866547 c 0.0046,-0.05962 0.01376,-0.1375834 0.01376,-0.1926167 z M 53.136899,5.9495537 c 0.321028,0 0.55492,0.2017888 0.605367,0.5136443 h -1.215319 c 0.05045,-0.3164416 0.284338,-0.5136443 0.609952,-0.5136443 z"
id="path41" /><path
style="font-weight:600;-inkscape-font-specification:'Montserrat, Semi-Bold'"
d="m 56.400799,7.9582699 c 0.527402,0 0.976841,-0.1880305 1.274938,-0.5365749 L 57.290504,7.0548062 c -0.233892,0.2568222 -0.522816,0.3806472 -0.857602,0.3806472 -0.664986,0 -1.146528,-0.4677833 -1.146528,-1.1281831 0,-0.6603999 0.481542,-1.1281831 1.146528,-1.1281831 0.334786,0 0.62371,0.123825 0.857602,0.376061 L 57.675737,5.1928455 C 57.37764,4.8443012 56.928201,4.6562706 56.405385,4.6562706 c -0.986014,0 -1.719791,0.6925027 -1.719791,1.6509997 0,0.958497 0.733777,1.6509996 1.715205,1.6509996 z m 2.722731,-0.013758 c 0.761295,0 1.307042,-0.5228166 1.307042,-1.2565942 0,-0.7337776 -0.545747,-1.252008 -1.307042,-1.252008 -0.752122,0 -1.302455,0.5182304 -1.302455,1.252008 0,0.7337776 0.550333,1.2565942 1.302455,1.2565942 z m 0,-0.4907138 c -0.41275,0 -0.724605,-0.2980971 -0.724605,-0.7658804 0,-0.4677832 0.311855,-0.7658804 0.724605,-0.7658804 0.417336,0 0.729192,0.2980972 0.729192,0.7658804 0,0.4677833 -0.311856,0.7658804 -0.729192,0.7658804 z M 61.447281,5.463426 h -0.545747 v 2.4489828 h 0.573263 V 6.7246063 c 0,-0.499886 0.275167,-0.7567082 0.710848,-0.7567082 0.04127,0 0.08255,0.00459 0.132997,0.013758 V 5.4359094 c -0.408164,0 -0.706261,0.128411 -0.871361,0.3852332 z m 2.635605,-0.027517 c -0.334786,0 -0.619125,0.1146527 -0.811741,0.3485443 V 5.463426 h -0.545747 v 3.3386882 h 0.573263 V 7.6143117 c 0.197203,0.2247194 0.47237,0.3301999 0.784225,0.3301999 0.715433,0 1.242836,-0.4952999 1.242836,-1.2565942 0,-0.7567081 -0.527403,-1.252008 -1.242836,-1.252008 z m -0.06421,2.0178884 c -0.41275,0 -0.729192,-0.2980971 -0.729192,-0.7658804 0,-0.4677832 0.316442,-0.7658804 0.729192,-0.7658804 0.41275,0 0.724605,0.2980972 0.724605,0.7658804 0,0.4677833 -0.311855,0.7658804 -0.724605,0.7658804 z m 2.530125,0.4907138 c 0.687916,0 1.109838,-0.2980972 1.109838,-0.7567082 0,-0.958497 -1.513416,-0.5182304 -1.513416,-1.0135303 0,-0.1605139 0.1651,-0.2751666 0.513644,-0.2751666 0.233892,0 0.467784,0.045861 0.701675,0.1834444 l 0.220134,-0.4356805 c -0.220134,-0.1329972 -0.591609,-0.210961 -0.917222,-0.210961 -0.6604,0 -1.077736,0.3026832 -1.077736,0.7658804 0,0.9768414 1.513416,0.5365748 1.513416,1.0043581 0,0.169686 -0.151342,0.2705805 -0.513644,0.2705805 -0.30727,0 -0.63747,-0.1008945 -0.853017,-0.2430639 L 65.512345,7.669345 c 0.220133,0.1559277 0.628297,0.2751666 1.036461,0.2751666 z"
id="path42" /><path
style="font-weight:normal;-inkscape-font-specification:'Montserrat, Normal';opacity:1"
d="M 69.775483,7.9124088 V 4.7021317 H 69.43611 v 3.2102771 z m 2.273299,0 c 1.027288,0 1.719791,-0.6603998 1.719791,-1.6051385 0,-0.9447387 -0.692503,-1.6051386 -1.719791,-1.6051386 H 70.74174 v 3.2102771 z m -0.96767,-2.916766 h 0.949325 c 0.853017,0 1.40335,0.541161 1.40335,1.3116275 0,0.7704665 -0.550333,1.3116275 -1.40335,1.3116275 h -0.949325 z"
id="path43" /></g></g></svg>

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -0.5 32 32" shape-rendering="crispEdges">
<metadata>Made with Pixels to Svg https://codepen.io/shshaw/pen/XbxvNj</metadata>
<path stroke="#cbdbfc" d="M2 4h28M2 5h1M29 5h1M0 6h3M29 6h3M0 7h1M31 7h1M0 8h1M31 8h1M0 9h1M31 9h1M0 10h1M31 10h1M0 11h1M31 11h1M0 12h1M31 12h1M0 13h1M31 13h1M0 14h1M31 14h1M0 15h1M31 15h1M0 16h1M31 16h1M0 17h1M31 17h1M0 18h1M31 18h1M0 19h1M31 19h1M0 20h1M31 20h1M0 21h1M31 21h1M0 22h1M31 22h1M0 23h1M31 23h1M0 24h1M31 24h1M0 25h3M29 25h3M2 26h1M29 26h1M2 27h28" />
<path stroke="#ffffff" d="M3 5h26M3 6h26M1 7h30M1 8h30M1 9h30M1 10h6M8 10h1M10 10h6M21 10h1M25 10h6M1 11h7M9 11h9M19 11h3M23 11h2M26 11h5M1 12h6M12 12h6M19 12h3M23 12h2M26 12h5M1 13h6M12 13h6M19 13h3M23 13h2M26 13h5M1 14h6M12 14h6M19 14h3M23 14h2M26 14h5M1 15h6M12 15h6M19 15h3M23 15h2M26 15h5M1 16h15M21 16h1M25 16h6M1 17h6M12 17h19M1 18h5M13 18h18M1 19h5M13 19h3M24 19h1M26 19h5M1 20h5M13 20h18M1 21h5M13 21h3M17 21h1M21 21h1M26 21h5M1 22h30M1 23h30M1 24h30M3 25h26M3 26h26" />
<path stroke="#000000" d="M7 10h1M9 10h1M16 10h5M22 10h3M8 11h1M18 11h1M22 11h1M25 11h1M7 12h5M18 12h1M22 12h1M25 12h1M7 13h5M18 13h1M22 13h1M25 13h1M7 14h5M18 14h1M22 14h1M25 14h1M7 15h5M18 15h1M22 15h1M25 15h1M16 16h5M22 16h3M7 17h5M6 18h7M6 19h7M16 19h8M25 19h1M6 20h7M6 21h7M16 21h1M18 21h3M22 21h4" />
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1,8 +0,0 @@
{
"require": {
"sentry/sdk": "^4.0",
"erusev/parsedown": "^1.7",
"erusev/parsedown-extra": "^0.8.1",
"resend/resend-php": "^0.11.0"
}
}

1219
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,206 +0,0 @@
<style>
main {
display: flex;
flex-direction: column;
}
#credits {
max-height: 80vh;
width: 100%;
flex:1;
scroll-behavior: smooth;
overflow: hidden;
}
#credits > :last-child {
margin-top: 40vh;
margin-bottom: 65vh;
}
#credits .title {
position: sticky;
top: 0;
padding-top: 2rem;
padding-bottom: 2rem;
background: linear-gradient(to top, #ffffff00, var(--background) 2rem);
display: flex;
align-items: end;
gap: 0.5rem;
}
@media screen and (prefers-color-scheme: dark) {
#credits .title {
background: linear-gradient(to top, #12121200, var(--background-dark) 2rem);
}
}
#credits .title > * {
margin: 0;
}
#credits .spacer {
display: block;
/*position: relative;*/
height: 65vh;
transition: height 0.5s ease-in-out;
}
#fps {
position: fixed;
bottom: .5rem;
left: .5rem;
font-family: monospace;
}
.fa-ul {
position: relative;
z-index: -10;
}
</style>
<div id="fps"></div>
<div id="credits">
<div class="title">
<h1 class="logo"><span class="bc-1">Bye</span><span class="bc-2">Corps</span><span class="bc-3"> ID</span></h1>
<span class="subtitle">v. <?= current_git_commit() ?></span>
</div>
<p>ByeCorps ID is a <a href="https://byecorps.com">ByeCorps</a> service created by <a href="https://byemc.xyz">Bye</a>. It wouldn't be possible without the work of other amazing people.</p>
<button id="start">Show credits.</button>
<div class="spacer"></div>
<h2>Credits</h2>
<ul>
<li><a href="https://bye.omg.lol">Bye</a>, who programmed this entire thing.</li>
<li><a href="https://adam.omg.lol">Adam Newbold</a> for writing the code this site depends on for routing</li>
<li>PHP, the language it's built in.</li>
<li>Composer, to keep all the libs together.</li>
<li>Caddy, the webserver it's usually running on.</li>
<li>MariaDB, the MySQL server.</li>
<li>PhpStorm by JetBrains and Visual Studio Code by Microsoft, both of which were used to make this service.</li>
</ul>
<h2>Music</h2>
<ul class="fa-ul music">
<li><span class="fa-li fa-fw fa-solid fa-compact-disc fa-spin"></span> <strong>Now playing</strong>:<br>"Screen Saver" Kevin MacLeod (<a href="https://incompetech.com">incompetech.com</a>)<br>
Licensed under Creative Commons: By Attribution 4.0 License<br>
<a href="http://creativecommons.org/licenses/by/4.0/">http://creativecommons.org/licenses/by/4.0/</a></li>
<li><span class="fa-li fa-fw fa-solid fa-music"></span>"Electrodoodle" Kevin MacLeod (<a href="https://incompetech.com">incompetech.com</a>)<br>
Licensed under Creative Commons: By Attribution 4.0 License <br>
<a href="http://creativecommons.org/licenses/by/4.0/">http://creativecommons.org/licenses/by/4.0/</a></span></li>
</ul>
<h2>Third-party libraries</h2>
<p>ByeCorps ID relies on the following third-party libraries:</p>
<ul>
<li><code>sentry/sdk</code> for diagnostics.</li>
<li><code>phpmailer/phpmailer</code> for email.</li>
<li><code>erusev/parsedown</code> and <code>erusev/parsedown-extra</code> for parsing Markdown right in PHP.</li>
<li><code>kornrunner/blurhash</code> for generating blurhashes.</li>
</ul>
<p>Getting the FPS of your display powered by <a href="https://stackoverflow.com/a/5111475">this StackOverflow answer</a>.</p>
<a id="final"></a>
<p>Thank you for using ByeCorps ID.</p>
</div>
<script>
//autoscroll
const credits = document.getElementById("credits");
const finalLine = document.getElementById("final");
credits.scrollTop = 0;
let fakeScrollTop = 1;
let speed = 15 // pixels per second
// speed = 100
const music = new Audio("https://cdn.byecorps.com/id/music/Screen Saver.mp3");
music.loop = true;
const silence = new Audio("https://cdn.byecorps.com/id/music/500-milliseconds-of-silence.mp3");
var filterStrength = 60;
var frameTime = 0, lastLoop = new Date, thisLoop;
let fps = 60;
setInterval(function(){
document.getElementById("fps").innerText = (1000/frameTime).toFixed(0) + ` / Speed ${speed}`;
fps = 1000/frameTime;
},1000);
function setFPS() {
var thisFrameTime = (thisLoop=new Date) - lastLoop;
frameTime+= (thisFrameTime - frameTime) / filterStrength;
lastLoop = thisLoop;
requestAnimationFrame(setFPS);
}
function main() {
let frameFraction = 1 / fps;
fakeScrollTop += speed * frameFraction;
credits.scrollTop = Math.floor(fakeScrollTop);
if (credits.scrollTop >= credits.scrollTopMax) {
music.loop = false;
setTimeout(function () {
credits.style.overflowY = "auto";
credits.scrollTo(0, 0);
document.getElementsByClassName("spacer")[0].style.height = 0;
}, 2500);
} else {
requestAnimationFrame(main);
}
}
function startMain() {
document.getElementById("start").style.display = "none";
music.play();
setTimeout(function () {
requestAnimationFrame(main);
}, 500);
}
async function checkForAutoplay() {
try {
await silence.play();
// so if that works, just start the credits.
document.getElementById("start").style.display = "none";
startMain();
} catch (e) {
document.getElementById("start").style.display = "block";
console.error(e);
}
}
document.getElementById("start").onclick = startMain;
requestAnimationFrame(setFPS);
checkForAutoplay();
</script>

View file

@ -1,43 +0,0 @@
<?php
if (empty($_SESSION)) {
http_response_code(307);
header('Location: /signin?callback=/dashboard');
exit();
}
if (!$_SESSION['auth']) {
http_response_code(307);
header('Location: /signin?callback=/dashboard');
exit;
}
?>
<link rel='stylesheet' href='/styles/settings.css' />
<div id="settings_split">
<div id="mini_profile" class="left">
<div class="image_container" data-backgroundcolour="white">
<img src='<?= get_avatar_url($user['id']) ?>' />
</div>
<div class="texts">
<span class="displayname"><?= htmlspecialchars(get_display_name($user['id'], false)) ?></span>
<span class="id bcid"><?= format_bcid($user['id']) ?></span>
</div>
</div>
<div class='right tiles'>
<a href="/settings" class="tile">
<div class="wrapper"> <!-- SUPERIMPORTANTBECAUSE IM BAD AT CSS -->
<span class="fa-solid fa-cog icon"></span>
<span class="text">Settings</span>
</div>
</a>
<a href="/profile" class="tile">
<div class="wrapper"> <!-- SUPERIMPORTANTBECAUSE IM BAD AT CSS -->
<span class="fa-solid fa-id-card-clip icon"></span>
<span class="text">Profile</span>
</div>
</a>
</div>
</div>

View file

@ -1,26 +0,0 @@
<?php
// Functions for interacting with the database. Requires PDO is initialised at $pdo.
function db_execute($sql, $variables=[]) {
global $pdo;
$stmt = $pdo->prepare($sql);
$stmt->execute($variables);
return $stmt->fetch();
}
function db_execute_all($sql, $variables=[]) {
global $pdo;
$stmt = $pdo->prepare($sql);
$stmt->execute($variables);
return $stmt->fetchAll();
}
function db_query($sql) {
global $pdo;
return $pdo->query($sql);
}

View file

@ -1,41 +0,0 @@
<?php
$Parsedown = new ParsedownExtra();
// Loads the relevant file from /docs
$file_path = __DIR__ . $path;
/* If it's a dir, check for index.md
If it's a file.md, load it. */
// First check if the file exists as a directory
if (file_exists($file_path)) {
// Check if the index.md exists
if (file_exists($file_path . '/index.md')) {
// And if so, make that the file path.
$file_path .= "/index.md";
} else { // If not, 404.
http_response_code(404);
include("404.html");
include("footer.php");
die($file_path);
}
} elseif (file_exists($file_path . '.md')) { // Check if $file.md exists.
// And if so, make that the file path.
$file_path .= '.md';
} else { // now if not, just show the standard 404 page.
http_response_code(404);
include("404.html");
include("footer.php");
die($file_path);
}
echo $file_path;
echo "<br>";
$file = fopen($file_path, "r");
$file_contents = fread($file, filesize($file_path));
fclose($file);
echo $Parsedown->parse($file_contents);

View file

@ -1,17 +0,0 @@
# config.php
Here's all the variables in `config.php`:
| Variable | Description / Example |
|----------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `BASE_URL` | The url generated for emails. Should be "https://id.byecorps.com" in production. |
| `DB_ADDRESS` | The address for the database. Usually `localhost` |
| `DB_USERNAME` | Username for connecting to the database. |
| `DB_PASSWORD` | Password for the database. |
| `DB_DATABASE` | The database to connect to. |
| `PDO_OPTIONS` | `<br/>const PDO_OPTIONS = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false,];` |
| `DB_DSN` | `mysql:host='.DB_ADDRESS.';dbname='.DB_DATABASE.';charset=utf8mb4`, for PDO. |
| `SENTRY_DSN ` | Used for Sentry. |
| `MAIL_HOST` | SMTP host for emails |
| `MAIL_USERNAME` | SMTP username |
| `MAIL_PASSWORD` | SMTP password |

View file

@ -1,7 +0,0 @@
# Errors
Here's all the error codes and what they mean.
| Error Code | Explanation |
|-----------:|:----------------------------|
| 12 | A generic error explaing something went wrong adding a password reset

View file

@ -1,7 +0,0 @@
# Hosting
Here's everything you need to know about hosting ByeCorps ID. This mainly covers the `config.php` file.
## Contents
- [config.php](hosting/configphp)

View file

@ -1 +0,0 @@
# ByeCorps ID docs

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 B

View file

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 -0.5 16 16"
shape-rendering="crispEdges"
version="1.1"
id="svg1"
sodipodi:docname="favicon.svg"
width="16"
height="16"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="30.692308"
inkscape:cx="0.96115288"
inkscape:cy="9.8070175"
inkscape:window-width="1920"
inkscape:window-height="973"
inkscape:window-x="1920"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<metadata
id="metadata1">Made with Pixels to Svg https://codepen.io/shshaw/pen/XbxvNj</metadata>
<path
stroke="#000000"
d="m 4.0000001,0.16666691 h 1.3333334 m 1.3333334,0 h 2.6666667 m -4,1.33333329 H 6.6666669 M 4.0000001,2.8333335 H 11.999999 M 4.0000001,4.1666669 H 11.999999 M 4.0000001,5.5000002 H 11.999999 M 4.0000001,6.8333335 H 11.999999 M 4.0000001,9.5000002 H 11.999999 M 2.6666669,10.833333 H 13.333333 M 2.6666669,12.166667 H 13.333333 M 2.6666669,13.5 H 13.333333 M 2.6666669,14.833333 H 13.333333"
id="path1"
style="stroke-width:1.33333" />
<style
id="style1">@media (prefers-color-scheme:dark){:root{filter:invert(100%)}}</style>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

7955
fontawesome/css/all.css vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -1,19 +0,0 @@
/*!
* Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
:root, :host {
--fa-style-family-classic: 'Font Awesome 6 Free';
--fa-font-regular: normal 400 1em/1 'Font Awesome 6 Free'; }
@font-face {
font-family: 'Font Awesome 6 Free';
font-style: normal;
font-weight: 400;
font-display: block;
src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); }
.far,
.fa-regular {
font-weight: 400; }

View file

@ -1,6 +0,0 @@
/*!
* Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
:host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-weight:400}

View file

@ -1,19 +0,0 @@
/*!
* Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
:root, :host {
--fa-style-family-classic: 'Font Awesome 6 Free';
--fa-font-solid: normal 900 1em/1 'Font Awesome 6 Free'; }
@font-face {
font-family: 'Font Awesome 6 Free';
font-style: normal;
font-weight: 900;
font-display: block;
src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }
.fas,
.fa-solid {
font-weight: 900; }

View file

@ -1,6 +0,0 @@
/*!
* Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
:host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-weight:900}

View file

@ -1,639 +0,0 @@
/*!
* Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
:root, :host {
--fa-font-solid: normal 900 1em/1 'Font Awesome 6 Solid';
--fa-font-regular: normal 400 1em/1 'Font Awesome 6 Regular';
--fa-font-light: normal 300 1em/1 'Font Awesome 6 Light';
--fa-font-thin: normal 100 1em/1 'Font Awesome 6 Thin';
--fa-font-duotone: normal 900 1em/1 'Font Awesome 6 Duotone';
--fa-font-sharp-solid: normal 900 1em/1 'Font Awesome 6 Sharp';
--fa-font-sharp-regular: normal 400 1em/1 'Font Awesome 6 Sharp';
--fa-font-sharp-light: normal 300 1em/1 'Font Awesome 6 Sharp';
--fa-font-brands: normal 400 1em/1 'Font Awesome 6 Brands'; }
svg:not(:root).svg-inline--fa, svg:not(:host).svg-inline--fa {
overflow: visible;
box-sizing: content-box; }
.svg-inline--fa {
display: var(--fa-display, inline-block);
height: 1em;
overflow: visible;
vertical-align: -.125em; }
.svg-inline--fa.fa-2xs {
vertical-align: 0.1em; }
.svg-inline--fa.fa-xs {
vertical-align: 0em; }
.svg-inline--fa.fa-sm {
vertical-align: -0.07143em; }
.svg-inline--fa.fa-lg {
vertical-align: -0.2em; }
.svg-inline--fa.fa-xl {
vertical-align: -0.25em; }
.svg-inline--fa.fa-2xl {
vertical-align: -0.3125em; }
.svg-inline--fa.fa-pull-left {
margin-right: var(--fa-pull-margin, 0.3em);
width: auto; }
.svg-inline--fa.fa-pull-right {
margin-left: var(--fa-pull-margin, 0.3em);
width: auto; }
.svg-inline--fa.fa-li {
width: var(--fa-li-width, 2em);
top: 0.25em; }
.svg-inline--fa.fa-fw {
width: var(--fa-fw-width, 1.25em); }
.fa-layers svg.svg-inline--fa {
bottom: 0;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0; }
.fa-layers-text, .fa-layers-counter {
display: inline-block;
position: absolute;
text-align: center; }
.fa-layers {
display: inline-block;
height: 1em;
position: relative;
text-align: center;
vertical-align: -.125em;
width: 1em; }
.fa-layers svg.svg-inline--fa {
-webkit-transform-origin: center center;
transform-origin: center center; }
.fa-layers-text {
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
-webkit-transform-origin: center center;
transform-origin: center center; }
.fa-layers-counter {
background-color: var(--fa-counter-background-color, #ff253a);
border-radius: var(--fa-counter-border-radius, 1em);
box-sizing: border-box;
color: var(--fa-inverse, #fff);
line-height: var(--fa-counter-line-height, 1);
max-width: var(--fa-counter-max-width, 5em);
min-width: var(--fa-counter-min-width, 1.5em);
overflow: hidden;
padding: var(--fa-counter-padding, 0.25em 0.5em);
right: var(--fa-right, 0);
text-overflow: ellipsis;
top: var(--fa-top, 0);
-webkit-transform: scale(var(--fa-counter-scale, 0.25));
transform: scale(var(--fa-counter-scale, 0.25));
-webkit-transform-origin: top right;
transform-origin: top right; }
.fa-layers-bottom-right {
bottom: var(--fa-bottom, 0);
right: var(--fa-right, 0);
top: auto;
-webkit-transform: scale(var(--fa-layers-scale, 0.25));
transform: scale(var(--fa-layers-scale, 0.25));
-webkit-transform-origin: bottom right;
transform-origin: bottom right; }
.fa-layers-bottom-left {
bottom: var(--fa-bottom, 0);
left: var(--fa-left, 0);
right: auto;
top: auto;
-webkit-transform: scale(var(--fa-layers-scale, 0.25));
transform: scale(var(--fa-layers-scale, 0.25));
-webkit-transform-origin: bottom left;
transform-origin: bottom left; }
.fa-layers-top-right {
top: var(--fa-top, 0);
right: var(--fa-right, 0);
-webkit-transform: scale(var(--fa-layers-scale, 0.25));
transform: scale(var(--fa-layers-scale, 0.25));
-webkit-transform-origin: top right;
transform-origin: top right; }
.fa-layers-top-left {
left: var(--fa-left, 0);
right: auto;
top: var(--fa-top, 0);
-webkit-transform: scale(var(--fa-layers-scale, 0.25));
transform: scale(var(--fa-layers-scale, 0.25));
-webkit-transform-origin: top left;
transform-origin: top left; }
.fa-1x {
font-size: 1em; }
.fa-2x {
font-size: 2em; }
.fa-3x {
font-size: 3em; }
.fa-4x {
font-size: 4em; }
.fa-5x {
font-size: 5em; }
.fa-6x {
font-size: 6em; }
.fa-7x {
font-size: 7em; }
.fa-8x {
font-size: 8em; }
.fa-9x {
font-size: 9em; }
.fa-10x {
font-size: 10em; }
.fa-2xs {
font-size: 0.625em;
line-height: 0.1em;
vertical-align: 0.225em; }
.fa-xs {
font-size: 0.75em;
line-height: 0.08333em;
vertical-align: 0.125em; }
.fa-sm {
font-size: 0.875em;
line-height: 0.07143em;
vertical-align: 0.05357em; }
.fa-lg {
font-size: 1.25em;
line-height: 0.05em;
vertical-align: -0.075em; }
.fa-xl {
font-size: 1.5em;
line-height: 0.04167em;
vertical-align: -0.125em; }
.fa-2xl {
font-size: 2em;
line-height: 0.03125em;
vertical-align: -0.1875em; }
.fa-fw {
text-align: center;
width: 1.25em; }
.fa-ul {
list-style-type: none;
margin-left: var(--fa-li-margin, 2.5em);
padding-left: 0; }
.fa-ul > li {
position: relative; }
.fa-li {
left: calc(var(--fa-li-width, 2em) * -1);
position: absolute;
text-align: center;
width: var(--fa-li-width, 2em);
line-height: inherit; }
.fa-border {
border-color: var(--fa-border-color, #eee);
border-radius: var(--fa-border-radius, 0.1em);
border-style: var(--fa-border-style, solid);
border-width: var(--fa-border-width, 0.08em);
padding: var(--fa-border-padding, 0.2em 0.25em 0.15em); }
.fa-pull-left {
float: left;
margin-right: var(--fa-pull-margin, 0.3em); }
.fa-pull-right {
float: right;
margin-left: var(--fa-pull-margin, 0.3em); }
.fa-beat {
-webkit-animation-name: fa-beat;
animation-name: fa-beat;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);
animation-timing-function: var(--fa-animation-timing, ease-in-out); }
.fa-bounce {
-webkit-animation-name: fa-bounce;
animation-name: fa-bounce;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1)); }
.fa-fade {
-webkit-animation-name: fa-fade;
animation-name: fa-fade;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); }
.fa-beat-fade {
-webkit-animation-name: fa-beat-fade;
animation-name: fa-beat-fade;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); }
.fa-flip {
-webkit-animation-name: fa-flip;
animation-name: fa-flip;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);
animation-timing-function: var(--fa-animation-timing, ease-in-out); }
.fa-shake {
-webkit-animation-name: fa-shake;
animation-name: fa-shake;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, linear);
animation-timing-function: var(--fa-animation-timing, linear); }
.fa-spin {
-webkit-animation-name: fa-spin;
animation-name: fa-spin;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 2s);
animation-duration: var(--fa-animation-duration, 2s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, linear);
animation-timing-function: var(--fa-animation-timing, linear); }
.fa-spin-reverse {
--fa-animation-direction: reverse; }
.fa-pulse,
.fa-spin-pulse {
-webkit-animation-name: fa-spin;
animation-name: fa-spin;
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, steps(8));
animation-timing-function: var(--fa-animation-timing, steps(8)); }
@media (prefers-reduced-motion: reduce) {
.fa-beat,
.fa-bounce,
.fa-fade,
.fa-beat-fade,
.fa-flip,
.fa-pulse,
.fa-shake,
.fa-spin,
.fa-spin-pulse {
-webkit-animation-delay: -1ms;
animation-delay: -1ms;
-webkit-animation-duration: 1ms;
animation-duration: 1ms;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
-webkit-transition-delay: 0s;
transition-delay: 0s;
-webkit-transition-duration: 0s;
transition-duration: 0s; } }
@-webkit-keyframes fa-beat {
0%, 90% {
-webkit-transform: scale(1);
transform: scale(1); }
45% {
-webkit-transform: scale(var(--fa-beat-scale, 1.25));
transform: scale(var(--fa-beat-scale, 1.25)); } }
@keyframes fa-beat {
0%, 90% {
-webkit-transform: scale(1);
transform: scale(1); }
45% {
-webkit-transform: scale(var(--fa-beat-scale, 1.25));
transform: scale(var(--fa-beat-scale, 1.25)); } }
@-webkit-keyframes fa-bounce {
0% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); }
10% {
-webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);
transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); }
30% {
-webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));
transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); }
50% {
-webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);
transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); }
57% {
-webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));
transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); }
64% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); }
100% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); } }
@keyframes fa-bounce {
0% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); }
10% {
-webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);
transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); }
30% {
-webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));
transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); }
50% {
-webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);
transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); }
57% {
-webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));
transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); }
64% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); }
100% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); } }
@-webkit-keyframes fa-fade {
50% {
opacity: var(--fa-fade-opacity, 0.4); } }
@keyframes fa-fade {
50% {
opacity: var(--fa-fade-opacity, 0.4); } }
@-webkit-keyframes fa-beat-fade {
0%, 100% {
opacity: var(--fa-beat-fade-opacity, 0.4);
-webkit-transform: scale(1);
transform: scale(1); }
50% {
opacity: 1;
-webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));
transform: scale(var(--fa-beat-fade-scale, 1.125)); } }
@keyframes fa-beat-fade {
0%, 100% {
opacity: var(--fa-beat-fade-opacity, 0.4);
-webkit-transform: scale(1);
transform: scale(1); }
50% {
opacity: 1;
-webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));
transform: scale(var(--fa-beat-fade-scale, 1.125)); } }
@-webkit-keyframes fa-flip {
50% {
-webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));
transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); } }
@keyframes fa-flip {
50% {
-webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));
transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); } }
@-webkit-keyframes fa-shake {
0% {
-webkit-transform: rotate(-15deg);
transform: rotate(-15deg); }
4% {
-webkit-transform: rotate(15deg);
transform: rotate(15deg); }
8%, 24% {
-webkit-transform: rotate(-18deg);
transform: rotate(-18deg); }
12%, 28% {
-webkit-transform: rotate(18deg);
transform: rotate(18deg); }
16% {
-webkit-transform: rotate(-22deg);
transform: rotate(-22deg); }
20% {
-webkit-transform: rotate(22deg);
transform: rotate(22deg); }
32% {
-webkit-transform: rotate(-12deg);
transform: rotate(-12deg); }
36% {
-webkit-transform: rotate(12deg);
transform: rotate(12deg); }
40%, 100% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); } }
@keyframes fa-shake {
0% {
-webkit-transform: rotate(-15deg);
transform: rotate(-15deg); }
4% {
-webkit-transform: rotate(15deg);
transform: rotate(15deg); }
8%, 24% {
-webkit-transform: rotate(-18deg);
transform: rotate(-18deg); }
12%, 28% {
-webkit-transform: rotate(18deg);
transform: rotate(18deg); }
16% {
-webkit-transform: rotate(-22deg);
transform: rotate(-22deg); }
20% {
-webkit-transform: rotate(22deg);
transform: rotate(22deg); }
32% {
-webkit-transform: rotate(-12deg);
transform: rotate(-12deg); }
36% {
-webkit-transform: rotate(12deg);
transform: rotate(12deg); }
40%, 100% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); } }
@-webkit-keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
@keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
.fa-rotate-90 {
-webkit-transform: rotate(90deg);
transform: rotate(90deg); }
.fa-rotate-180 {
-webkit-transform: rotate(180deg);
transform: rotate(180deg); }
.fa-rotate-270 {
-webkit-transform: rotate(270deg);
transform: rotate(270deg); }
.fa-flip-horizontal {
-webkit-transform: scale(-1, 1);
transform: scale(-1, 1); }
.fa-flip-vertical {
-webkit-transform: scale(1, -1);
transform: scale(1, -1); }
.fa-flip-both,
.fa-flip-horizontal.fa-flip-vertical {
-webkit-transform: scale(-1, -1);
transform: scale(-1, -1); }
.fa-rotate-by {
-webkit-transform: rotate(var(--fa-rotate-angle, none));
transform: rotate(var(--fa-rotate-angle, none)); }
.fa-stack {
display: inline-block;
vertical-align: middle;
height: 2em;
position: relative;
width: 2.5em; }
.fa-stack-1x,
.fa-stack-2x {
bottom: 0;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
z-index: var(--fa-stack-z-index, auto); }
.svg-inline--fa.fa-stack-1x {
height: 1em;
width: 1.25em; }
.svg-inline--fa.fa-stack-2x {
height: 2em;
width: 2.5em; }
.fa-inverse {
color: var(--fa-inverse, #fff); }
.sr-only,
.fa-sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0; }
.sr-only-focusable:not(:focus),
.fa-sr-only-focusable:not(:focus) {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0; }
.svg-inline--fa .fa-primary {
fill: var(--fa-primary-color, currentColor);
opacity: var(--fa-primary-opacity, 1); }
.svg-inline--fa .fa-secondary {
fill: var(--fa-secondary-color, currentColor);
opacity: var(--fa-secondary-opacity, 0.4); }
.svg-inline--fa.fa-swap-opacity .fa-primary {
opacity: var(--fa-secondary-opacity, 0.4); }
.svg-inline--fa.fa-swap-opacity .fa-secondary {
opacity: var(--fa-primary-opacity, 1); }
.svg-inline--fa mask .fa-primary,
.svg-inline--fa mask .fa-secondary {
fill: black; }
.fad.fa-inverse,
.fa-duotone.fa-inverse {
color: var(--fa-inverse, #fff); }

File diff suppressed because one or more lines are too long

View file

@ -1,26 +0,0 @@
/*!
* Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
@font-face {
font-family: 'FontAwesome';
font-display: block;
src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }
@font-face {
font-family: 'FontAwesome';
font-display: block;
src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); }
@font-face {
font-family: 'FontAwesome';
font-display: block;
src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype");
unicode-range: U+F003,U+F006,U+F014,U+F016-F017,U+F01A-F01B,U+F01D,U+F022,U+F03E,U+F044,U+F046,U+F05C-F05D,U+F06E,U+F070,U+F087-F088,U+F08A,U+F094,U+F096-F097,U+F09D,U+F0A0,U+F0A2,U+F0A4-F0A7,U+F0C5,U+F0C7,U+F0E5-F0E6,U+F0EB,U+F0F6-F0F8,U+F10C,U+F114-F115,U+F118-F11A,U+F11C-F11D,U+F133,U+F147,U+F14E,U+F150-F152,U+F185-F186,U+F18E,U+F190-F192,U+F196,U+F1C1-F1C9,U+F1D9,U+F1DB,U+F1E3,U+F1EA,U+F1F7,U+F1F9,U+F20A,U+F247-F248,U+F24A,U+F24D,U+F255-F25B,U+F25D,U+F271-F274,U+F278,U+F27B,U+F28C,U+F28E,U+F29C,U+F2B5,U+F2B7,U+F2BA,U+F2BC,U+F2BE,U+F2C0-F2C1,U+F2C3,U+F2D0,U+F2D2,U+F2D4,U+F2DC; }
@font-face {
font-family: 'FontAwesome';
font-display: block;
src: url("../webfonts/fa-v4compatibility.woff2") format("woff2"), url("../webfonts/fa-v4compatibility.ttf") format("truetype");
unicode-range: U+F041,U+F047,U+F065-F066,U+F07D-F07E,U+F080,U+F08B,U+F08E,U+F090,U+F09A,U+F0AC,U+F0AE,U+F0B2,U+F0D0,U+F0D6,U+F0E4,U+F0EC,U+F10A-F10B,U+F123,U+F13E,U+F148-F149,U+F14C,U+F156,U+F15E,U+F160-F161,U+F163,U+F175-F178,U+F195,U+F1F8,U+F219,U+F27A; }

View file

@ -1,6 +0,0 @@
/*!
* Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -1,22 +0,0 @@
/*!
* Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
@font-face {
font-family: 'Font Awesome 5 Brands';
font-display: block;
font-weight: 400;
src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); }
@font-face {
font-family: 'Font Awesome 5 Free';
font-display: block;
font-weight: 900;
src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }
@font-face {
font-family: 'Font Awesome 5 Free';
font-display: block;
font-weight: 400;
src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); }

View file

@ -1,6 +0,0 @@
/*!
* Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
@font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}

View file

@ -1,3 +0,0 @@
<footer>
&COPY; ByeCorps <?php echo(date("Y")); ?> <a href="/credits">Credits</a>
</footer>

View file

@ -1,53 +0,0 @@
<?php
if ($_SESSION['auth']) {
header('Location: /account');
}
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$message = "We've sent an email to that inbox if we find an associated account.";
$sql = "SELECT * FROM accounts WHERE email = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$_POST['email']]);
$user = $stmt->fetch();
if ($user != null) { // account exists
// create a password reset
$password_reset_link = create_password_reset($user['id']);
$safe_display_name = get_display_name($user['id'], use_bcid_fallback: true);
try {
$resend->emails->send([
'from' => 'ByeCorps ID <noreply@id.byecorps.com>',
'to' => [$safe_display_name . "<" . $user['email']. ">"],
'subject' => 'Reset your password',
'text' => 'Hey there '.$safe_display_name.'! Here is that password reset you requested. Just click the following link and you\'ll be sorted:
'.$password_reset_link.'
This link expires in 5 minutes.
If you did not request this password reset, please ignore this email.']);
// echo("<a href='$password_reset_link'>This is a security issue.</a>");
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: $e";
}
}
}
?>
<h1>Forgot password</h1>
<?php if(isset($message)) echo "<p>".$message."</p>"; ?>
<p>Forgot your password? We'll email you to reset it.</p>
<form method="post">
<input placeholder="a.dent@squornshellous.cloud" name="email" id="email" type="email">
<button type="submit">Request password reset</button>
</form>

View file

@ -1,21 +0,0 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script
src="https://js.sentry-cdn.com/15d71a72983891268a3298cdc2bd1498.min.js"
crossorigin="anonymous"
></script>
<title><?php if (isset($doc_title)) { echo $doc_title." | "; } ?>ByeCorps ID</title>
<link rel="shortcut icon" href="/favicon.svg" type="image/svg" />
<link rel="manifest" href="manifest.json" />
<!-- 0_o -->
<link rel="apple-touch-icon" href="/assets/icons/apple-icon-180.png">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="stylesheet" href="/styles/global.css" />
<link rel="stylesheet" href="/fontawesome/css/all.css" />

View file

@ -1,40 +0,0 @@
<!-- This is a testing file for the header used on BCID. Copy of header on ByeCorps.com -->
<?php
if (!$_SESSION['auth']) goto skip_auth;
if ($_SESSION['auth']) {
$sql = "SELECT display_name FROM accounts WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$_SESSION['id']]);
$name = $stmt->fetchColumn();
}
if (empty($name)) {
$name = '<code class=bcid>'.format_bcid($_SESSION['id']).'</code>';
}
skip_auth:
?>
<header>
<div class="start">
<a href="/" id="sitetitle">
<span class="bc-1">Bye</span><span class="bc-2">Corps</span><span class="bc-3"> ID</span>
</a></div>
<div class="end">
<?php if (!$_SESSION['auth']) goto signed_out; ?>
<?php if ($user['is_admin']) echo "<a href='/admin'>Admin panel</a>"; ?>
<div class="loggedin">
<a href="/account" class="account">Hey there, <?= $name ?>!</a>
</div>
<?php signed_out: ?>
</div>
</header>

View file

@ -1,32 +0,0 @@
<?php
function generate_bcid() {
$CHARS = str_split("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
return $CHARS[array_rand($CHARS)].$CHARS[array_rand($CHARS)].$CHARS[array_rand($CHARS)].$CHARS[array_rand($CHARS)].$CHARS[array_rand($CHARS)].$CHARS[array_rand($CHARS)].$CHARS[array_rand($CHARS)];
}
function validate_bcid($bcid) {
$stripped_bcid = str_replace([" ", "-"], "", $bcid);
$stripped_bcid = strtoupper($stripped_bcid);
if (!preg_match('/^[^A-Z^0-9]^/', $stripped_bcid) && strlen($stripped_bcid) == 7) {
return 1;
}
return 0; // fail condition
}
function format_bcid ($bcid) { // Formats to XXX-XXXX
$stripped_bcid = str_replace([' ','-'], '', $bcid);
$stripped_bcid = strtoupper($stripped_bcid);
if (!validate_bcid($stripped_bcid)) {
throw new Exception('Invalid BCID.');
}
return substr($stripped_bcid, 0, 3).'-'.substr($stripped_bcid, -4, 4);
}
$BCID = generate_bcid();
?>

View file

@ -1,17 +0,0 @@
<?php
if (array_key_exists(2, $uri)) {
$avatar_links = db_execute('SELECT public FROM avatars WHERE id = ? LIMIT 1', [$uri[2]]);
if (empty($avatar_links)) {
$fp = fopen('./assets/default.png', 'rb');
} else {
$fp = fopen(DATA_LOCATION . $avatar_links['public'], 'rb');
}
header("Content-Type: image/png");
header("Content-Length: " . filesize(DATA_LOCATION . $avatar_links['public']));
fpassthru($fp);
exit;
}

216
index.php
View file

@ -1,216 +0,0 @@
<?php
require_once __DIR__ . '/vendor/autoload.php';
session_start();
error_reporting(E_ERROR | E_WARNING | E_PARSE);
if (empty($_SESSION)) {
$_SESSION['auth'] = false;
}
include "config.php";
// MySQL
$pdo = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD, PDO_OPTIONS);
// Email
if (defined("RESEND_API_KEY")) {
$resend = Resend::client(RESEND_API_KEY);
}
require "misc_functions.php";
require "database.php";
include("time_handler.php");
include("id_handler.php");
include("accounts_handler.php");
// Attempt to log the user in using their cookie if auth isn't set.
if (!$_SESSION['auth']) {
if (key_exists('keep_me_logged_in', $_COOKIE)) {
if (validate_access_token($_COOKIE['keep_me_logged_in'])) {
// Work out who the key belongs to
$cookie_owner = db_execute("SELECT * FROM tokens WHERE access_token = ?", [$_COOKIE['keep_me_logged_in']]);
if ($cookie_owner['type'] != "cookie") {
setcookie('keep_me_logged_in', '', time()-3600);
goto skip_cookie;
}
$_SESSION['auth'] = true;
$_SESSION['id'] = $cookie_owner['owner_id'];
} else {
setcookie('keep_me_logged_in', '', time()-3600);
}
}
}
skip_cookie:
$host_string = $_SERVER['HTTP_HOST'];
$host = explode('.', $host_string);
$uri_string = $_SERVER['REQUEST_URI'];
$query_string = explode('?', $uri_string);
$path = $query_string[0];
if (str_ends_with($path,'/') && $path != "/") {
header('Location: '.substr($path,0, -1));
exit;
}
$uri = array_values(array_filter(explode('/', $uri_string)));
try {
if ($_SESSION['auth']) {
$user = db_execute("SELECT * FROM `accounts` WHERE id = ? LIMIT 1", [$_SESSION['id']]);
if (!$user) {
// Account doesn't exist. Log the user out.
// We won't redirect to the logout endpoint because if this is going off there's something
// broken anyway.
session_destroy();
die("Your session was invalid so we've logged you out.");
}
}
}
catch (Exception) {
echo('<header>Database is broken. Please tell an admin.</header>');
if ($uri_string == "/admin/init/database") { // Allows access to this page even if user doesn't have admin rights
// because you can't check the rights.
echo "<main>";
include "admin_initdatabase.php";
die ("</main>");
}
}
if (defined("SENTRY_DSN")) {
\Sentry\init([
'dsn' => SENTRY_DSN,
// Specify a fixed sample rate
'traces_sample_rate' => 1.0,
// Set a sampling rate for profiling - this is relative to traces_sample_rate
'profiles_sample_rate' => 1.0,
]);
}
function does_variable_exists( $variable ) {
return (isset($$variable)) ? "true" : "false";
}
if(isset($query_string[1])) {
$uri_string = $query_string[0];
$query_string = explode('&', $query_string[1]);
$query = array();
foreach($query_string as $string) {
$bits = explode('=', $string);
$query[$bits[0]] = $bits[1];
}
}
else {
$query = array();
}
$include = "404.html";
// routing
$paths = array(
"/" => ["landing.php"],
"/admin" => ['admin.php'],
"/admin/init/database" => ["admin_initdatabase.php"],
"/admin/list/accounts" => ["admin_accounts.php"],
"/admin/list/apps" => ["admin_apps.php"],
"/admin/create/app" => ["admin_apps_create.php"],
"/admin/create/token" => ["admin_create_token.php"],
"/admin/signinas" => ["signinas.php"],
"/admin/purge" => ["admin_purge.php"],
// Settings
"/dashboard" => ["dashboard.php", "Dashboard"],
"/settings" => ["settings.php", "Settings"],
"/settings/account" => ["settings_account.php", "Settings -> Account"],
"/account" => ["account.php", "Your account"],
"/signin" => ["signin.php", "Sign in"],
"/signup" => ["signup.php", "Sign up"],
"/signout" => ["signout.php", "Signed out"],
"/forgot/password" => ["forgot_password.php", "Forgot password"],
"/reset/password" => ["reset_password.php", "Reset password"],
"/docs" => ["docs.php", "Docs"],
"/credits" => ["credits.php", "Credits"],
"/profile" => ["profile.php", "Profile"],
"/signin/external/basic" => ["login_external_basic.php"]
);
if (!empty($uri) ) { // Go to jail. Go directly to jail. Do not pass Go.
if ($uri[0] == "api") {
include("api_handler.php");
exit(); // fuck this shit i'm out
}
if ($uri[0] == "public" && $uri[1] == "avatars") {
include("image_grabber.php");
exit();
}
}
$migrated = false;
if (isset($paths[$path])) {
$include = $paths[$path][0];
if (isset($paths[$path][1])) {
$doc_title = $paths[$path][1];
}
if (isset($paths[$path][2])) {
$migrated = $paths[$path][2];
}
}
else {
$doc_title = "404";
http_response_code(404);
}
if ($migrated) {
$output = "";
include($include);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<?php include("head.php"); ?>
</head>
<body>
<?php include("header.php"); ?>
<main>
<?php
if (!empty($uri)) {
// print_r ($uri);
if ($uri[0] == "admin") {
echo "<h2 class=\"subheading\">Admin</h2>";
}
if ($uri[0] == "admin" && !$user['is_admin']) {
http_response_code(401);
die("<img src='https://http.cat/401.jpg' alt='A cat standing in front of a door with a No Cats Allowed sign on it.' />");
}
if ($uri[0] == "docs") {
$include = "docs.php";
}
}
if ($migrated) {
echo $output;
}
else {
include ($include);
}
?>
</main>
<?php include("footer.php"); ?>
</body>
</html>

View file

@ -1,38 +0,0 @@
<?php
if (isset($_GET['new_landing'])) {
goto new_landing;
}
?>
<div class="hero">
<div class="hero-text">
<img src="/assets/bcid.svg" alt="ByeCorps ID Logo" class="logo">
<h1><span class="bc-1">Bye</span><span class="bc-2">Corps</span><span class="bc-3"> ID</span></h1>
<p>Log into ByeCorps and beyond with a single ID.</p>
<!-- <p><input type="email" name="loginEmail" id="loginEmail" placeholder="Email" /></p> -->
<?php
if ( $_SESSION['auth']) { echo "<a href='/account' class='button primary'>Manage account</a>"; }
else { echo "<a href='/signin' class='button primary'>Sign in</a><a href='/signup' class='button'>Create an account</a>"; }
?>
</div>
</div>
<?php
exit;
new_landing:
?>
<div class="hero">
<div class="hero-text">
<img src="/assets/bcid.svg" alt="ByeCorps ID Logo" class="logo">
<h1><span class="bc-1">Bye</span><span class="bc-2">Corps</span><span class="bc-3"> ID</span></h1>
<p>Log into ByeCorps and beyond with a single ID.</p>
</div>

Some files were not shown because too many files have changed in this diff Show more