frontend: Introduce navigation bar Minor changes to the front-end mostly, to allow users to register, sign in, and sign out. The sign out route is changed to a GET endpoint, as links in HTML cannot DELETE.

zj
Sep 3, 2021, 12:08 PM
KFVJ3KMWXEGILN4NWIWPPX7AU65M4H4UEAUIAQL2QSXOW3B5RFGQC

Dependencies

  • [2] 5UNA2DEA routes: Register and authenticate users Allow users to sign up, and sign in/sign out. The routes are added, though the design of the pages is very bare bones still, it's hard to go through the full flow to demo. On the server side: Passwords are stored encrypted in the database with salts. This uses the PG encrypt tooling to prevent against bugs and maintainance costs on this project. When a user is signed in, the user ID is set in a private cookie. Rocket has Guards for routes, which has not been implemented yet for this project.
  • [3] IWM4EE63 database: Add migration support Fairly minor change codewise; add support for creating migrations and run them at the start of the runtime. In this case not a lot of changes happen, only the migrations tracking table is added. The sqlx command line tool is used to manage migrations; invoke `cargo sqlx --help` for more info.
  • [4] W3M3C7CC Initial commit This change includes a very small hello world application server written in Rust using Rocket.rs. Managing dependencies is done with Nix as that works well between Linux and Mac for me.
  • [5] K4JNAJOF database: Connect to postgres on Rocket boot As database I've chosen PostgreSQL, as my personal experience has been good with it. This change allows Rocket to connect to the database on booting the server. It depends on the DATABASE_URL being set, and for now circumvents the Rocket config helpers as it seemed faster to be up and running this way.
  • [6] EIIUUAKG nix: Install and initialize a Postgres DB For a persistance layer, this change introduces postgresql as dependency. The daemon is started when `nix-shell` is invoked. `pg_ctl stop` is not invoked, and this has to be done by a developer. Data is persisted in a tmp directory, which is added to the ignore file.

Change contents

  • file deletion: TODO (----------)
    [1.0][2.9740:9768](),[2.9768][2.9769:9769]()
    - Test the sign up/sign in/sign out flow
    - Record changes
  • file deletion: base.html.tera (----------)
    [2.21][2.1926:1964](),[2.1964][2.1965:1965]()
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Nidobyte</title>
    </head>
    <body>
    {% if flash %}
    <p>{{flash}}</p>
    {% endif %}
    {% block body %}
    {% endblock body %}
    </body>
    </html>
  • replacement in templates/sign_in.html.tera at line 3
    [2.103][2.103:152]()
    <div style="width:30%;" class="container-fluid">
    [2.103]
    [2.152]
    <div style="width:50%;" class="container-fluid">
  • replacement in templates/sign_in.html.tera at line 17
    [2.735][2.735:806]()
    <button class="btn btn-primary" type="submit">Sign up</button>
    [2.735]
    [2.806]
    <button class="btn btn-primary" type="submit">Sign in</button>
  • file addition: nav.html.tera (----------)
    [2.21]
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container-fluid">
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarsExample08" aria-controls="navbarsExample08" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse justify-content-md-center" id="navbarsExample08">
    <ul class="navbar-nav">
    <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Nidobyte</a>
    </li>
    <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
    </li>
    <li class="nav-item">
    <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
    </li>
    <li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#" id="dropdown08" data-bs-toggle="dropdown" aria-expanded="false">User</a>
    <ul class="dropdown-menu" aria-labelledby="dropdown08">
    <li><a class="dropdown-item" href="/users/sign_in">Sign in</a></li>
    <li><a class="dropdown-item" href="/users/new">Sign up</a></li>
    <li><a class="dropdown-item" href="/users/sign_out">Sign out</a></li>
    </ul>
    </li>
    </ul>
    </div>
    </div>
    </nav>
  • file addition: landing.html.tera (----------)
    [2.21]
    {% extends "base" %}
    {% block body %}
    <p>Hello world!</p>
    {% endblock body %}
  • file addition: base.html.tera (----------)
    [2.21]
    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Nidobyte</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>
    </head>
    <body>
    {% include "nav" %}
    {% block body %}
    <p> foo</p>
    {% endblock body %}
    </body>
    </html>
  • file deletion: index.html (----------)
    [3.18][3.19:53](),[3.53][3.54:54]()
    <html>
    <head>
    <title>Nidobyte</title>
    </head>
    <body>
    <h1>Hello, world!</h1>
    </body>
    </html>
  • replacement in src/users.rs at line 94
    [2.4944][2.4944:4967]()
    #[delete("/sign_out")]
    [2.4944]
    [2.4967]
    #[get("/sign_out")]
  • file addition: root.rs (----------)
    [3.179]
    use rocket::form::Context;
    use rocket_dyn_templates::Template;
    #[get("/")]
    pub fn landing() -> Template {
    Template::render("landing", &Context::default())
    }
  • edit in src/main.rs at line 11
    [2.8067]
    [2.8067]
    mod root;
  • edit in src/main.rs at line 29
    [2.8399]
    [3.823]
    .mount("/", routes![root::landing])
  • file deletion: mod.rs (----------)
    [2.8420][2.8421:8451](),[2.8451][2.8452:8452]()
    use std::env;
    use rocket::{
    fairing::{self, AdHoc},
    Build, Rocket,
    };
    pub(crate) type Database = sqlx::PgPool;
    async fn init_db(rocket: Rocket<Build>) -> fairing::Result {
    let database_url = match env::var("DATABASE_URL") {
    Ok(val) => val,
    Err(e) => {
    error!("Failed to read DATABASE_URL environment variable: {}", e);
    return Err(rocket);
    }
    };
    let pool = sqlx::PgPool::connect(&database_url)
    .await
    .expect("Failed to connect to the database");
    if let Err(e) = sqlx::migrate!("./migrations").run(&pool).await {
    error!("Failed to migrate PG database: {}", e);
    return Err(rocket);
    }
    Ok(rocket.manage(pool))
    }
    pub fn stage() -> AdHoc {
    AdHoc::on_ignite("SQL Stage - PostgreSQL", |rocket| async {
    rocket.attach(AdHoc::try_on_ignite("Postgres Database", init_db))
    })
    }
  • file addition: mod.rs (----------)
    [2.8420]
    use std::env;
    use rocket::{
    fairing::{self, AdHoc},
    Build, Rocket,
    };
    pub(crate) type Database = sqlx::PgPool;
    async fn init_db(rocket: Rocket<Build>) -> fairing::Result {
    let database_url = match env::var("DATABASE_URL") {
    Ok(val) => val,
    Err(e) => {
    error!("Failed to read DATABASE_URL environment variable: {}", e);
    return Err(rocket);
    }
    };
    let pool = sqlx::PgPool::connect(&database_url)
    .await
    .expect("Failed to connect to the database");
    if let Err(e) = sqlx::migrate!("./migrations").run(&pool).await {
    error!("Failed to migrate PG database: {}", e);
    return Err(rocket);
    }
    Ok(rocket.manage(pool))
    }
    pub fn stage() -> AdHoc {
    AdHoc::on_ignite("SQL Stage - PostgreSQL", |rocket| async {
    rocket.attach(AdHoc::try_on_ignite("Postgres Database", init_db))
    })
    }