mail based rss feed aggregator
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

add password to user

ollie 109fafb1 ad9dfcca

+50 -22
+2 -1
db/migrations/20260331190734_initialize.sql
··· 17 17 CREATE TABLE users 18 18 ( 19 19 id uuid PRIMARY KEY NOT NULL UNIQUE, 20 - email TEXT NOT NULL UNIQUE 20 + email TEXT NOT NULL UNIQUE, 21 + password_hash BLOB NOT NULL 21 22 ); 22 23 23 24 CREATE TABLE subscriptions
+2 -1
db/schema.sql
··· 2 2 CREATE TABLE users 3 3 ( 4 4 id uuid PRIMARY KEY NOT NULL UNIQUE, 5 - email TEXT NOT NULL UNIQUE 5 + email TEXT NOT NULL UNIQUE, 6 + password_hash BLOB NOT NULL 6 7 ); 7 8 CREATE TABLE subscriptions 8 9 (
+2 -1
dev/insert_test_data.gleam
··· 29 29 30 30 io.println("Inserting test data") 31 31 32 - let test_user = user.new("rss@ollie.earth") 32 + let password = user.hash_password("testing123") 33 + let test_user = user.new("rss@ollie.earth", password) 33 34 34 35 let assert Ok(_) = database.add_user(test_user, into: database) 35 36 as "Failed to insert test user"
+9 -4
src/eater/database.gleam
··· 21 21 import eater/user 22 22 import gleam/dynamic/decode 23 23 import gleam/list 24 - import gleam/option.{type Option, None, Some} 24 + import gleam/option.{Some} 25 25 import gleam/result 26 26 import parrot/dev 27 27 import sqlight ··· 114 114 user user: user.User, 115 115 into on: sqlight.Connection, 116 116 ) -> Result(Nil, sqlight.Error) { 117 - let #(sql, with) = sql.add_user(user.id |> uuid.to_bit_array, user.email) 117 + let #(sql, with) = 118 + sql.add_user( 119 + id: user.id |> uuid.to_bit_array, 120 + email: user.email, 121 + password_hash: user.password_hash, 122 + ) 118 123 119 124 let with = list.map(with, parrot_to_sqlight) 120 125 ··· 137 142 let assert Ok(id) = uuid.from_bit_array(user.id) 138 143 as "invalid UUID from db UUID column?!" 139 144 140 - user.User(id, user.email) 145 + user.User(id, user.email, user.password_hash) 141 146 }) 142 147 |> Ok 143 148 } ··· 161 166 let assert Ok(id) = uuid.from_bit_array(user.id) 162 167 as "invalid UUID from db UUID column?!" 163 168 164 - user.User(id, user.email) 169 + user.User(id, user.email, user.password_hash) 165 170 |> Ok 166 171 } 167 172 }
+22 -10
src/eater/sql.gleam
··· 66 66 ]) 67 67 } 68 68 69 - pub fn add_user(id id: BitArray, email email: String) { 69 + pub fn add_user( 70 + id id: BitArray, 71 + email email: String, 72 + password_hash password_hash: BitArray, 73 + ) { 70 74 let sql = 71 75 " 72 76 INSERT INTO users ( 73 77 id, 74 - email 78 + email, 79 + password_hash 75 80 ) 76 81 values 77 - (?, ?)" 78 - #(sql, [dev.ParamBitArray(id), dev.ParamString(email)]) 82 + (?, ?, ?)" 83 + #(sql, [ 84 + dev.ParamBitArray(id), 85 + dev.ParamString(email), 86 + dev.ParamBitArray(password_hash), 87 + ]) 79 88 } 80 89 81 90 pub type AllUsers { 82 - AllUsers(id: BitArray, email: String) 91 + AllUsers(id: BitArray, email: String, password_hash: BitArray) 83 92 } 84 93 85 94 pub fn all_users() { 86 - let sql = "SELECT id, email FROM users" 95 + let sql = "SELECT id, email, password_hash FROM users" 87 96 #(sql, [], all_users_decoder()) 88 97 } 89 98 90 99 pub fn all_users_decoder() -> decode.Decoder(AllUsers) { 91 100 use id <- decode.field(0, decode.bit_array) 92 101 use email <- decode.field(1, decode.string) 93 - decode.success(AllUsers(id:, email:)) 102 + use password_hash <- decode.field(2, decode.bit_array) 103 + decode.success(AllUsers(id:, email:, password_hash:)) 94 104 } 95 105 96 106 pub type UserByEmail { 97 - UserByEmail(id: BitArray, email: String) 107 + UserByEmail(id: BitArray, email: String, password_hash: BitArray) 98 108 } 99 109 100 110 pub fn user_by_email(email email: String) { 101 - let sql = "SELECT id, email FROM users WHERE users.email = ? LIMIT 1" 111 + let sql = 112 + "SELECT id, email, password_hash FROM users WHERE users.email = ? LIMIT 1" 102 113 #(sql, [dev.ParamString(email)], user_by_email_decoder()) 103 114 } 104 115 105 116 pub fn user_by_email_decoder() -> decode.Decoder(UserByEmail) { 106 117 use id <- decode.field(0, decode.bit_array) 107 118 use email <- decode.field(1, decode.string) 108 - decode.success(UserByEmail(id:, email:)) 119 + use password_hash <- decode.field(2, decode.bit_array) 120 + decode.success(UserByEmail(id:, email:, password_hash:)) 109 121 } 110 122 111 123 pub type WasUpdateSentToUser {
+3 -2
src/eater/sql/users.sql
··· 16 16 -- name: AddUser :exec 17 17 INSERT INTO users ( 18 18 id, 19 - email 19 + email, 20 + password_hash 20 21 ) 21 22 values 22 - (?, ?); 23 + (?, ?, ?); 23 24 24 25 25 26 -- name: AllUsers :many
+10 -3
src/eater/user.gleam
··· 13 13 // This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5] 14 14 // See the Licence for the specific language governing permissions and limitations. [cite: 6] 15 15 16 + import gleam/crypto 16 17 import youid/uuid 17 18 18 19 pub type User { 19 - User(id: uuid.Uuid, email: String) 20 + User(id: uuid.Uuid, email: String, password_hash: BitArray) 20 21 } 21 22 22 23 /// creates a new user with a uuid 23 24 /// 24 - pub fn new(email email: String) { 25 - User(uuid.v7(), email:) 25 + pub fn new(email email: String, password_hash password_hash: BitArray) { 26 + User(uuid.v7(), email:, password_hash:) 27 + } 28 + 29 + /// hash a string password 30 + /// 31 + pub fn hash_password(password: String) { 32 + crypto.hash(crypto.Sha256, <<password:utf8>>) 26 33 }