Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .changeset/calm-pandas-write.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/fast-tigers-run.md

This file was deleted.

12 changes: 0 additions & 12 deletions .changeset/pre.json

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/quiet-mice-dance.md

This file was deleted.

30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
# Changelog

## 3.6.2

### Patch Changes

- Stop the production container restart loop caused by unhandled promise rejections under Node 24. Two changes: (1) the `/stats/[ign]/[[profile]]/card` endpoint now uses `Promise.allSettled` rather than `Promise.all` for the parallel `getProfileStats` / `getNetworth` / `getCombined` calls β€” when one rejects first, the losing-side promises no longer become orphaned rejections that crash the process. (2) A `process.on("unhandledRejection")` safety net in `instrumentation.server.ts` logs + reports any future orphans to Sentry instead of exiting, since Node 24's default `--unhandled-rejections=throw` is fatal. Combined this ends the ~2-minute restart cycle visible in production logs. ([#326](https://github.com/SkyCryptWebsite/SkyCrypt-Frontend/pull/326))

## 3.6.2-beta.0

### Patch Changes

- Stop the production container restart loop caused by unhandled promise rejections under Node 24. Two changes: (1) the `/stats/[ign]/[[profile]]/card` endpoint now uses `Promise.allSettled` rather than `Promise.all` for the parallel `getProfileStats` / `getNetworth` / `getCombined` calls β€” when one rejects first, the losing-side promises no longer become orphaned rejections that crash the process. (2) A `process.on("unhandledRejection")` safety net in `instrumentation.server.ts` logs + reports any future orphans to Sentry instead of exiting, since Node 24's default `--unhandled-rejections=throw` is fatal. Combined this ends the ~2-minute restart cycle visible in production logs. ([`9ffadbc`](https://github.com/SkyCryptWebsite/SkyCrypt-Frontend/commit/9ffadbcf6e4c5730756a06039dc23cf9a56eda98))

## 3.6.1

### Patch Changes

- Render the JSON-LD `<script type="application/ld+json">` block via `<svelte:element>` instead of `{@html}`, dropping the closing-tag-splitting workaround. The XSS-safe `safeJsonLd` escaping (`<` / `>` / `&`) is unchanged and still preserves data fidelity, so crawlers see exactly the same JSON content as before. ([#324](https://github.com/SkyCryptWebsite/SkyCrypt-Frontend/pull/324))

- Restore the card background and inline-emoji rendering after upgrading to `takumi-js@1.1.x`. The underlying Rust crate's commit `adc48da` ("Treat absolute/floated children as out-of-flow for inline layout detection") reworked which children participate in inline formatting context, leaving the previous `<img class="absolute inset-0">` background unrendered β€” which made the white text and emoji appear to vanish too. The persistent image is now applied as `background-image` CSS on the parent `<main>`, matching the pattern shown in the takumi docs. ([#324](https://github.com/SkyCryptWebsite/SkyCrypt-Frontend/pull/324))

- Escape JSON-LD payload so user-controlled fields (e.g. the `ign` URL parameter on stats pages) cannot break out of the `<script type="application/ld+json">` tag. `svelte-seo`'s `jsonLd` prop emits `JSON.stringify(data)` raw, and `JSON.stringify` does not escape `<`, `>` or `&` β€” so visiting `/stats/<script>alert(1)</script>` was enough to inject arbitrary HTML/JS into `<head>`. The new `JsonLd` component escapes those three characters to their unicode escapes (still valid JSON) before emitting the tag. ([#324](https://github.com/SkyCryptWebsite/SkyCrypt-Frontend/pull/324))

- Harden security headers against iframe-based phishing. The phishing site `sky.shiiiyu.moe` was embedding the real site in an invisible cross-origin iframe and rewriting `history.pushState` to disguise the URL bar. The fix layers three browser-enforced controls: `Content-Security-Policy: frame-ancestors 'self'` (modern browsers) and `X-Frame-Options: DENY` (older-browser fallback) refuse the iframe outright, and `Cross-Origin-Opener-Policy: same-origin` isolates the top-level browsing context group so a malicious opener cannot reach back via `window.opener`. The `/api/*` surface is unaffected β€” partner integrations (e.g., Lunar Client) that call the Go backend directly continue to work. ([#324](https://github.com/SkyCryptWebsite/SkyCrypt-Frontend/pull/324))

## 3.6.1-beta.2

### Patch Changes

- Harden security headers against iframe-based phishing. The phishing site `sky.shiiiyu.moe` was embedding the real site in an invisible cross-origin iframe and rewriting `history.pushState` to disguise the URL bar. The fix layers three browser-enforced controls: `Content-Security-Policy: frame-ancestors 'self'` (modern browsers) and `X-Frame-Options: DENY` (older-browser fallback) refuse the iframe outright, and `Cross-Origin-Opener-Policy: same-origin` isolates the top-level browsing context group so a malicious opener cannot reach back via `window.opener`. The `/api/*` surface is unaffected β€” partner integrations (e.g., Lunar Client) that call the Go backend directly continue to work. ([`43736ae`](https://github.com/SkyCryptWebsite/SkyCrypt-Frontend/commit/43736ae30e223ad18c6281484d728fafa2279365))

## 3.6.1-beta.1

### Patch Changes
Expand Down
5 changes: 3 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ ENV PUBLIC_SERVER_API_URL=$PUBLIC_SERVER_API_URL

COPY package*.json .
COPY pnpm-lock.yaml .
COPY pnpm-workspace.yaml .

RUN pnpm fetch
RUN pnpm install --frozen-lockfile
Expand All @@ -30,7 +31,7 @@ FROM node:24-alpine

ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable pnpm && corepack install -g pnpm@latest-10
RUN corepack enable pnpm && corepack install -g pnpm@latest-11

WORKDIR /app

Expand All @@ -42,4 +43,4 @@ COPY pnpm-lock.yaml .

EXPOSE 3000
ENV NODE_ENV=production
CMD ["pnpm", "run", "runbuild"]
CMD ["node", "./build"]
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
> This is a fork of [SkyCryptWebsite/SkyCrypt-Frontend](https://github.com/SkyCryptWebsite/SkyCrypt-Frontend) with minimal changes to support embedding the profile viewer in Lunar Client. To keep this fork up to date with upstream:
>
> ```
> git rebase upstream/dev
> # Resolve any conflicts that occur
> git push origin dev --force-with-lease
> ```

<p align="center">
<picture>
<source media="(prefers-color-scheme: light)" srcset="static/img/logo_black.avif">
Expand Down
46 changes: 24 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "skycrypt-frontend",
"version": "3.6.1-beta.1",
"version": "3.6.2",
"private": true,
"type": "module",
"repository": {
Expand Down Expand Up @@ -33,37 +33,38 @@
},
"devDependencies": {
"@changesets/cli": "^2.31.0",
"@commitlint/cli": "^21.0.0",
"@commitlint/config-conventional": "^21.0.0",
"@commitlint/types": "^21.0.0",
"@commitlint/cli": "^21.0.1",
"@commitlint/config-conventional": "^21.0.1",
"@commitlint/types": "^21.0.1",
"@date-fns/tz": "^1.4.1",
"@dnd-kit/abstract": "^0.4.0",
"@dnd-kit/dom": "^0.4.0",
"@dnd-kit/helpers": "^0.4.0",
"@dnd-kit/svelte": "^0.4.0",
"@eslint/compat": "^2.1.0",
"@eslint/js": "^10.0.1",
"@lucide/svelte": "^1.14.0",
"@lucide/svelte": "^1.16.0",
"@oslojs/crypto": "^1.0.1",
"@oslojs/encoding": "^1.1.0",
"@playwright/test": "^1.59.1",
"@playwright/test": "^1.60.0",
"@sveltejs/adapter-cloudflare": "^7.2.8",
"@sveltejs/adapter-node": "^5.5.4",
"@sveltejs/kit": "^2.59.1",
"@sveltejs/kit": "^2.60.1",
"@sveltejs/vite-plugin-svelte": "^7.1.2",
"@svitejs/changesets-changelog-github-compact": "^1.2.0",
"@tailwindcss/vite": "^4.3.0",
"@types/culori": "^4.0.1",
"@types/eslint": "^9.6.1",
"@types/node": "^25.6.2",
"@types/node": "^25.8.0",
"@types/relaxed-json": "^1.0.4",
"@types/upng-js": "^2.1.5",
"@vitest/browser-playwright": "^4.1.5",
"@vitest/coverage-v8": "^4.1.5",
"@vitest/ui": "^4.1.5",
"@vitest/browser-playwright": "^4.1.6",
"@vitest/coverage-v8": "^4.1.6",
"@vitest/ui": "^4.1.6",
"bits-ui": "^2.18.1",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
"devalue": "^5.8.0",
"devalue": "^5.8.1",
"dotenv-cli": "^11.0.0",
"eslint": "^10.3.0",
"eslint-config-prettier": "^10.1.8",
Expand All @@ -72,41 +73,42 @@
"globals": "^17.6.0",
"ky": "^2.0.2",
"numerable": "^0.3.15",
"orval": "^8.9.1",
"orval": "^8.10.0",
"paneforge": "^1.0.2",
"playwright": "^1.59.1",
"playwright": "^1.60.0",
"prettier": "^3.8.3",
"prettier-plugin-svelte": "^3.5.1",
"prettier-plugin-svelte": "^3.5.2",
"prettier-plugin-tailwindcss": "^0.8.0",
"pretty-ms": "^9.3.0",
"runed": "^0.37.1",
"satori-html": "^0.3.2",
"skinview3d": "^3.4.2",
"super-sitemap": "^1.0.12",
"svelte": "^5.55.5",
"svelte": "^5.55.7",
"svelte-check": "^4.4.8",
"svelte-persisted-store": "^0.12.0",
"svelte-preprocess": "^6.0.3",
"svelte-seo": "^2.0.0",
"svelte-sonner": "^1.1.1",
"svelte-tiny-virtual-list": "4.0.0-rc.2",
"sveltekit-superforms": "^2.30.1",
"tailwind-merge": "^3.5.0",
"tailwind-merge": "^3.6.0",
"tailwindcss": "^4.3.0",
"tailwindcss-motion": "^1.1.1",
"tslib": "^2.8.1",
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.2",
"typescript-eslint": "^8.59.3",
"vaul-svelte": "1.0.0-next.7",
"vite": "^8.0.11",
"vitest": "^4.1.5",
"vite": "^8.0.13",
"vitest": "^4.1.6",
"vitest-browser-svelte": "^2.1.1",
"zod": "^4.4.3"
},
"dependencies": {
"@sentry/sveltekit": "^10.52.0",
"@sentry/sveltekit": "^10.53.1",
"culori": "^4.0.2",
"simple-git-hooks": "^2.13.1",
"svelte-interactions": "^0.2.0",
"takumi-js": "1.1.2"
},
"engines": {
Expand All @@ -120,4 +122,4 @@
"simple-git-hooks": {
"commit-msg": "pnpm exec commitlint --edit $1"
}
}
}
Loading
Loading