diff --git a/.dvmrc b/.dvmrc index 59aa62c..f225a78 100644 --- a/.dvmrc +++ b/.dvmrc @@ -1 +1 @@ -2.4.5 +2.5.2 diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index 0ab708f..f1ead8a 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -22,7 +22,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Log in to the Container registry uses: docker/login-action@v3 diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 60de93d..3dcb742 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -10,7 +10,7 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Configure SSH run: | mkdir -p ~/.ssh/ diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2b3625c..4106457 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: denoland/setup-deno@v2 with: deno-version-file: .dvmrc diff --git a/Dockerfile b/Dockerfile index 3d5d754..40f2e8b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM denoland/deno:ubuntu-2.4.5 +FROM denoland/deno:ubuntu-2.5.2 EXPOSE 8000 @@ -9,8 +9,6 @@ WORKDIR /app # These steps will be re-run upon each file change in your working directory: ADD . /app -RUN rm -fr node_modules _fresh - # Build fresh RUN deno task build diff --git a/Makefile b/Makefile index cd10544..cc6dc94 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +SHELL := /bin/bash + .PHONY: start start: deno task start @@ -19,10 +21,6 @@ build: migrate-db: deno run --allow-net --allow-read --allow-env migrate-db.ts -.PHONY: crons/cleanup -crons/cleanup: - deno run --allow-net --allow-read --allow-env crons/cleanup.ts - .PHONY: exec-db exec-db: docker exec -it -u postgres $(shell basename $(CURDIR))-postgresql-1 psql diff --git a/bewcloud.config.sample.ts b/bewcloud.config.sample.ts index 3c176e0..84ffba8 100644 --- a/bewcloud.config.sample.ts +++ b/bewcloud.config.sample.ts @@ -3,7 +3,7 @@ import { Config, PartialDeep } from './lib/types.ts'; /** Check the Config type for all the possible options and instructions. */ const config: PartialDeep = { auth: { - baseUrl: 'http://localhost:8000', // The base URL of the application you use to access the app, i.e. "http://localhost:8000" or "https://cloud.example.com" (SSO redirect, if enabled, will be this + /oidc/callback, so "https://cloud.example.com/oidc/callback") + baseUrl: 'http://localhost:8000', // The base URL of the application you use to access the app, i.e. "http://localhost:8000" or "https://cloud.example.com" (note authentication won't work without https:// except for localhost; SSO redirect, if enabled, will be this + /oidc/callback, so "https://cloud.example.com/oidc/callback") allowSignups: false, // If true, anyone can sign up for an account. Note that it's always possible to sign up for the first user, and they will be an admin enableEmailVerification: false, // If true, email verification will be required for signups (using SMTP settings below) enableForeverSignup: true, // If true, all signups become active for 100 years diff --git a/components/expenses/ExpenseModal.tsx b/components/expenses/ExpenseModal.tsx index a7dc10f..ca35c0d 100644 --- a/components/expenses/ExpenseModal.tsx +++ b/components/expenses/ExpenseModal.tsx @@ -191,7 +191,6 @@ export default function ExpenseModal( onChange={(event) => { newExpenseBudget.value = event.currentTarget.value; }} - placeholder='Misc' > {sortedBudgetNames.map((budget) => ( diff --git a/components/expenses/ListBudgets.tsx b/components/expenses/ListBudgets.tsx index 7ab9f6c..3f6a647 100644 --- a/components/expenses/ListBudgets.tsx +++ b/components/expenses/ListBudgets.tsx @@ -1,6 +1,6 @@ import { useSignal } from '@preact/signals'; import { useEffect, useRef } from 'preact/hooks'; -import { Chart } from 'chart.js'; +import { Chart } from 'chart.js/auto'; import { formatNumber } from '/lib/utils/misc.ts'; import { Budget, SupportedCurrencySymbol } from '/lib/types.ts'; diff --git a/components/files/ListFiles.tsx b/components/files/ListFiles.tsx index 18a80e4..371e526 100644 --- a/components/files/ListFiles.tsx +++ b/components/files/ListFiles.tsx @@ -1,4 +1,4 @@ -import { join } from 'std/path/join.ts'; +import { join } from '@std/path'; import { Directory, DirectoryFile } from '/lib/types.ts'; import { humanFileSize, TRASH_PATH } from '/lib/utils/files.ts'; diff --git a/components/files/ListPhotos.tsx b/components/files/ListPhotos.tsx index 0ab9660..40b00b4 100644 --- a/components/files/ListPhotos.tsx +++ b/components/files/ListPhotos.tsx @@ -1,7 +1,7 @@ import { Directory, DirectoryFile } from '/lib/types.ts'; import { humanFileSize, TRASH_PATH } from '/lib/utils/files.ts'; -interface ListFilesProps { +interface ListPhotosProps { directories: Directory[]; files: DirectoryFile[]; onClickOpenRenameDirectory?: (parentPath: string, name: string) => void; @@ -13,7 +13,7 @@ interface ListFilesProps { isShowingNotes?: boolean; } -export default function ListFiles( +export default function ListPhotos( { directories, files, @@ -24,7 +24,7 @@ export default function ListFiles( onClickDeleteDirectory, onClickDeleteFile, isShowingNotes, - }: ListFilesProps, + }: ListPhotosProps, ) { const dateFormatOptions: Intl.DateTimeFormatOptions = { year: 'numeric', diff --git a/crons/index.ts b/crons/index.ts index 5f0b162..d475efb 100644 --- a/crons/index.ts +++ b/crons/index.ts @@ -1,4 +1,4 @@ -import { Cron } from 'https://deno.land/x/croner@8.1.2/dist/croner.js'; +import { Cron } from '@hexagon/croner'; import { AppConfig } from '/lib/config.ts'; import { cleanupSessions } from './sessions.ts'; diff --git a/deno.json b/deno.json index 76419da..60e9c90 100644 --- a/deno.json +++ b/deno.json @@ -1,13 +1,12 @@ { "lock": false, "tasks": { - "check": "deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx", + "check": "deno fmt --check && deno lint && deno check .", "cli": "echo \"import '\\$fresh/src/dev/cli.ts'\" | deno run --unstable -A -", "manifest": "deno task cli manifest $(pwd)", "start": "deno run -A --watch=static/,routes/,lib/,components/,islands/ dev.ts", "build": "deno run -A dev.ts build", "preview": "deno run -A main.ts", - "update": "deno run -A -r https://fresh.deno.dev/update .", "test": "deno test -A --check" }, "fmt": { @@ -16,13 +15,14 @@ "indentWidth": 2, "singleQuote": true, "proseWrap": "preserve", - "exclude": ["README.md"] + "exclude": ["README.md", "lib/models/dav.js"] }, "lint": { "rules": { "tags": ["fresh", "recommended"], "exclude": ["no-explicit-any", "no-empty-interface", "no-window", "no-unused-vars"] - } + }, + "exclude": ["lib/models/dav.js"] }, "exclude": ["./_fresh/*", "./node_modules/*", "**/_fresh/*"], "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "preact" }, @@ -30,28 +30,36 @@ "imports": { "/": "./", "./": "./", - "xml": "https://deno.land/x/xml@2.1.3/mod.ts", - "mrmime": "https://deno.land/x/mrmime@v2.0.0/mod.ts", + "fresh/": "https://deno.land/x/fresh@1.7.3/", "$fresh/": "https://deno.land/x/fresh@1.7.3/", - "std/": "https://deno.land/std@0.224.0/", - "$std/": "https://deno.land/std@0.224.0/", - "postgres": "https://deno.land/x/postgres@v0.19.3/mod.ts", - "preact": "https://esm.sh/preact@10.23.2", - "preact/": "https://esm.sh/preact@10.23.2/", - "@preact/signals": "https://esm.sh/*@preact/signals@1.3.0", - "@preact/signals-core": "https://esm.sh/*@preact/signals-core@1.8.0", - "chart.js": "https://esm.sh/chart.js@4.4.9/auto", - "otpauth": "https://esm.sh/otpauth@9.4.0", - "qrcode": "https://esm.sh/qrcode@1.5.4", - "openid-client": "https://esm.sh/openid-client@6.6.3", - "@simplewebauthn/server": "jsr:@simplewebauthn/server@13.1.2", - "@simplewebauthn/server/helpers": "jsr:@simplewebauthn/server@13.1.2/helpers", - "@simplewebauthn/browser": "jsr:@simplewebauthn/browser@13.1.2", + + "postgres": "jsr:@db/postgres@0.19.5", + "@b-fuze/deno-dom": "jsr:@b-fuze/deno-dom@0.1.56", + "@fresh/plugin-vite": "jsr:@fresh/plugin-vite@1.0.4", + "@hexagon/croner": "jsr:@hexagon/croner@9.1.0", + "@mikaelporttila/rss": "jsr:@mikaelporttila/rss@1.1.3", + "@libs/qrcode": "jsr:@libs/qrcode@3.0.0", + "@libs/xml": "jsr:@libs/xml@7.0.2", + "@simplewebauthn/server": "jsr:@simplewebauthn/server@13.2.1", + "@simplewebauthn/browser": "jsr:@simplewebauthn/browser@13.2.0", + "@std/assert": "jsr:@std/assert@1.0.14", + "@std/dotenv": "jsr:@std/dotenv@0.225.5", + "@std/encoding": "jsr:@std/encoding@1.0.10", + "@std/http": "jsr:@std/http@1.0.20", + "@std/path": "jsr:@std/path@1.1.2", + + "chart.js": "npm:chart.js@4.5.0", + "mrmime": "npm:mrmime@2.0.1", + "nodemailer": "npm:nodemailer@7.0.6", + "openid-client": "npm:openid-client@6.8.0", + "otpauth": "npm:otpauth@9.4.1", + "preact": "npm:preact@10.27.2", + "sharp": "npm:sharp@0.34.4", "tailwindcss": "npm:tailwindcss@3.4.17", "tailwindcss/": "npm:/tailwindcss@3.4.17/", "tailwindcss/plugin": "npm:/tailwindcss@3.4.17/plugin.js", - "nodemailer": "npm:nodemailer@7.0.5", - "tsdav": "https://raw.githubusercontent.com/sunsama/tsdav/cc1c5a09b64c87bbee7e5f171cfcb6748e99469e/dist/tsdav.js" + "vite": "npm:vite@7.1.7", + "@preact/signals": "npm:@preact/signals@2.3.1" } } diff --git a/dev.ts b/dev.ts index 43f077b..d3dc519 100755 --- a/dev.ts +++ b/dev.ts @@ -3,6 +3,6 @@ import dev from 'fresh/dev.ts'; import config from './fresh.config.ts'; -import 'std/dotenv/load.ts'; +import '@std/dotenv/load'; await dev(import.meta.url, './main.ts', config); diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 9384e3a..4508456 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -18,7 +18,7 @@ services: # NOTE: If you don't want to use the CardDav/CalDav servers, you can comment/remove this service. radicale: - image: tomsquest/docker-radicale:3.5.4.0 + image: tomsquest/docker-radicale:3.5.6.0 ports: - 5232:5232 init: true diff --git a/docker-compose.yml b/docker-compose.yml index afb9756..cb4a8cf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ services: website: - image: ghcr.io/bewcloud/bewcloud:v2.5.3 + image: ghcr.io/bewcloud/bewcloud:v2.6.0 restart: always ports: - 127.0.0.1:8000:8000 @@ -32,7 +32,7 @@ services: # NOTE: If you don't want to use the CardDav/CalDav servers, you can comment/remove this service. radicale: - image: tomsquest/docker-radicale:3.5.4.0 + image: tomsquest/docker-radicale:3.5.6.0 # NOTE: uncomment below only if you need to connect to the CardDav/CalDav servers from outside the container # ports: # - 127.0.0.1:5232:5232 diff --git a/islands/auth/MultiFactorAuthSettings.tsx b/islands/auth/MultiFactorAuthSettings.tsx index fe19084..67336da 100644 --- a/islands/auth/MultiFactorAuthSettings.tsx +++ b/islands/auth/MultiFactorAuthSettings.tsx @@ -391,8 +391,8 @@ export default function MultiFactorAuthSettings({ methods }: MultiFactorAuthSett

1. Scan this QR code with your authenticator app (Aegis Authenticator, Google Authenticator, etc.):

-
- TOTP QR Code +
+ TOTP QR Code

Or manually enter this secret:{' '} diff --git a/lib/auth.ts b/lib/auth.ts index 0dc8ecf..4b453bb 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -1,7 +1,6 @@ -import { decodeBase64Url, encodeBase64Url } from 'std/encoding/base64url.ts'; -import { decodeBase64 } from 'std/encoding/base64.ts'; -import { Cookie, getCookies, setCookie } from 'std/http/cookie.ts'; -import 'std/dotenv/load.ts'; +import { decodeBase64, decodeBase64Url, encodeBase64Url } from '@std/encoding'; +import { Cookie, getCookies, setCookie } from '@std/http'; +import '@std/dotenv/load'; import { generateHash, isRunningLocally } from './utils/misc.ts'; import { User, UserSession } from './types.ts'; diff --git a/lib/feed.ts b/lib/feed.ts index b24b795..0759f8a 100644 --- a/lib/feed.ts +++ b/lib/feed.ts @@ -1,5 +1,5 @@ -import { DOMParser, initParser } from 'https://deno.land/x/deno_dom@v0.1.45/deno-dom-wasm-noinit.ts'; -import { Feed, parseFeed } from 'https://deno.land/x/rss@1.0.0/mod.ts'; +import { DOMParser, initParser } from '@b-fuze/deno-dom/wasm-noinit'; +import { Feed, parseFeed } from '@mikaelporttila/rss'; import { fetchUrl, fetchUrlAsGooglebot, fetchUrlWithProxy, fetchUrlWithRetries } from './utils/misc.ts'; import { NewsFeed, NewsFeedCrawlType, NewsFeedType } from './types.ts'; diff --git a/lib/form-utils.tsx b/lib/form-utils.tsx index da61512..e1763c5 100644 --- a/lib/form-utils.tsx +++ b/lib/form-utils.tsx @@ -124,7 +124,7 @@ function generateInputHtml( if (type === 'select') { return ( - {options?.map((option) => (