forked from AbleOS/holey-bytes
fixing js errors, adding password change form
This commit is contained in:
parent
e89511b14c
commit
f3879cb013
|
@ -44,8 +44,8 @@ async function getFmtInstance() {
|
|||
return fmtInstance ??= (await fmtInstaceFuture).instance;
|
||||
}
|
||||
|
||||
/** @param {WebAssembly.Instance} instance @param {string} code @param {"fmt" | "minify"} action
|
||||
* @returns {string | undefined} */
|
||||
/** @param {WebAssembly.Instance} instance @param {string} code @param {"tok" | "fmt" | "minify"} action
|
||||
* @returns {string | Uint8Array | undefined} */
|
||||
function modifyCode(instance, code, action) {
|
||||
let {
|
||||
INPUT, INPUT_LEN,
|
||||
|
@ -54,6 +54,7 @@ function modifyCode(instance, code, action) {
|
|||
} = instance.exports;
|
||||
|
||||
let funs = { fmt, tok, minify };
|
||||
let fun = funs[action];
|
||||
if (!(true
|
||||
&& memory instanceof WebAssembly.Memory
|
||||
&& INPUT instanceof WebAssembly.Global
|
||||
|
@ -61,9 +62,8 @@ function modifyCode(instance, code, action) {
|
|||
&& OUTPUT instanceof WebAssembly.Global
|
||||
&& OUTPUT_LEN instanceof WebAssembly.Global
|
||||
&& funs.hasOwnProperty(action)
|
||||
&& typeof funs[action] === "function"
|
||||
&& typeof fun === "function"
|
||||
)) never();
|
||||
let fun = funs[action];
|
||||
|
||||
if (action !== "fmt") {
|
||||
INPUT = OUTPUT;
|
||||
|
@ -133,7 +133,7 @@ function packPosts(posts, view) {
|
|||
* @return {Uint8Array} */
|
||||
function bufSlice(mem, ptr, len) {
|
||||
return new Uint8Array(mem.buffer, ptr.value,
|
||||
new DataView(mem.buffer).getUint32(len.value, true));
|
||||
new DataView(mem.buffer).getUint32(len.value, true));
|
||||
}
|
||||
|
||||
/** @param {WebAssembly.Memory} mem
|
||||
|
@ -283,27 +283,27 @@ async function bindCodeEdit(target) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @type {{ Array<string> }}
|
||||
* @type {Array<string>}
|
||||
* to be synched with `enum TokenGroup` in bytecode/src/fmt.rs */
|
||||
const TOK_CLASSES = [
|
||||
'Blank',
|
||||
'Comment',
|
||||
'Keyword',
|
||||
'Identifier',
|
||||
'Directive',
|
||||
'Number',
|
||||
'String',
|
||||
'Op',
|
||||
'Assign',
|
||||
'Paren',
|
||||
'Bracket',
|
||||
'Colon',
|
||||
'Comma',
|
||||
'Dot',
|
||||
'Ctor',
|
||||
'Blank',
|
||||
'Comment',
|
||||
'Keyword',
|
||||
'Identifier',
|
||||
'Directive',
|
||||
'Number',
|
||||
'String',
|
||||
'Op',
|
||||
'Assign',
|
||||
'Paren',
|
||||
'Bracket',
|
||||
'Colon',
|
||||
'Comma',
|
||||
'Dot',
|
||||
'Ctor',
|
||||
];
|
||||
|
||||
/** @type {{ [key: string]: (el: HTMLElement) => undefined | Promise<undefined> }} */
|
||||
/** @type {{ [key: string]: (el: HTMLElement) => void | Promise<void> }} */
|
||||
const applyFns = {
|
||||
timestamp: (el) => {
|
||||
const timestamp = el.innerText;
|
||||
|
@ -314,15 +314,16 @@ const applyFns = {
|
|||
};
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} target
|
||||
* @param {string} code */
|
||||
* @param {HTMLElement} target */
|
||||
async function fmt(target) {
|
||||
const code = target.innerText;
|
||||
const instance = await getFmtInstance();
|
||||
const decoder = new TextDecoder('utf-8');
|
||||
const fmt = modifyCode(instance, code, 'fmt');
|
||||
const codeBytes = new TextEncoder('utf-8').encode(fmt);
|
||||
if (typeof fmt !== "string") never()
|
||||
const codeBytes = new TextEncoder().encode(fmt);
|
||||
const tok = modifyCode(instance, fmt, 'tok');
|
||||
if (!(tok instanceof Uint8Array)) never();
|
||||
target.innerHTML = '';
|
||||
let start = 0;
|
||||
let kind = tok[0];
|
||||
|
@ -429,6 +430,7 @@ if (window.location.hostname === 'localhost') {
|
|||
const code = "main:=fn():void{return}";
|
||||
const inst = await getFmtInstance()
|
||||
const fmtd = modifyCode(inst, code, "fmt") ?? never();
|
||||
if (typeof fmtd !== "string") never();
|
||||
const prev = modifyCode(inst, fmtd, "minify") ?? never();
|
||||
if (code != prev) console.error(code, prev);
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ async fn amain() {
|
|||
.route("/profile", get(Profile::page))
|
||||
.route("/profile-view", get(Profile::get))
|
||||
.route("/profile/:name", get(Profile::get_other_page))
|
||||
.route("/profile/password", post(PasswordChange::post))
|
||||
.route("/profile-view/:name", get(Profile::get_other))
|
||||
.route("/post", get(Post::page))
|
||||
.route("/post-view", get(Post::get))
|
||||
|
@ -339,6 +340,70 @@ impl fmt::Display for Post {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Default)]
|
||||
struct PasswordChange {
|
||||
old_password: String,
|
||||
new_password: String,
|
||||
#[serde(skip)]
|
||||
error: Option<&'static str>,
|
||||
}
|
||||
|
||||
impl PasswordChange {
|
||||
async fn post(
|
||||
session: Session,
|
||||
axum::Form(mut change): axum::Form<PasswordChange>,
|
||||
) -> Html<String> {
|
||||
db::with(|que| {
|
||||
match que.authenticate.query_row((&session.name,), |r| r.get::<_, String>(1)) {
|
||||
Ok(hash) if verify_password(&hash, &change.old_password).is_err() => {
|
||||
change.error = Some("invalid credentials");
|
||||
}
|
||||
Ok(_) => {
|
||||
let new_hashed = hash_password(&change.new_password);
|
||||
match que
|
||||
.change_passowrd
|
||||
.execute((new_hashed, &session.name))
|
||||
.log("execute update")
|
||||
{
|
||||
None => change.error = Some("intenal server error"),
|
||||
Some(0) => change.error = Some("password is incorrect"),
|
||||
Some(_) => {}
|
||||
}
|
||||
}
|
||||
Err(rusqlite::Error::QueryReturnedNoRows) => {
|
||||
change.error = Some("invalid credentials");
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("login queri failed: {e}");
|
||||
change.error = Some("internal server error");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if change.error.is_some() {
|
||||
change.render(&session)
|
||||
} else {
|
||||
PasswordChange::default().render(&session)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Page for PasswordChange {
|
||||
fn render_to_buf(self, _: &Session, buf: &mut String) {
|
||||
let Self { old_password, new_password, error } = self;
|
||||
write_html! { (buf)
|
||||
<form "hx-post"="/profile/password" "hx-swap"="outerHTML">
|
||||
if let Some(e) = error { <div class="error">e</div> }
|
||||
<input name="old_password" type="password" autocomplete="old-password"
|
||||
placeholder="old password" value=old_password>
|
||||
<input name="new_password" type="password" autocomplete="new-password" placeholder="new password"
|
||||
value=new_password>
|
||||
<input type="submit" value="submit">
|
||||
</form>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Profile {
|
||||
other: Option<String>,
|
||||
|
@ -357,14 +422,19 @@ impl Profile {
|
|||
impl Page for Profile {
|
||||
fn render_to_buf(self, session: &Session, buf: &mut String) {
|
||||
db::with(|db| {
|
||||
let name = self.other.as_ref().unwrap_or(&session.name);
|
||||
let iter = db
|
||||
.get_user_posts
|
||||
.query_map((self.other.as_ref().unwrap_or(&session.name),), Post::from_row)
|
||||
.query_map((name,), Post::from_row)
|
||||
.log("get user posts query")
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter_map(|p| p.log("user post row"));
|
||||
write_html! { (buf)
|
||||
write_html! { (*buf)
|
||||
if name == &session.name {
|
||||
|b|{PasswordChange::default().render_to_buf(session, b)}
|
||||
}
|
||||
|
||||
for post in iter {
|
||||
!{post}
|
||||
} else {
|
||||
|
@ -399,7 +469,7 @@ struct Login {
|
|||
|
||||
impl PublicPage for Login {
|
||||
fn render_to_buf(self, buf: &mut String) {
|
||||
let Login { name, password, error } = self;
|
||||
let Self { name, password, error } = self;
|
||||
write_html! { (buf)
|
||||
<form "hx-post"="/login" "hx-swap"="outerHTML">
|
||||
if let Some(e) = error { <div class="error">e</div> }
|
||||
|
@ -439,13 +509,12 @@ impl Login {
|
|||
data.error = Some("invalid credentials");
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("foo {e}");
|
||||
log::error!("login queri failed: {e}");
|
||||
data.error = Some("internal server error");
|
||||
}
|
||||
});
|
||||
|
||||
if data.error.is_some() {
|
||||
log::error!("what {:?}", data);
|
||||
Err(data.render())
|
||||
} else {
|
||||
Ok(AppendHeaders([
|
||||
|
@ -682,6 +751,7 @@ mod db {
|
|||
gen_queries! {
|
||||
pub struct Queries {
|
||||
register: "INSERT INTO user (name, password_hash) VALUES(?, ?)",
|
||||
change_passowrd: "UPDATE user SET password_hash = ? WHERE name = ?",
|
||||
authenticate: "SELECT name, password_hash FROM user WHERE name = ?",
|
||||
login: "INSERT OR REPLACE INTO session (id, username, expiration) VALUES(?, ?, ?)",
|
||||
logout: "DELETE FROM session WHERE id = ?",
|
||||
|
|
Loading…
Reference in a new issue