Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 28e2eab5ba | |||
| 439784bdbb | |||
| a773df9c46 | |||
| b80ad26a15 | |||
| 862b12c444 | |||
| f6434af4a2 | |||
| 4ad394b70b | |||
| 5d8237386d | |||
| d11cdce8b5 | |||
| db8fa8928d | |||
| 5777e4910e | |||
| 58ccce0d71 | |||
| e862a75fd0 | |||
| 70fc51ed01 | |||
| c02a11bf27 | |||
| 36f71cb4a9 | |||
| 8c70f3cfe8 |
@@ -39,3 +39,20 @@ jobs:
|
|||||||
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
|
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
--data @-
|
--data @-
|
||||||
|
|
||||||
|
- name: Trigger Komodo build
|
||||||
|
env:
|
||||||
|
KOMODO_WEBHOOK_URL: https://komodo.urania.dev/listener/github/build/urania_builder_nadir
|
||||||
|
KOMODO_WEBHOOK_SECRET: ${{ secrets.KOMODO_WEBHOOK_SECRET }}
|
||||||
|
run: |
|
||||||
|
# Komodo's GitHub listener requires `ref` + a matching HMAC signature.
|
||||||
|
BODY=$(jq -nc --arg sha "$GITHUB_SHA" \
|
||||||
|
'{ref:"refs/heads/main", after:$sha,
|
||||||
|
repository:{full_name:"${{ github.repository }}",
|
||||||
|
clone_url:"${{ github.server_url }}/${{ github.repository }}.git"}}')
|
||||||
|
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$KOMODO_WEBHOOK_SECRET" -hex | awk '{print $NF}')
|
||||||
|
curl -fsSL -X POST "$KOMODO_WEBHOOK_URL" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "X-GitHub-Event: push" \
|
||||||
|
-H "X-Hub-Signature-256: sha256=$SIG" \
|
||||||
|
-d "$BODY"
|
||||||
|
|||||||
+2
-1
@@ -28,4 +28,5 @@ project.inlang/cache/
|
|||||||
*.db
|
*.db
|
||||||
CONTEXT.md
|
CONTEXT.md
|
||||||
build.sh
|
build.sh
|
||||||
.claude
|
.claude
|
||||||
|
release.sh
|
||||||
+13
@@ -12,6 +12,19 @@ COPY . .
|
|||||||
RUN bun run build
|
RUN bun run build
|
||||||
|
|
||||||
FROM base AS release
|
FROM base AS release
|
||||||
|
ARG VERSION=dev
|
||||||
|
ARG REVISION=unknown
|
||||||
|
ARG CREATED
|
||||||
|
LABEL org.opencontainers.image.title="nadir" \
|
||||||
|
org.opencontainers.image.description="SvelteKit dashboard for nadir-agent — central web console for Nadir backend nodes." \
|
||||||
|
org.opencontainers.image.documentation="https://nadir.urania.dev/docs" \
|
||||||
|
org.opencontainers.image.url="https://tea.urania.dev/urania/nadir-webui" \
|
||||||
|
org.opencontainers.image.source="https://tea.urania.dev/urania/nadir-webui" \
|
||||||
|
org.opencontainers.image.authors="Mirko Isaia <m.isaia@urania.dev>" \
|
||||||
|
org.opencontainers.image.licenses="MIT" \
|
||||||
|
org.opencontainers.image.version="${VERSION}" \
|
||||||
|
org.opencontainers.image.revision="${REVISION}" \
|
||||||
|
org.opencontainers.image.created="${CREATED}"
|
||||||
ENV NODE_ENV=production \
|
ENV NODE_ENV=production \
|
||||||
DATABASE_URL=/app/data/db.sqlite \
|
DATABASE_URL=/app/data/db.sqlite \
|
||||||
HOST=0.0.0.0 \
|
HOST=0.0.0.0 \
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "clean",
|
"name": "clean",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.6.0",
|
"version": "0.7.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:types": "bun run type:generate && bun --bun vite dev --host",
|
"dev:types": "bun run type:generate && bun --bun vite dev --host",
|
||||||
|
|||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Cut a release: bump package.json, tag, push.
|
|
||||||
# Gitea Actions creates the release; Komodo builds & pushes the image via webhook.
|
|
||||||
# Usage: ./release.sh [patch|minor|major] (default: patch)
|
|
||||||
set -euo pipefail
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
|
|
||||||
BUMP="${1:-patch}"
|
|
||||||
[ -z "$(git status --porcelain)" ] || { echo "working tree dirty, commit first"; exit 1; }
|
|
||||||
|
|
||||||
# bumps version in package.json AND creates commit + tag vX.Y.Z
|
|
||||||
bun pm version "$BUMP"
|
|
||||||
git push --follow-tags
|
|
||||||
|
|
||||||
echo "released v$(bun -e 'console.log(require("./package.json").version)')"
|
|
||||||
+32
-1
@@ -5,9 +5,11 @@ import { getAuth } from '$lib/auth/server';
|
|||||||
import { getTextDirection } from '$lib/paraglide/runtime';
|
import { getTextDirection } from '$lib/paraglide/runtime';
|
||||||
import { paraglideMiddleware } from '$lib/paraglide/server';
|
import { paraglideMiddleware } from '$lib/paraglide/server';
|
||||||
import { getConfig } from '$lib/server/config';
|
import { getConfig } from '$lib/server/config';
|
||||||
|
import { db } from '$lib/server/db';
|
||||||
import { svelteKitHandler } from 'better-auth/svelte-kit';
|
import { svelteKitHandler } from 'better-auth/svelte-kit';
|
||||||
|
import { randomBytes } from 'node:crypto';
|
||||||
|
|
||||||
export const init: ServerInit = () => {
|
export const init: ServerInit = async () => {
|
||||||
const env = process.env;
|
const env = process.env;
|
||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
|
|
||||||
@@ -20,6 +22,34 @@ export const init: ServerInit = () => {
|
|||||||
|
|
||||||
if (errors.length)
|
if (errors.length)
|
||||||
throw new Error(`Invalid environment:\n - ${errors.join('\n - ')}`);
|
throw new Error(`Invalid environment:\n - ${errors.join('\n - ')}`);
|
||||||
|
|
||||||
|
// Bootstrap an admin if the user table is empty.
|
||||||
|
const userCount = db.$client.prepare('SELECT COUNT(*) AS c FROM user').get() as { c: number };
|
||||||
|
if (userCount.c > 0) return;
|
||||||
|
|
||||||
|
const username = env.ADMIN_USERNAME?.trim() || 'admin';
|
||||||
|
const email = env.ADMIN_EMAIL?.trim() || `${username}@example.com`;
|
||||||
|
const provided = env.ADMIN_PASSWORD?.trim();
|
||||||
|
const password = provided || randomBytes(18).toString('base64url');
|
||||||
|
|
||||||
|
await getAuth().api.createUser({
|
||||||
|
body: {
|
||||||
|
data: { displayUsername: username, emailVerified: true, username },
|
||||||
|
email,
|
||||||
|
name: username,
|
||||||
|
password,
|
||||||
|
role: 'admin'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const line = '━'.repeat(64);
|
||||||
|
if (provided) {
|
||||||
|
console.log(`${line}\nBootstrap admin "${username}" created (ADMIN_PASSWORD).\n${line}`);
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
`${line}\nBootstrap admin created — sign in with these and rotate immediately:\n username: ${username}\n password: ${password}\nSet ADMIN_PASSWORD env to pick your own.\n${line}`
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBetterAuth: Handle = async ({ event, resolve }) => {
|
const handleBetterAuth: Handle = async ({ event, resolve }) => {
|
||||||
@@ -33,6 +63,7 @@ const handleBetterAuth: Handle = async ({ event, resolve }) => {
|
|||||||
event.locals.session = session.session;
|
event.locals.session = session.session;
|
||||||
event.locals.user = session.user;
|
event.locals.user = session.user;
|
||||||
} else if (
|
} else if (
|
||||||
|
event.url.pathname !== "/" &&
|
||||||
!event.url.pathname.startsWith('/auth') &&
|
!event.url.pathname.startsWith('/auth') &&
|
||||||
!event.url.pathname.startsWith('/api/auth') &&
|
!event.url.pathname.startsWith('/api/auth') &&
|
||||||
event.url.pathname !== '/install.sh'
|
event.url.pathname !== '/install.sh'
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export const load = () => {};
|
||||||
+4
-1
@@ -5,11 +5,14 @@ import adapter from 'svelte-adapter-bun';
|
|||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
build: {
|
||||||
|
rollupOptions: { external: ['async_hooks'] }
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
tailwindcss(),
|
tailwindcss(),
|
||||||
sveltekit({
|
sveltekit({
|
||||||
adapter: adapter({
|
adapter: adapter({
|
||||||
precompress:true
|
precompress: true
|
||||||
}),
|
}),
|
||||||
compilerOptions: {
|
compilerOptions: {
|
||||||
experimental: { async: true },
|
experimental: { async: true },
|
||||||
|
|||||||
Reference in New Issue
Block a user