Skip to content

Commit

Permalink
Merge Staging into Main (#153)
Browse files Browse the repository at this point in the history
* Bring Staging up to date with Main (#143)

* Merge Staging into Main (#139)

* news carousel adjustments

* adjust explore and tag pages

* work header fixes

* profile header updates

* adjust profile home page

* sizes down work stats on smaller displays

* adjusting works and blogs lists

* Update +layout.svelte

* adding optimizations to section list

* Update +page.svelte

* Update +page.svelte

* Feat/email and recovery (#136)

* feat: password resets and email confirmations

* updating controllers with confirmation guard

* API routes for features now in place

* password resets are in

* email confirmations are now in

* update readme

* Feat/work and comments features (#138)

* Feat/fixing profile forms (#142)

* chore: add beta badge to nav

* chore: fix display of beta badge

* chore: update about panel and version

* adding placeholder for messages panel

* profile forms now work

* fix: redirect approval/rejection notifications to their intended recipient

* adding links form to profile setitngs

* feat: adding links to profile pages

* fix: address issue with layout of admin badge on mobile

* chore: adds unique constraint to the approval queue (#123)

adds a `UNIQUE` constraint to the approval queue table on `work_id`, guaranteeing that works can only ever be submitted to the queue once.

closes #78

* fix: testing new method of obtaining client IP address

* Update Functions.swift

* Update Functions.swift

* fix: addresses issues with pagination on profile pages

* fix: address issue of width on mobile devices for profile pages

* fix: remove more tags button when less than 2 tags

* fix: one last fix for tags display

* fix: make sure transactions are actually being committed

* fix: pagination on works and blogs pages

* Update version.ts

* Update Paginator.svelte

* Update version.ts

* [FIX] Addresses access token expiry issue (#152)

* fix: include parent tags when fetching approval queue

* fix: addresses issue with sessions expiring early

* chore: remove debug lines

* feat: update site version

* feat: adding svelte query
  • Loading branch information
Figments authored Feb 16, 2023
1 parent 08285a1 commit 494e4c4
Show file tree
Hide file tree
Showing 21 changed files with 157 additions and 156 deletions.
2 changes: 1 addition & 1 deletion Client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
"@sveltejs/adapter-auto": "^1.0.0",
"@sveltejs/adapter-node": "^1.1.0",
"@sveltejs/kit": "^1.0.11",
"@sveltestack/svelte-query": "^1.6.0",
"@tailwindcss/aspect-ratio": "^0.4.2",
"@tailwindcss/forms": "^0.5.3",
"@tailwindcss/line-clamp": "^0.4.2",
"@tailwindcss/typography": "^0.5.9",
"@tanstack/svelte-query": "^4.24.6",
"@tiptap/core": "^2.0.0-beta.199",
"@tiptap/extension-blockquote": "^2.0.0-beta.199",
"@tiptap/extension-bold": "^2.0.0-beta.199",
Expand Down
25 changes: 0 additions & 25 deletions Client/src/hooks.server.ts

This file was deleted.

7 changes: 4 additions & 3 deletions Client/src/lib/http/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './http-service';
export { BASE_URL } from './base-url';
export type { ResponseError } from './response-error';
export * from "./http-service";
export { BASE_URL } from "./base-url";
export type { ResponseError } from "./response-error";
export { queryClient } from "./query-client";
10 changes: 10 additions & 0 deletions Client/src/lib/http/query-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { browser } from "$app/environment";
import { QueryClient } from "@tanstack/svelte-query";

export const queryClient = new QueryClient({
defaultOptions: {
queries: {
enabled: browser
}
}
});
1 change: 1 addition & 0 deletions Client/src/lib/models/accounts/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface Account {
emailConfirmed: boolean;
readonly createdAt: Date;
readonly updatedAt: Date;
readonly token?: string;
}

export interface AccountWithReports extends Account {
Expand Down
2 changes: 1 addition & 1 deletion Client/src/lib/ui/guide/account/LoginPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
initialValues: {
email: "",
password: "",
rememberMe: false
rememberMe: true
}
});
</script>
Expand Down
2 changes: 1 addition & 1 deletion Client/src/lib/util/constants/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const VERSION = "v1.0.0-beta.3";
export const VERSION = "v1.0.0-beta.4";
23 changes: 21 additions & 2 deletions Client/src/routes/+layout.server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
import type { LayoutServerLoad } from "./$types";
import { postReqServer, type ServerResponseError } from "$lib/server";
import type { RefreshPackage, SessionInfo } from "$lib/models/accounts";

export const load: LayoutServerLoad = async ({ locals }): Promise<{ hasKey: boolean }> => {
return { hasKey: !!locals.user };
export const load: LayoutServerLoad = async ({ cookies }): Promise<{ token: string | null }> => {
const accountId = cookies.get("accountId");
const refreshToken = cookies.get("refreshToken");

if (accountId && refreshToken) {
const info: SessionInfo = {
accountId: accountId,
refreshToken: refreshToken
};
const response = await postReqServer<RefreshPackage>(`/auth/refresh`, info);
if ((response as ServerResponseError).statusCode) {
return { token: null };
} else {
const result = response as RefreshPackage;
return { token: result.accessToken };
}
} else {
return { token: null };
}
};
116 changes: 61 additions & 55 deletions Client/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@
import { getReq, patchReq, type ResponseError } from "$lib/http";
import Button from "$lib/ui/util/Button.svelte";
import type { Account } from "$lib/models/accounts";
import { QueryClientProvider } from "@tanstack/svelte-query";
import { queryClient } from "$lib/http";
export let data: { hasKey: boolean } = { hasKey: false };
export let data: { token: string | null } = { token: null };
let loadingTerms = false;
let loadingConfirm = false;
if (!data.hasKey) {
if (data.token) {
$account.token = data.token;
} else {
$account.account = null;
$account.currProfile = null;
$account.profiles = [];
Expand Down Expand Up @@ -58,63 +62,65 @@
}
</script>

<Popup />
<main
class="flex flex-col min-h-[100vh] h-full overflow-y-scroll lg:overflow-y-hidden lg:flex-row lg:h-screen {$app.theme}"
class:light={$app.darkMode === false}
class:dark={$app.darkMode === true}
>
<Nav />
<Guide>
{#if $account.account && !$account.account.termsAgree}
<div
class="xl:max-w-4xl w-full flex flex-col lg:flex-row items-center mx-auto p-4 xl:mt-6 xl:rounded-xl bg-red-600 bg-opacity-25 border-y xl:border-x border-red-600"
>
<div class="flex-1">
<div class="flex items-center">
<CloseCircleLine size="18px" class="mr-2" />
<span class="font-bold text-lg">Head's Up!</span>
<QueryClientProvider client={queryClient}>
<Popup />
<main
class="flex flex-col min-h-[100vh] h-full overflow-y-scroll lg:overflow-y-hidden lg:flex-row lg:h-screen {$app.theme}"
class:light={$app.darkMode === false}
class:dark={$app.darkMode === true}
>
<Nav />
<Guide>
{#if $account.account && !$account.account.termsAgree}
<div
class="xl:max-w-4xl w-full flex flex-col lg:flex-row items-center mx-auto p-4 xl:mt-6 xl:rounded-xl bg-red-600 bg-opacity-25 border-y xl:border-x border-red-600"
>
<div class="flex-1">
<div class="flex items-center">
<CloseCircleLine size="18px" class="mr-2" />
<span class="font-bold text-lg">Head's Up!</span>
</div>
<span>
You haven't agreed to Offprint's Terms of Service, Privacy Policy, and
Code of Conduct. Until you do, all features of your account are locked.
Hit the "I Agree" button to fix this ASAP.
</span>
</div>
<span>
You haven't agreed to Offprint's Terms of Service, Privacy Policy, and Code
of Conduct. Until you do, all features of your account are locked. Hit the
"I Agree" button to fix this ASAP.
</span>
<Button on:click={agreeToTerms} loading={loadingTerms} loadingText="Saving...">
<CheckLine class="button-icon" />
<span class="button-text">I agree</span>
</Button>
</div>
<Button on:click={agreeToTerms} loading={loadingTerms} loadingText="Saving...">
<CheckLine class="button-icon" />
<span class="button-text">I agree</span>
</Button>
</div>
{/if}
{#if $account.account && !$account.account.emailConfirmed}
<div
class="xl:max-w-4xl w-full flex flex-col lg:flex-row items-center mx-auto p-4 xl:mt-6 xl:rounded-xl bg-red-600 bg-opacity-25 border-y xl:border-x border-red-600"
>
<div class="flex-1">
<div class="flex items-center">
<CloseCircleLine size="18px" class="mr-2" />
<span class="font-bold text-lg">Head's Up!</span>
{/if}
{#if $account.account && !$account.account.emailConfirmed}
<div
class="xl:max-w-4xl w-full flex flex-col lg:flex-row items-center mx-auto p-4 xl:mt-6 xl:rounded-xl bg-red-600 bg-opacity-25 border-y xl:border-x border-red-600"
>
<div class="flex-1">
<div class="flex items-center">
<CloseCircleLine size="18px" class="mr-2" />
<span class="font-bold text-lg">Head's Up!</span>
</div>
<span>
You haven't confirmed your email address yet. Until you do, all features
of your account are locked. Hit the "Confirm" button to fix this ASAP!
</span>
</div>
<span>
You haven't confirmed your email address yet. Until you do, all features of
your account are locked. Hit the "Confirm" button to fix this ASAP!
</span>
<Button
on:click={sendConfirmationEmail}
loading={loadingConfirm}
loadingText="Sending..."
>
<CheckLine class="button-icon" />
<span class="button-text">Confirm</span>
</Button>
</div>
<Button
on:click={sendConfirmationEmail}
loading={loadingConfirm}
loadingText="Sending..."
>
<CheckLine class="button-icon" />
<span class="button-text">Confirm</span>
</Button>
</div>
{/if}
<slot />
</Guide>
<Toaster />
</main>
{/if}
<slot />
</Guide>
<Toaster />
</main>
</QueryClientProvider>

<style lang="scss">
:global(main) {
Expand Down
5 changes: 5 additions & 0 deletions Client/src/routes/api/auth/log-in/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ export const POST: RequestHandler = async ({ request, cookies, getClientAddress
httpOnly: true,
expires: expirationDate
});
cookies.set("accountId", data.account.id, {
path: "/",
httpOnly: true,
expires: expirationDate
});
data.refreshToken = "";
data.refreshExpirationTime = 0;
return new Response(JSON.stringify(data), { status: 200 });
Expand Down
15 changes: 7 additions & 8 deletions Client/src/routes/api/auth/log-out/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@ import type { RequestHandler } from "./$types";
import type { SessionInfo } from "$lib/models/accounts";
import { postReqServer } from "$lib/server";

export const POST: RequestHandler = async ({ cookies, locals }) => {
if (!locals.user) {
return new Response(null, { status: 422 });
}

if (cookies.get("refreshToken")) {
export const POST: RequestHandler = async ({ cookies }) => {
const accountId = cookies.get("accountId");
const refreshToken = cookies.get("refreshToken");
if (accountId && refreshToken) {
const sessionInfo: SessionInfo = {
accountId: locals.user.id,
refreshToken: cookies.get("refreshToken") ?? ""
accountId: accountId,
refreshToken: refreshToken
};

await postReqServer<void>(`/auth/logout`, sessionInfo);
}
cookies.delete("accountId", { path: "/" });
cookies.delete("refreshToken", { path: "/" });
return new Response(null, { status: 200 });
};
8 changes: 2 additions & 6 deletions Client/src/routes/api/auth/refresh-token/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@ import type { RequestHandler } from "./$types";
import type { RefreshPackage, SessionInfo } from "$lib/models/accounts";
import { postReqServer, type ServerResponseError } from "$lib/server";

export const POST: RequestHandler = async ({ cookies, locals }) => {
if (!locals.user) {
return new Response(null, { status: 422 });
}

export const POST: RequestHandler = async ({ cookies }) => {
const info: SessionInfo = {
accountId: locals.user.id,
accountId: cookies.get("accountId") ?? "",
refreshToken: cookies.get("refreshToken") ?? ""
};

Expand Down
8 changes: 7 additions & 1 deletion Client/src/routes/api/auth/sign-up/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@ export const POST: RequestHandler = async ({ request, cookies, getClientAddress
return new Response(JSON.stringify(error), { status: error.statusCode });
} else {
const data = response as ClientPackage;
const expirationDate = new Date(Date.now() + data.refreshExpirationTime * 1000);
cookies.set("refreshToken", data.refreshToken, {
path: "/",
httpOnly: true,
expires: new Date(Date.now() + data.refreshExpirationTime * 1000)
expires: expirationDate
});
cookies.set("accountId", data.account.id, {
path: "/",
httpOnly: true,
expires: expirationDate
});
data.refreshToken = "";
data.refreshExpirationTime = 0;
Expand Down
17 changes: 12 additions & 5 deletions Client/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,6 @@
svelte-hmr "^0.15.1"
vitefu "^0.2.3"

"@sveltestack/svelte-query@^1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@sveltestack/svelte-query/-/svelte-query-1.6.0.tgz#d175863557a7abe6a8dcb0da2080a9f43ae8d1d1"
integrity sha512-C0wWuh6av1zu3Pzwrg6EQmX3BhDZQ4gMAdYu6Tfv4bjbEZTB00uEDz52z92IZdONh+iUKuyo0xRZ2e16k2Xifg==

"@tailwindcss/aspect-ratio@^0.4.2":
version "0.4.2"
resolved "https://registry.yarnpkg.com/@tailwindcss/aspect-ratio/-/aspect-ratio-0.4.2.tgz#9ffd52fee8e3c8b20623ff0dcb29e5c21fb0a9ba"
Expand Down Expand Up @@ -347,6 +342,18 @@
lodash.merge "^4.6.2"
postcss-selector-parser "6.0.10"

"@tanstack/[email protected]":
version "4.24.6"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.24.6.tgz#8f102bc922308f0c6c5ddea34fe253688314265a"
integrity sha512-Tfru6YTDTCpX7dKVwHp/sosw/dNjEdzrncduUjIkQxn7n7u+74HT2ZrGtwwrU6Orws4x7zp3FKRqBPWVVhpx9w==

"@tanstack/svelte-query@^4.24.6":
version "4.24.6"
resolved "https://registry.yarnpkg.com/@tanstack/svelte-query/-/svelte-query-4.24.6.tgz#028c370e0d223b76ae183cb22409b3c6b2ed5ec6"
integrity sha512-bBA2r8iH6jKy/oq4JDMRt3WOzZWuvIvRvXU9dE8RmtMZfm42yRcDBd7zNmoo8kNlNvhuLulx8zVh9B9mE++Bsw==
dependencies:
"@tanstack/query-core" "4.24.6"

"@tiptap/core@^2.0.0-beta.199":
version "2.0.0-beta.202"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.202.tgz#be4c6a200e81875c552e1cc15ae9c6cdd86c37c2"
Expand Down
14 changes: 0 additions & 14 deletions Sources/App/Controllers/Accounts/AuthController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,6 @@ struct AuthController: RouteCollection {
return try await request.authService.logout(with: logoutInfo)
}

auth.get("get-account-from-session") { request async throws -> ClientAccount in
let errorMsg = "Requires a valid session ID."
guard let sessionId: String = request.query["sessionId"] else {
throw Abort(.badRequest, reason: errorMsg)
}
guard let idString: String = sessionId.fromBase64() else {
throw Abort(.badRequest, reason: errorMsg)
}
guard let id = UUID(uuidString: idString) else {
throw Abort(.badRequest, reason: errorMsg)
}
return try await request.authService.getAccountFromSession(id)
}

auth.get("send-recovery-email") { request async throws -> Response in
let email: String? = request.query["email"]
if let hasEmail = email {
Expand Down
4 changes: 3 additions & 1 deletion Sources/App/Models/Accounts/ClientAccount.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ struct ClientAccount: Content {
var emailConfirmed: Bool
var createdAt: Date?
var updatedAt: Date?
var token: String?

init(from account: Account) {
init(from account: Account, token: String? = nil) {
id = account.id
profiles = account.$profiles.value ?? []
roles = account.roles
termsAgree = account.termsAgree
emailConfirmed = account.emailConfirmed
createdAt = account.createdAt
updatedAt = account.updatedAt
self.token = token
}
}
Loading

0 comments on commit 494e4c4

Please sign in to comment.