summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/nginx/site.conf34
-rw-r--r--src/db/rest/rest.sql1
-rw-r--r--src/db/rest/user/api_update_password.sql44
-rw-r--r--src/db/rest/user/api_user_update.sql20
-rw-r--r--src/public/css/home.css2
-rw-r--r--src/web/_views/apps/settings/main.php48
-rw-r--r--src/web/_views/modal/about.php7
-rw-r--r--src/web/lang/Makefile19
-rwxr-xr-xsrc/web/lang/_bin/transpile.sh30
-rw-r--r--src/web/lang/en_US/api_lang.php1
-rw-r--r--src/web/lang/en_US/apps/settings.php6
-rw-r--r--src/web/lang/en_US/common_lang.php2
12 files changed, 109 insertions, 105 deletions
diff --git a/conf/nginx/site.conf b/conf/nginx/site.conf
index ed9bff0..04c75ca 100644
--- a/conf/nginx/site.conf
+++ b/conf/nginx/site.conf
@@ -30,41 +30,13 @@ server {
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml image/x-icon;
location /api/ {
-
- if ($request_method = 'OPTIONS') {
- add_header 'Access-Control-Allow-Origin $http_origin' always;
- # Om nom nom cookies
- add_header 'Access-Control-Allow-Credentials' 'true';
- add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
- # Custom headers and headers various browsers *should* be OK with but aren't
- add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
- # Tell client that this pre-flight info is valid for 20 days
- add_header 'Access-Control-Max-Age' 1728000;
- add_header 'Content-Type' 'text/plain charset=UTF-8';
- add_header 'Content-Length' 0;
- return 204;
- }
-
- if ($request_method = 'POST') {
- add_header 'Access-Control-Allow-Origin $http_origin' always;
- add_header 'Access-Control-Allow-Credentials' 'true';
- add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
- add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
- }
-
- if ($request_method = 'GET') {
- add_header 'Access-Control-Allow-Origin $http_origin' always;
- add_header 'Access-Control-Allow-Credentials' 'true';
- add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
- add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
- }
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header Accept-Encoding "";
proxy_redirect off;
default_type application/json;
+ add_header 'Access-Control-Allow-Origin' '*';
add_header Content-Location /api/$upstream_http_content_location;
proxy_set_header Connection "";
proxy_http_version 1.1;
@@ -72,21 +44,25 @@ server {
}
location /apidocs {
+ add_header 'Access-Control-Allow-Origin' '*';
proxy_http_version 1.1;
proxy_pass http://swagger;
}
location /favicon.ico {
+ add_header 'Access-Control-Allow-Origin' '*';
root /opt/xssbook/public;
add_header Cache-Control "public, max-age=108000";
}
location /public {
+ add_header 'Access-Control-Allow-Origin' '*';
try_files $uri =404;
add_header Cache-Control "public, max-age=108000";
}
location / {
+ add_header 'Access-Control-Allow-Origin' '*';
root /opt/xssbook/web;
include fastcgi_params;
fastcgi_pass php:9000;
diff --git a/src/db/rest/rest.sql b/src/db/rest/rest.sql
index 2b71ebe..6c3fb7d 100644
--- a/src/db/rest/rest.sql
+++ b/src/db/rest/rest.sql
@@ -26,6 +26,7 @@ GRANT USAGE ON SCHEMA _api TO rest_anon, rest_user;
\i /db/rest/user/api_user_insert.sql;
\i /db/rest/user/api_user_update.sql;
\i /db/rest/user/api_user_delete.sql;
+\i /db/rest/user/api_update_password.sql;
-- post
\i /db/rest/post/api_post.sql;
diff --git a/src/db/rest/user/api_update_password.sql b/src/db/rest/user/api_update_password.sql
new file mode 100644
index 0000000..34cc1ac
--- /dev/null
+++ b/src/db/rest/user/api_update_password.sql
@@ -0,0 +1,44 @@
+CREATE FUNCTION api.update_password(
+ current_password TEXT,
+ new_password TEXT
+)
+RETURNS void
+LANGUAGE plpgsql VOLATILE
+AS $BODY$
+DECLARE
+ _user_id INTEGER;
+ _real_password TEXT;
+BEGIN
+ _user_id = _api.get_user_id();
+
+ PERFORM _api.validate_text(
+ _text => new_password,
+ _column => 'password',
+ _min => 1,
+ _max => 256
+ );
+
+ SELECT password
+ INTO _real_password
+ FROM admin.user
+ WHERE id = _user_id;
+
+ IF _real_password <> current_password THEN
+ PERFORM _api.raise(
+ _msg => 'api_invalid_password'
+ );
+ END IF;
+
+ UPDATE
+ admin.user
+ SET
+ "password" = new_password
+ WHERE
+ id = _user_id;
+END
+$BODY$;
+
+GRANT EXECUTE ON FUNCTION api.update_password(TEXT, TEXT)
+ TO rest_user;
+GRANT SELECT, UPDATE ON TABLE admin.user
+ TO rest_user;
diff --git a/src/db/rest/user/api_user_update.sql b/src/db/rest/user/api_user_update.sql
index 2e7cd50..c26c680 100644
--- a/src/db/rest/user/api_user_update.sql
+++ b/src/db/rest/user/api_user_update.sql
@@ -32,25 +32,6 @@ BEGIN
_changed = TRUE;
END IF;
- -- password
- SELECT password
- INTO OLD.password
- FROM admin.user
- WHERE id = OLD.id;
-
- NEW.password = COALESCE(NEW.password, OLD.password);
- NEW.password := _api.trim(NEW.password);
- PERFORM _api.validate_text(
- _text => NEW.password,
- _column => 'password',
- _min => 1,
- _max => 256
- );
-
- IF NEW.password IS DISTINCT FROM OLD.password THEN
- _changed = TRUE;
- END IF;
-
-- first name
NEW.first_name = COALESCE(NEW.first_name, OLD.first_name);
NEW.first_name := _api.trim(NEW.first_name);
@@ -138,7 +119,6 @@ BEGIN
IF _changed THEN
UPDATE admin.user SET
username = NEW.username,
- password = NEW.password,
first_name = NEW.first_name,
last_name = NEW.last_name,
middle_name = NEW.middle_name,
diff --git a/src/public/css/home.css b/src/public/css/home.css
index 3fdc381..40e1063 100644
--- a/src/public/css/home.css
+++ b/src/public/css/home.css
@@ -13,7 +13,7 @@
font-size: 1.5rem;
margin: 1rem 0;
width: 100%;
- height: 70%;
+ height: 10rem;
flex-grow: 1;
background-color: transparent;
color: var(--text);
diff --git a/src/web/_views/apps/settings/main.php b/src/web/_views/apps/settings/main.php
index 0cdc4f2..00c1601 100644
--- a/src/web/_views/apps/settings/main.php
+++ b/src/web/_views/apps/settings/main.php
@@ -54,6 +54,23 @@ function handleSubmit(e) {
}
+function handlePassword(e) {
+ e.preventDefault();
+ let el = e.target.elements;
+ let curr = el.curr_password.value;
+ let newp = el.new_password.value;
+
+ $.ajax({
+ url: '/api/rpc/update_password',
+ method: 'POST',
+ data: JSON.stringify({
+ new_password: newp,
+ current_password: curr
+ }),
+ success: onSuccess
+ })
+}
+
const toBase64 = file => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
@@ -111,6 +128,37 @@ function resetMedia(media_type) {
<?=__create_form($user, 'last_name')?>
<?=__create_form($user, 'gender')?>
<hr class="mt">
+ <h2><?=ucfirst(lang('security_title'))?></h2>
+ <strong><?=ucfirst(lang('security_desc'))?></strong>
+ <form action="" class="col mt settings-form" onsubmit="handlePassword(event)">
+ <div class="rel mb" style="flex: 1">
+ <input
+ type="password"
+ name="curr_password"
+ id="curr_password"
+ placeholder=" "
+ >
+ <label for="curr_password">
+ <?=ucwords(lang('ph_current_pass'))?>
+ </label>
+ </div>
+ <div class="rel mb" style="flex: 1">
+ <input
+ type="password"
+ name="new_password"
+ id="new_password"
+ placeholder=" "
+ >
+ <label for="new_password">
+ <?=ucwords(lang('ph_new_pass'))?>
+ </label>
+ </div>
+ <button
+ class="btn btn-wide btn-submit"
+ style="flex: 0; height: fit-content;"
+ ><?=lang('update')?></button>
+ </form>
+ <hr class="mt">
<h2><?=ucfirst(lang('media_title'))?></h2>
<strong><?=ucfirst(lang('media_desc'))?></strong>
<h3><?=ucfirst(lang('ph_avatar'))?></h3>
diff --git a/src/web/_views/modal/about.php b/src/web/_views/modal/about.php
index 746607e..d434908 100644
--- a/src/web/_views/modal/about.php
+++ b/src/web/_views/modal/about.php
@@ -2,11 +2,10 @@
<?php /* vi: syntax=php */ ?>
<div id="about-modal-body">
<span class="logo">xssbook</span>
- <hr>
<span class="mb"><?=ucfirst(lang('version'))?></span>
<span><?=ucfirst(lang('copyright'))?></span>
- <hr>
- <a class="btn btn-blue" href="https://g.freya.cat/freya/xssbook2">Source Code</a>
+ <a class="btn btn-blue mt" href="https://g.freya.cat/freya/xssbook2">Source Code</a>
+ <p>For reports of abuse, please email <a class="btn-blue" href="mailto:contact@freyacat.org">contact@freyacat.org</a></p>
</div>
<style>
#about-modal-body {
@@ -15,8 +14,6 @@
flex-direction: column;
justify-content: center;
align-items: center;
- font-weight: bold;
- font-size: 1.1rem;
padding: 1rem;
}
#about-modal-body .logo {
diff --git a/src/web/lang/Makefile b/src/web/lang/Makefile
deleted file mode 100644
index fd4ca9c..0000000
--- a/src/web/lang/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# en_CAT generator from en_US
-# uwuify and awk required
-#
-
-LANG_SRC = $(shell find en_US -type f)
-LANG_OBJ = $(patsubst en_US/%,en_CAT/%,$(LANG_SRC))
-
-.PHONY: all
-
-all: $(LANG_OBJ)
-
-$(LANG_OBJ): en_CAT/% : en_US/%
- @printf "\033[35m UWU \033[0m%s\n" $<
- @mkdir -p $(@D)
- @./_bin/transpile.sh $< $@
-
-clean:
- @rm -fr "en_CAT"
diff --git a/src/web/lang/_bin/transpile.sh b/src/web/lang/_bin/transpile.sh
deleted file mode 100755
index 36cd226..0000000
--- a/src/web/lang/_bin/transpile.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env bash
-
-lang_part() {
- echo "$1" | awk "{split(\$0,a,\" = \"); print a[$2]}"
-}
-export -f lang_part
-
-handle_line() {
- line="$1"
- left=$(lang_part "$line" 1)
- right=$(lang_part "$line" 2)
- echo "$left" | grep -Ev '_content|_line' > /dev/null
- code=$?
- if [ $code -eq 0 ]; then
- right=$(echo "$right" | uwuify)
- fi;
- right=${right%;};
- echo "$left = $right;"
-}
-export -f handle_line
-
-transpile() {
- file="$1"
- out="$2"
- printf "" > "$out"
- printf "<?php /* Copyright (c) 2024 Freya Murphy */\n\n" > "$out";
- grep "\$lang" < "$file" | xargs -n1 -I{} bash -c 'handle_line "$@"' _ {} >> "$out"
-}
-
-transpile "$1" "$2"
diff --git a/src/web/lang/en_US/api_lang.php b/src/web/lang/en_US/api_lang.php
index 3afc4f6..bc118dd 100644
--- a/src/web/lang/en_US/api_lang.php
+++ b/src/web/lang/en_US/api_lang.php
@@ -24,6 +24,7 @@ $lang['api_unique_value'] = '%s is not available (not unique)';
$lang['api_min_value'] = '%s length cannot be less than %s';
$lang['api_max_value'] = '%s length cannot exceed %s';
$lang['api_invalid_login'] = 'Invalid username or password';
+$lang['api_invalid_password'] = 'Invalid password';
$lang['api_unknown'] = 'An unknown error as occurred';
// toast messages
diff --git a/src/web/lang/en_US/apps/settings.php b/src/web/lang/en_US/apps/settings.php
index 2fca197..06796df 100644
--- a/src/web/lang/en_US/apps/settings.php
+++ b/src/web/lang/en_US/apps/settings.php
@@ -7,11 +7,17 @@ $lang['settings_success'] = 'Updated successfully';
$lang['general_title'] = 'Account Information';
$lang['general_desc'] = 'Modify your general account information.';
+$lang['security_title'] = 'Account Security';
+$lang['security_desc'] = 'Modify your account authentication information.';
+
$lang['media_title'] = 'Account Media';
$lang['media_desc'] = 'Modify your profiles avatar and banner.';
$lang['ph_avatar'] = 'Avatar';
$lang['ph_banner'] = 'Banner';
+$lang['ph_current_pass'] = 'Current Password';
+$lang['ph_new_pass'] = 'New Passowrd';
+
$lang['update'] = 'Update';
$lang['reset'] = 'Reset';
diff --git a/src/web/lang/en_US/common_lang.php b/src/web/lang/en_US/common_lang.php
index 771b20f..1d6a3e1 100644
--- a/src/web/lang/en_US/common_lang.php
+++ b/src/web/lang/en_US/common_lang.php
@@ -1,6 +1,6 @@
<?php /* Copyright (c) 2024 Freya Murphy */
-$lang['version'] = 'Version 2.0.3';
+$lang['version'] = 'Version 2.0.4';
$lang['copyright'] = 'Freya Murphy © 2024';
// Navigation Bar Lang