Harden sync and security; add IQ Bible, templates, password reset, backups
Build and Push Docker Image / build-and-push (push) Successful in 7m14s
Build and Push Docker Image / build-and-push (push) Successful in 7m14s
Sync and data safety - Autosave flushes on leaving a study or the tab; storage-full errors are reported - Unsynced studies, deletes and ink are queued and retried when back online - Deletes propagate across devices (with a "Keep it" undo) and no longer resurrect - Server assigns study versions (no client-clock conflicts); "Combine both" merges a conflicted study chunk by chunk - Reading-plan progress made offline is merged, not overwritten; plans, ink and marks are cleared from the device on sign-out Security - Block SSRF through the ntfy reminder URL; failure-only rate limiting per IP and account; constant-time login; TOTP replay protection; input validation; SESSION_SECRET required in production; admin user delete fixed - Forgot password: one-time code sent to the account's ntfy topic Features - IQ Bible proxy (route allow-list, text-only caching per its terms): more commentaries, lexicons, study aids, daily verse and devotional, plan calendar export, narrations, podcast background - Study templates, reading-plan catch-up, account export, daily database snapshots Tests and tooling - ESLint config; App tests split into src/test; tests for sync queues, library hook, merge, templates, IQ Bible UI and reset form Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6bb392933a
commit
f274bc9c8a
67 files changed
+4734
-1569
No files matched your search
@@ -5,11 +5,11 @@ import { vi, test, expect } from 'vitest';
|
||||
const noop = () => {};
|
||||
const ctx = {
|
||||
goHome: noop,
|
||||
readerBookAbbrev: 'JHN', setReaderBookAbbrev: noop,
|
||||
readerBookAbbrev: 'JHN', setReaderBookAbbrev: vi.fn(),
|
||||
readerTranslation: 'ESV', setReaderTranslation: noop,
|
||||
readerTheme: 'paper', setReaderTheme: noop, readerCommentary: 'matthew-henry', setReaderCommentary: noop,
|
||||
readerLayout: 'flow', setReaderLayout: noop,
|
||||
readerChapter: 3, setReaderChapter: noop,
|
||||
readerChapter: 3, setReaderChapter: vi.fn(),
|
||||
readerVerses: [{ number: 1, text: 'Now there was a man of the Pharisees.' }, { number: 2, text: 'This man came to Jesus by night.' }],
|
||||
readerTotalChapters: 21, readerLoading: false, readerError: '',
|
||||
readerInterlinear: null, readerSelectedVerse: null, setReaderSelectedVerse: vi.fn(),
|
||||
@@ -28,7 +28,6 @@ const ctx = {
|
||||
readerInkByPage: {}, updateReaderPageInk: noop, readerTextHighlights: [], addTextHighlight: noop, removeTextHighlight: noop,
|
||||
planProgress: [], toggleDay: vi.fn(), toggleChapterRead: vi.fn(), readingActivity: [],
|
||||
readerPlan: null, setReaderPlan: vi.fn(), openPlanReading: vi.fn(), studyReadingPlanDay: vi.fn(), studyBuildBusy: false,
|
||||
setReaderBookAbbrev: vi.fn(), setReaderChapter: vi.fn(),
|
||||
};
|
||||
vi.mock('../context/AppContext.js', () => ({ useApp: () => ctx }));
|
||||
|
||||
|
||||
Reference in new issue
Block a user