diff --git a/backend/data/users.py b/backend/data/users.py
index 00746f1..71494c7 100644
--- a/backend/data/users.py
+++ b/backend/data/users.py
@@ -1,5 +1,5 @@
from dataclasses import dataclass
-from hashlib import scrypt
+# from hashlib import scrypt
import hashlib
import random
import string
@@ -90,8 +90,10 @@ def register_user(username: str, password_plaintext: str) -> User:
raise UserRegistrationError("user already exists")
+# def scrypt(password_plaintext: bytes, password_salt: bytes) -> bytes:
+# return hashlib.scrypt(password_plaintext, salt=password_salt, n=8, r=8, p=1)
def scrypt(password_plaintext: bytes, password_salt: bytes) -> bytes:
- return hashlib.scrypt(password_plaintext, salt=password_salt, n=8, r=8, p=1)
+ return hashlib.pbkdf2_hmac('sha256', password_plaintext, password_salt, 100000)
SALT_CHARACTERS = string.ascii_uppercase + string.ascii_lowercase + string.digits
diff --git a/front-end/components/bloom.mjs b/front-end/components/bloom.mjs
index 0b4166c..d50c42e 100644
--- a/front-end/components/bloom.mjs
+++ b/front-end/components/bloom.mjs
@@ -11,77 +11,79 @@
*/
const createBloom = (template, bloom) => {
- if (!bloom) return;
- const bloomFrag = document.getElementById(template).content.cloneNode(true);
- const bloomParser = new DOMParser();
+ if (!bloom) return;
+ const bloomFrag = document.getElementById(template).content.cloneNode(true);
+ const bloomParser = new DOMParser();
- const bloomArticle = bloomFrag.querySelector("[data-bloom]");
- const bloomUsername = bloomFrag.querySelector("[data-username]");
- const bloomTime = bloomFrag.querySelector("[data-time]");
- const bloomTimeLink = bloomFrag.querySelector("a:has(> [data-time])");
- const bloomContent = bloomFrag.querySelector("[data-content]");
+ const bloomArticle = bloomFrag.querySelector("[data-bloom]");
+ const bloomUsername = bloomFrag.querySelector("[data-username]");
+ const bloomTime = bloomFrag.querySelector("[data-time]");
+ const bloomTimeLink = bloomFrag.querySelector("a:has(> [data-time])");
+ const bloomContent = bloomFrag.querySelector("[data-content]");
- bloomArticle.setAttribute("data-bloom-id", bloom.id);
- bloomUsername.setAttribute("href", `/profile/${bloom.sender}`);
- bloomUsername.textContent = bloom.sender;
- bloomTime.textContent = _formatTimestamp(bloom.sent_timestamp);
- bloomTimeLink.setAttribute("href", `/bloom/${bloom.id}`);
- bloomContent.replaceChildren(
- ...bloomParser.parseFromString(_formatHashtags(bloom.content), "text/html")
- .body.childNodes
- );
+ bloomArticle.setAttribute("data-bloom-id", bloom.id);
+ bloomUsername.setAttribute("href", `/profile/${bloom.sender}`);
+ bloomUsername.textContent = bloom.sender;
+ bloomTime.textContent = _formatTimestamp(bloom.sent_timestamp);
+ bloomTimeLink.setAttribute("href", `/bloom/${bloom.id}`);
+ bloomContent.replaceChildren(
+ ...bloomParser.parseFromString(_formatHashtags(bloom.content), "text/html")
+ .body.childNodes
+ );
- return bloomFrag;
+ return bloomFrag;
};
function _formatHashtags(text) {
- if (!text) return text;
- return text.replace(
- /\B#[^#]+/g,
- (match) => `${match}`
- );
+ if (!text) return text;
+ return text.replace(
+ /\B#[^#]+/g, // does not grab #
+ /\B#[a-zA-Z0-9_]+/g,
+
+ (match) => `${match}`
+ );
}
function _formatTimestamp(timestamp) {
- if (!timestamp) return "";
+ if (!timestamp) return "";
- try {
- const date = new Date(timestamp);
- const now = new Date();
- const diffSeconds = Math.floor((now - date) / 1000);
+ try {
+ const date = new Date(timestamp);
+ const now = new Date();
+ const diffSeconds = Math.floor((now - date) / 1000);
- // Less than a minute
- if (diffSeconds < 60) {
- return `${diffSeconds}s`;
- }
+ // Less than a minute
+ if (diffSeconds < 60) {
+ return `${diffSeconds}s`;
+ }
- // Less than an hour
- const diffMinutes = Math.floor(diffSeconds / 60);
- if (diffMinutes < 60) {
- return `${diffMinutes}m`;
- }
+ // Less than an hour
+ const diffMinutes = Math.floor(diffSeconds / 60);
+ if (diffMinutes < 60) {
+ return `${diffMinutes}m`;
+ }
- // Less than a day
- const diffHours = Math.floor(diffMinutes / 60);
- if (diffHours < 24) {
- return `${diffHours}h`;
- }
+ // Less than a day
+ const diffHours = Math.floor(diffMinutes / 60);
+ if (diffHours < 24) {
+ return `${diffHours}h`;
+ }
- // Less than a week
- const diffDays = Math.floor(diffHours / 24);
- if (diffDays < 7) {
- return `${diffDays}d`;
- }
+ // Less than a week
+ const diffDays = Math.floor(diffHours / 24);
+ if (diffDays < 7) {
+ return `${diffDays}d`;
+ }
- // Format as month and day for older dates
- return new Intl.DateTimeFormat("en-US", {
- month: "short",
- day: "numeric",
- }).format(date);
- } catch (error) {
- console.error("Failed to format timestamp:", error);
- return "";
- }
+ // Format as month and day for older dates
+ return new Intl.DateTimeFormat("en-US", {
+ month: "short",
+ day: "numeric",
+ }).format(date);
+ } catch (error) {
+ console.error("Failed to format timestamp:", error);
+ return "";
+ }
}
-export {createBloom};
+export { createBloom };
diff --git a/front-end/views/profile.mjs b/front-end/views/profile.mjs
index dd2b92a..9824d9c 100644
--- a/front-end/views/profile.mjs
+++ b/front-end/views/profile.mjs
@@ -1,66 +1,69 @@
-import {renderEach, renderOne, destroy} from "../lib/render.mjs";
+import { renderEach, renderOne, destroy } from "../lib/render.mjs";
import {
- apiService,
- state,
- getLogoutContainer,
- getLoginContainer,
- getProfileContainer,
- getTimelineContainer,
+ apiService,
+ state,
+ getLogoutContainer,
+ getLoginContainer,
+ getProfileContainer,
+ getTimelineContainer,
} from "../index.mjs";
-import {createLogin, handleLogin} from "../components/login.mjs";
-import {createLogout, handleLogout} from "../components/logout.mjs";
-import {createProfile, handleFollow} from "../components/profile.mjs";
-import {createBloom} from "../components/bloom.mjs";
+import { createLogin, handleLogin } from "../components/login.mjs";
+import { createLogout, handleLogout } from "../components/logout.mjs";
+import { createProfile, handleFollow } from "../components/profile.mjs";
+import { createBloom } from "../components/bloom.mjs";
// Profile view - just this person's blooms and their profile
function profileView(username) {
- destroy();
+ destroy();
- const existingProfile = state.profiles.find((p) => p.username === username);
+ const existingProfile = state.profiles.find((p) => p.username === username);
- // Only fetch profile if we don't have it or if it's incomplete
- if (!existingProfile || !existingProfile.recent_blooms) {
- apiService.getProfile(username);
- }
+ // Only fetch profile if we don't have it or if it's incomplete
+ if (!existingProfile || !existingProfile.recent_blooms) {
+ apiService.getProfile(username);
+ }
- renderOne(
- state.isLoggedIn,
- getLogoutContainer(),
- "logout-template",
- createLogout
- );
- document
- .querySelector("[data-action='logout']")
- ?.addEventListener("click", handleLogout);
- renderOne(
- state.isLoggedIn,
- getLoginContainer(),
- "login-template",
- createLogin
- );
- document
- .querySelector("[data-action='login']")
- ?.addEventListener("click", handleLogin);
+ renderOne(
+ state.isLoggedIn,
+ getLogoutContainer(),
+ "logout-template",
+ createLogout
+ );
+ document
+ .querySelector("[data-action='logout']")
+ ?.addEventListener("click", handleLogout);
+ renderOne(
+ state.isLoggedIn,
+ getLoginContainer(),
+ "login-template",
+ createLogin
+ );
+ document
+ // .querySelector("[data-action='login']")
+ // ?.addEventListener("click", handleLogin);
+ .querySelector(".login__form")
+ ?.addEventListener("submit", handleLogin);
+ //submit event gets data from inputs
- const profileData = state.profiles.find((p) => p.username === username);
- if (profileData) {
- renderOne(
- {
- profileData,
- whoToFollow: state.isLoggedIn ? state.whoToFollow : [],
- isLoggedIn: state.isLoggedIn,
- },
- getProfileContainer(),
- "profile-template",
- createProfile
- );
- renderEach(
- profileData.recent_blooms || [],
- getTimelineContainer(),
- "bloom-template",
- createBloom
- );
- }
+ const profileData = state.profiles.find((p) => p.username === username);
+ if (profileData) {
+ renderOne(
+ {
+ profileData,
+ whoToFollow: state.isLoggedIn ? state.whoToFollow : [],
+ isLoggedIn: state.isLoggedIn,
+ },
+ getProfileContainer(),
+ "profile-template",
+ createProfile
+ );
+ renderEach(
+ profileData.recent_blooms || [],
+ getTimelineContainer(),
+ "bloom-template",
+ createBloom
+ );
+ }
}
-export {profileView};
+export { profileView };