|
@@ -14,47 +14,47 @@ const OPTIONS_PASSWORD = [
|
|
'threads' => 64,
|
|
'threads' => 64,
|
|
];
|
|
];
|
|
|
|
|
|
-function checkUsernameFormat($username) {
|
|
|
|
|
|
+function checkUsernameFormat(string $username): void {
|
|
if (preg_match('/' . USERNAME_REGEX . '/Du', $username) !== 1)
|
|
if (preg_match('/' . USERNAME_REGEX . '/Du', $username) !== 1)
|
|
output(403, 'Username malformed.');
|
|
output(403, 'Username malformed.');
|
|
}
|
|
}
|
|
|
|
|
|
-function checkPasswordFormat($password) {
|
|
|
|
|
|
+function checkPasswordFormat(string $password): void {
|
|
if (preg_match('/' . PASSWORD_REGEX . '/Du', $password) !== 1)
|
|
if (preg_match('/' . PASSWORD_REGEX . '/Du', $password) !== 1)
|
|
output(403, 'Password malformed.');
|
|
output(403, 'Password malformed.');
|
|
}
|
|
}
|
|
|
|
|
|
-function hashUsername($username) {
|
|
|
|
|
|
+function hashUsername(string $username): string {
|
|
return base64_encode(sodium_crypto_pwhash(32, $username, hex2bin(query('select', 'params', ['name' => 'username_salt'], 'value')[0]), 2**10, 2**14, SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13));
|
|
return base64_encode(sodium_crypto_pwhash(32, $username, hex2bin(query('select', 'params', ['name' => 'username_salt'], 'value')[0]), 2**10, 2**14, SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13));
|
|
}
|
|
}
|
|
|
|
|
|
-function hashPassword($password) {
|
|
|
|
|
|
+function hashPassword(string $password): string {
|
|
return password_hash($password, ALGO_PASSWORD, OPTIONS_PASSWORD);
|
|
return password_hash($password, ALGO_PASSWORD, OPTIONS_PASSWORD);
|
|
}
|
|
}
|
|
|
|
|
|
-function usernameExists($username) {
|
|
|
|
|
|
+function usernameExists(string $username): bool {
|
|
return isset(query('select', 'users', ['username' => $username], 'id')[0]);
|
|
return isset(query('select', 'users', ['username' => $username], 'id')[0]);
|
|
}
|
|
}
|
|
|
|
|
|
-function checkPassword($id, $password) {
|
|
|
|
|
|
+function checkPassword(string $id, string $password): bool {
|
|
return password_verify($password, query('select', 'users', ['id' => $id], 'password')[0]);
|
|
return password_verify($password, query('select', 'users', ['id' => $id], 'password')[0]);
|
|
}
|
|
}
|
|
|
|
|
|
-function outdatedPasswordHash($id) {
|
|
|
|
|
|
+function outdatedPasswordHash(string $id): bool {
|
|
return password_needs_rehash(query('select', 'users', ['id' => $id], 'password')[0], ALGO_PASSWORD, OPTIONS_PASSWORD);
|
|
return password_needs_rehash(query('select', 'users', ['id' => $id], 'password')[0], ALGO_PASSWORD, OPTIONS_PASSWORD);
|
|
}
|
|
}
|
|
|
|
|
|
-function changePassword($id, $password) {
|
|
|
|
|
|
+function changePassword(string $id, string $password): void {
|
|
DB->prepare('UPDATE users SET password = :password WHERE id = :id')
|
|
DB->prepare('UPDATE users SET password = :password WHERE id = :id')
|
|
->execute([':password' => hashPassword($password), ':id' => $id]);
|
|
->execute([':password' => hashPassword($password), ':id' => $id]);
|
|
}
|
|
}
|
|
|
|
|
|
-function stopSession() {
|
|
|
|
|
|
+function stopSession(): void {
|
|
if (session_status() === PHP_SESSION_ACTIVE)
|
|
if (session_status() === PHP_SESSION_ACTIVE)
|
|
session_destroy();
|
|
session_destroy();
|
|
}
|
|
}
|
|
|
|
|
|
-function logout() {
|
|
|
|
|
|
+function logout(): never {
|
|
stopSession();
|
|
stopSession();
|
|
|
|
|
|
header('Clear-Site-Data: "*"');
|
|
header('Clear-Site-Data: "*"');
|
|
@@ -62,7 +62,7 @@ function logout() {
|
|
redir();
|
|
redir();
|
|
}
|
|
}
|
|
|
|
|
|
-function setupDisplayUsername($display_username) {
|
|
|
|
|
|
+function setupDisplayUsername(string $display_username): void {
|
|
$nonce = random_bytes(24);
|
|
$nonce = random_bytes(24);
|
|
$key = sodium_crypto_aead_xchacha20poly1305_ietf_keygen();
|
|
$key = sodium_crypto_aead_xchacha20poly1305_ietf_keygen();
|
|
$cyphertext = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
|
|
$cyphertext = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
|
|
@@ -87,7 +87,7 @@ function setupDisplayUsername($display_username) {
|
|
$_SESSION['display-username-cyphertext'] = $cyphertext;
|
|
$_SESSION['display-username-cyphertext'] = $cyphertext;
|
|
}
|
|
}
|
|
|
|
|
|
-function authDeleteUser($user_id) {
|
|
|
|
|
|
+function authDeleteUser(string $user_id): void {
|
|
$user_services = explode(',', query('select', 'users', ['id' => $user_id], 'services')[0]);
|
|
$user_services = explode(',', query('select', 'users', ['id' => $user_id], 'services')[0]);
|
|
|
|
|
|
foreach (SERVICES_USER as $service)
|
|
foreach (SERVICES_USER as $service)
|
|
@@ -138,7 +138,7 @@ function authDeleteUser($user_id) {
|
|
query('delete', 'users', ['id' => $user_id]);
|
|
query('delete', 'users', ['id' => $user_id]);
|
|
}
|
|
}
|
|
|
|
|
|
-function rateLimit() {
|
|
|
|
|
|
+function rateLimit(): void {
|
|
if (PAGE_METADATA['tokens_account_cost'] ?? 0 > 0)
|
|
if (PAGE_METADATA['tokens_account_cost'] ?? 0 > 0)
|
|
rateLimitAccount(PAGE_METADATA['tokens_account_cost']);
|
|
rateLimitAccount(PAGE_METADATA['tokens_account_cost']);
|
|
|
|
|
|
@@ -147,7 +147,7 @@ function rateLimit() {
|
|
}
|
|
}
|
|
|
|
|
|
const MAX_ACCOUNT_TOKENS = 86400;
|
|
const MAX_ACCOUNT_TOKENS = 86400;
|
|
-function rateLimitAccount($requestedTokens) {
|
|
|
|
|
|
+function rateLimitAccount(int $requestedTokens): int {
|
|
// Get
|
|
// Get
|
|
$userData = query('select', 'users', ['id' => $_SESSION['id']]);
|
|
$userData = query('select', 'users', ['id' => $_SESSION['id']]);
|
|
$tokens = $userData[0]['bucket_tokens'];
|
|
$tokens = $userData[0]['bucket_tokens'];
|
|
@@ -174,7 +174,7 @@ function rateLimitAccount($requestedTokens) {
|
|
return $tokens;
|
|
return $tokens;
|
|
}
|
|
}
|
|
|
|
|
|
-function rateLimitInstance($requestedTokens) {
|
|
|
|
|
|
+function rateLimitInstance(int $requestedTokens): void {
|
|
// Get
|
|
// Get
|
|
$tokens = query('select', 'params', ['name' => 'instance_bucket_tokens'], 'value')[0];
|
|
$tokens = query('select', 'params', ['name' => 'instance_bucket_tokens'], 'value')[0];
|
|
$bucketLastUpdate = query('select', 'params', ['name' => 'instance_bucket_last_update'], 'value')[0];
|
|
$bucketLastUpdate = query('select', 'params', ['name' => 'instance_bucket_last_update'], 'value')[0];
|