From 384ef7a32abaa0e04b1f0d996c6626060d3f0b08 Mon Sep 17 00:00:00 2001 From: Kaan Date: Sun, 24 Mar 2024 07:15:16 +0300 Subject: [PATCH 1/4] feat: display commit count instead of gitlab stars on the homepage --- src/routes/+page.server.ts | 8 +++++++- src/routes/+page.svelte | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts index 2ce74a2..d3beb6c 100644 --- a/src/routes/+page.server.ts +++ b/src/routes/+page.server.ts @@ -6,6 +6,7 @@ let starCount = 0; let roleMembers = { "1214817156420862012": 50, }; +let gitCommits = 0; async function fetchServerSideData() { console.log("Fetching member count"); @@ -26,18 +27,22 @@ async function fetchServerSideData() { }, }) : Promise.resolve({ json: () => ({ star_count: 0 }) }), // Default to 0 if no token is provided + fetch('https://git.suyu.dev/api/v1/repos/suyu/suyu/commits?stat=false&verification=false&files=false&limit=1') ]; - const [res, roles, gitlabRes] = await Promise.all(promises); + const [res, roles, gitlabRes, suyuGitRes] = await Promise.all(promises); const jsonPromises = [res.json(), roles.json(), gitlabRes.json()]; const [resJson, rolesJson, gitlabResJson] = await Promise.all(jsonPromises); + memberCount = resJson.approximate_member_count; starCount = gitlabResJson.star_count; + gitCommits = parseInt(suyuGitRes?.headers?.get('x-total'), 10) || 0; if (DISCORD_USER_TOKEN) roleMembers = rolesJson; console.log("Member count:", memberCount); console.log("Stars count:", starCount); + console.log('Git commit count', gitCommits); } if (!building) { @@ -52,5 +57,6 @@ export async function load({ cookies }) { memberCount, starCount, roleMembers, + gitCommits }; } diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 7447cf2..e5cd94b 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -10,6 +10,7 @@ $: memberCount = parseFloat(data.memberCount?.toPrecision(2)); $: contributors = parseFloat(data.roleMembers["1214817156420862012"]?.toPrecision(2)); $: starCount = parseFloat(data.starCount?.toPrecision(2)); + $: gitCommits = parseFloat(data.gitCommits?.toPrecision(2)); let metadata = { url: "https://suyu.dev", title: "suyu - Open-source, non-profit Switch emulator", @@ -116,7 +117,7 @@ >

By the numbers

- + From f27bd3a3450b8e1f037a573c8387d243dc297f19 Mon Sep 17 00:00:00 2001 From: Zekerocks011 <59491890+Zekerocks011@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:30:43 -0400 Subject: [PATCH 2/4] Added Titles to All Links & Added a Temporary Link To Compatibility Google Sheet --- +layout.svelte | 445 +++++++++++++++++++++++++++++++++++++++++++++++++ +page.svelte | 279 +++++++++++++++++++++++++++++++ 2 files changed, 724 insertions(+) create mode 100644 +layout.svelte create mode 100644 +page.svelte diff --git a/+layout.svelte b/+layout.svelte new file mode 100644 index 0000000..90b8af6 --- /dev/null +++ b/+layout.svelte @@ -0,0 +1,445 @@ + + + +{#if navigator.userAgent.indexOf("Firefox") === -1} +
+ +
+{/if} + +
+
+ +
+
+ +
+
+ +
+
+
+ + {#each navItems as item, i} + toggleDropdown()} + > +

{item.name}

+
+ {/each} +
+
+ + {#key data.url} +
+ +
+ {/key} +
diff --git a/+page.svelte b/+page.svelte new file mode 100644 index 0000000..81ea910 --- /dev/null +++ b/+page.svelte @@ -0,0 +1,279 @@ + + + + {metadata.title} + + + + + + + + + + + + + + +
+ + + + +

+ suyu is a fully open-source + Switch emulator +

+

+ suyu is a familiar C++ based Switch emulator with a focus on compatibility. Completely free + and open-source, forever. +

+ +
+ +
+
+

By the numbers

+ + + + +
+
+
+
+ +
+
+
+
+ +
+

+ Built by and for the community +

+

+ The future of suyu is shaped by you. New features are always being added, and our community + continually shapes the direction of the project. +

+
+ + + +
+

+ we’re passionate about preserving games. +

+

+ We’re developing suyu as a tool to prevent Switch games from becoming lost media, so we’re + taking care to prevent dissolution from outside influences. +

+
+
+ + + +

suyu is community-run.

+
+
+ + + +

suyu is completely free. There’s no option to monetarily support the project.

+
+
+ + + +

suyu exists solely as an effort of hardware preservation and research.

+
+
+ + + +

suyu does not condone nor facilitate piracy or intellectual property theft.

+
+
+
+ +
From 55b3dfd8daa5f1c07d0045b970b43d3995da03ba Mon Sep 17 00:00:00 2001 From: Zekerocks011 <59491890+Zekerocks011@users.noreply.github.com> Date: Tue, 26 Mar 2024 11:47:09 -0400 Subject: [PATCH 3/4] Update +layout.svelte Changed the FAQ titles from "Coming Soon" to "Frequently Asked Questions" --- +layout.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/+layout.svelte b/+layout.svelte index 90b8af6..5e0c69d 100644 --- a/+layout.svelte +++ b/+layout.svelte @@ -149,7 +149,7 @@ { name: "FAQ", href: "/faq", - title: "Coming Soon", + title: "Frequently Asked Questions", target: "_self", }, { @@ -309,7 +309,7 @@ > Blog Docs - FAQ + FAQ Compatibility
From 368e5ef0f3cbfdb5a67fb1ff024a076c744255f6 Mon Sep 17 00:00:00 2001 From: not-nullptr Date: Thu, 28 Mar 2024 13:34:06 +0000 Subject: [PATCH 4/4] fix page transitions --- src/lib/server/util/index.ts | 4 +- src/lib/util/api/index.ts | 4 +- src/routes/+page.svelte | 14 +++--- src/routes/account/+layout.svelte | 5 ++- src/routes/jwt/external/[audience]/+server.ts | 24 ++++++++++ src/routes/jwt/external/key.pem/+server.ts | 44 +++---------------- src/routes/jwt/internal/+server.ts | 2 +- src/routes/lobby/+server.ts | 8 ---- 8 files changed, 42 insertions(+), 63 deletions(-) create mode 100644 src/routes/jwt/external/[audience]/+server.ts diff --git a/src/lib/server/util/index.ts b/src/lib/server/util/index.ts index fb4030d..104afea 100644 --- a/src/lib/server/util/index.ts +++ b/src/lib/server/util/index.ts @@ -1,6 +1,6 @@ import type { IJwtData } from "$types/auth"; import type { Role } from "$types/db"; -import { PUBLIC_KEY } from "../secrets/secrets.json"; +import { PUB_KEY } from "$env/static/private"; import jwt from "jsonwebtoken"; export function json(body: T, status?: number): Response { @@ -14,7 +14,7 @@ export function json(body: T, status?: number): Response { export async function getJwtData(token: string): Promise { return new Promise((resolve, reject) => { - jwt.verify(token, PUBLIC_KEY, { algorithms: ["RS256"] }, (err, data) => { + jwt.verify(token, PUB_KEY, { algorithms: ["RS256"] }, (err, data) => { if (err) reject(err); else resolve(data as IJwtData); }); diff --git a/src/lib/util/api/index.ts b/src/lib/util/api/index.ts index b5c24e4..dbedfb6 100644 --- a/src/lib/util/api/index.ts +++ b/src/lib/util/api/index.ts @@ -1,6 +1,6 @@ import { userRepo } from "$lib/server/repo"; import type { SuyuUser } from "$lib/server/schema"; -import { PUBLIC_KEY } from "$lib/server/secrets/secrets.json"; +import { PUB_KEY } from "$env/static/private"; import type { IJwtData } from "$types/auth"; import cookie from "cookie"; import jwt from "jsonwebtoken"; @@ -18,7 +18,7 @@ export async function useAuth( } if (apiKey.startsWith("Bearer ")) { const token = apiKey.replace("Bearer ", ""); - const decoded: IJwtData = jwt.verify(token, Buffer.from(PUBLIC_KEY), { + const decoded: IJwtData = jwt.verify(token, Buffer.from(PUB_KEY), { algorithms: ["RS256"], }) as IJwtData; let user = await userRepo.findOne({ diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 7447cf2..4661e00 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -8,7 +8,7 @@ export let data: PageData; $: memberCount = parseFloat(data.memberCount?.toPrecision(2)); - $: contributors = parseFloat(data.roleMembers["1214817156420862012"]?.toPrecision(2)); + $: contributors = parseFloat(data.roleMembers?.["1214817156420862012"]?.toPrecision(2)); $: starCount = parseFloat(data.starCount?.toPrecision(2)); let metadata = { url: "https://suyu.dev", @@ -70,12 +70,8 @@ and open-source, forever.

- - Download + Download

Git

- Our Git instance is where all the magic of suyu happens. We're always looking for new contributors - to help us out, so feel free to check out our code. + Our Git instance is where all the magic of suyu happens. We're always looking for new + contributors to help us out, so feel free to check out our code.

(".navbar"); if (navBars.length !== 1) navBars.forEach((bar) => { @@ -52,6 +52,7 @@ const bounds = target.getBoundingClientRect(); const navBounds = navBar.getBoundingClientRect(); const pillBounds = indicator.getBoundingClientRect(); + if (ignoreAnimation) return; indicator.style.transform = `translateX(${bounds.left - navBounds.left}px)`; indicator.style.width = `${bounds.width}px`; if ( @@ -190,7 +191,7 @@ navClick(e, true)} class={`navitem flex flex-grow basis-[0] items-center justify-center whitespace-nowrap rounded-full px-4 py-2 text-sm font-bold ${ selected === i ? " text-[#a9a9a9] opacity-100" : "opacity-50" }`} diff --git a/src/routes/jwt/external/[audience]/+server.ts b/src/routes/jwt/external/[audience]/+server.ts new file mode 100644 index 0000000..9551a48 --- /dev/null +++ b/src/routes/jwt/external/[audience]/+server.ts @@ -0,0 +1,24 @@ +import { PRIVATE_KEY } from "$env/static/private"; +import { userRepo } from "$lib/server/repo/index.js"; +import { getJwtData } from "$lib/server/util/index.js"; +import { useAuth } from "$lib/util/api/index.js"; +import type { IJwtData } from "$types/auth.js"; +import jwt from "jsonwebtoken"; + +export async function POST({ request }) { + const jwtData = await getJwtData(request.headers.get("authorization")?.split(" ")[1] || ""); + const user = await userRepo.findOne({ + where: { + apiKey: jwtData.apiKey, + }, + }); + const token = jwt.sign({ ...user }, Buffer.from(PRIVATE_KEY), { + algorithm: "RS256", + }); + return new Response(token, { + status: 200, + headers: { + "content-type": "text/html", + }, + }); +} diff --git a/src/routes/jwt/external/key.pem/+server.ts b/src/routes/jwt/external/key.pem/+server.ts index ef8c292..a5815f2 100644 --- a/src/routes/jwt/external/key.pem/+server.ts +++ b/src/routes/jwt/external/key.pem/+server.ts @@ -1,45 +1,11 @@ -import { json } from "$lib/server/util/index.js"; +import { PUB_KEY } from "$env/static/private"; export function GET({ request }) { - return new Response( - `-----BEGIN CERTIFICATE----- -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ------END CERTIFICATE-----`, - { - headers: { - "content-type": "text/plain", - }, + return new Response(PUB_KEY, { + headers: { + "content-type": "text/plain", }, - ); + }); } export function POST({ request }) { diff --git a/src/routes/jwt/internal/+server.ts b/src/routes/jwt/internal/+server.ts index ba144e7..a880dce 100644 --- a/src/routes/jwt/internal/+server.ts +++ b/src/routes/jwt/internal/+server.ts @@ -1,4 +1,4 @@ -import { PRIVATE_KEY } from "$lib/server/secrets/secrets.json"; +import { PRIVATE_KEY } from "$env/static/private"; import { useAuth } from "$lib/util/api/index.js"; import jwt from "jsonwebtoken"; diff --git a/src/routes/lobby/+server.ts b/src/routes/lobby/+server.ts index bb80a7d..650989a 100644 --- a/src/routes/lobby/+server.ts +++ b/src/routes/lobby/+server.ts @@ -1,7 +1,6 @@ import { Room, RoomManager } from "$lib/server/class/Room"; import { userRepo } from "$lib/server/repo/index.js"; import { SuyuUser } from "$lib/server/schema"; -import { PUBLIC_KEY } from "$lib/server/secrets/secrets.json"; import { json } from "$lib/server/util"; import { useAuth } from "$lib/util/api/index.js"; import type { IJwtData } from "$types/auth.js"; @@ -65,12 +64,5 @@ export async function POST({ request, getClientAddress }) { host: user, hasPassword: body.hasPassword || false, }); - console.log("Room added:", JSON.stringify(room, null, 2)); - // push every room to the top which starts with `[SUYU OFFICIAL]` and was created with username "suyu" - const suyuRoom = RoomManager.rooms.find((r) => r.roomInfo.name.startsWith("[SUYU OFFICIAL]")); - if (suyuRoom && suyuRoom.host.username === "suyu") { - RoomManager.rooms.splice(RoomManager.rooms.indexOf(suyuRoom), 1); - RoomManager.rooms.unshift(suyuRoom); - } return json(room.toJSON()); }