Skip to content

About

Family task schedule PWA with peer-to-peer sync via WebRTC. Zero servers zero cloud. All data stored locally. Admin approval gate. Arabic-first.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

17 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“… Task Schedule β€” Ψ§Ω„ΨΉΨ§Ψ¦Ω„Ψ©

A family task schedule that syncs peer-to-peer between your devices β€” no servers, no cloud, no third-party services.

πŸ”— App: https://alihkhawaher.github.io/task-schedule/

πŸ“¦ Source Code: https://github.com/Alihkhawaher/task-schedule

How it works

  • Devices connect directly via WebRTC (Trystero + Nostr for signaling)
  • All data stored in browser localStorage β€” you own everything
  • Sync happens between your devices only β€” nothing leaves your network
  • No CDN, no external dependencies β€” everything bundled locally, works fully offline
  • Installable PWA β€” works on phones, tablets, and desktops
  • Runs from GitHub Pages β€” no server, no build step, no deployment needed

Privacy

Zero telemetry. Zero analytics. Zero tracking. Your data never leaves your devices.

Core Philosophy

  1. Standalone β€” No external service dependencies. All libraries bundled locally. Works offline.
  2. Data is everything β€” Multiple persistence layers (memory, localStorage, P2P sync). Data survives everything.
  3. P2P is core β€” Devices connect directly via WebRTC (Trystero). No cloud, no servers, no middleman.
  4. User control β€” No telemetry, no tracking. You own your data, your devices, your network.

How P2P Works

Uses Trystero library for WebRTC peer-to-peer connections via Nostr network signaling:

  • Nostr relays are used only for peer discovery (signaling)
  • Actual data flows directly between devices via WebRTC (encrypted)
  • Both devices must be online simultaneously for connection
  • Once connected, data syncs in real-time

Connecting a new device:

  1. Existing device β†’ click "Ω…Ψ΄Ψ§Ψ±ΩƒΨ© Ψ§Ω„Ψ¬Ω‡Ψ§Ψ²" (Share Device) β†’ copy link or show QR
  2. New device β†’ open link β†’ auto-fills family code
  3. New device logs in β†’ admin approves β†’ P2P connects
  4. Family data syncs automatically

Requirements:

  • Both devices on the same WiFi (or internet for cross-network)
  • Both devices must have the app open at the same time for initial connection

Features

  • πŸ“… Calendar view β€” month and week (7-day) views with color-coded user avatars
  • πŸ‘€ User dashboard β€” tap any avatar to see per-task progress bars and overall completion
  • πŸ“‹ Per-user tasks β€” each task is assigned to one user with start/end dates and weekday schedule
  • πŸ”„ Day detail panel β€” tap a day to see all users' tasks with checkboxes
  • πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Multi-family support β€” each family has isolated data
  • πŸ”„ P2P mesh sync via Trystero/WebRTC β€” no server needed
  • πŸ” PIN-based check-in with configurable grace period
  • πŸ“Š Start date β€” schedule begins from your chosen date
  • πŸ’Ύ localStorage backup β€” data persists locally
  • πŸ“· QR code + share link device discovery
  • πŸ“± Device naming β€” name each device (e.g., "Ω‡Ψ§Ψͺف Ψ§Ω„Ψ£Ψ¨") visible to other peers
  • 🌐 Runs on GitHub Pages β€” no server or deployment needed, just open the link
  • πŸ“¦ Complete package β€” no CDN, all libraries, fonts, and icons bundled locally

Quick Start

1. Open the app

Open https://alihkhawaher.github.io/task-schedule/ in your browser.

2. Create your family

Enter family name + your name + PIN β†’ get family code + recovery code.

3. Share with family

Click "Ω…Ψ΄Ψ§Ψ±ΩƒΨ© Ψ§Ω„Ψ¬Ω‡Ψ§Ψ²" β†’ share the link or QR code with family members.

4. Family members join

Open shared link β†’ family code auto-fills β†’ enter name + PIN β†’ admin approves β†’ start using.

Data Protection

Layer What Survives
In-memory JS objects Current session
localStorage Browser storage Logout, refresh, restart
P2P peers Other devices' storage Device offline

PIN Security

Action Always asks? Grace period
Enter settings βœ… Yes No
Settings actions No Yes (refreshes)
Data reset βœ… Yes No

File Structure

β”œβ”€β”€ index.html              # Login page (Create Family + Connection)
β”œβ”€β”€ manifest.json           # PWA manifest
β”œβ”€β”€ README.md               # This file
β”œβ”€β”€ app-design.md           # Comprehensive design document
β”œβ”€β”€ mockup/
β”‚   └── calendar.html       # Calendar view mockup
└── app/
    β”œβ”€β”€ index.html          # Main app (calendar + settings overlay)
    β”œβ”€β”€ app.js              # Core logic (calendar, P2P broadcast, task check-in)
    β”œβ”€β”€ config.js           # Settings logic (users, per-user tasks, PIN, device name)
    β”œβ”€β”€ p2p.js              # Trystero/WebRTC P2P module
    β”œβ”€β”€ styles.css          # Styles (calendar, avatars, panels, RTL)
    β”œβ”€β”€ icons/              # SVG icons for PWA manifest
    └── libs/               # All dependencies (bundled locally)

Technology Stack

Component Technology Purpose
P2P Trystero (Nostr + WebRTC) Direct browser-to-browser sync
Database Gun.js (local only) Local data structure
Auth Web Crypto API (SHA-256) PIN hashing
UI Bootstrap 5 + Tajawal Arabic-first responsive design
QR qrcode.js Device discovery
PWA Web App Manifest Installable on mobile and desktop
Hosting GitHub Pages Free static hosting, no server needed

Security Model

The app implements a three-layer security model designed for a family P2P app where all approved members are trusted.

Layer 1: Random Room ID (Network Privacy)

When a family is created, a cryptographically random room ID (32 bytes, hex-encoded) is generated using crypto.getRandomValues(). This room ID is used as the Trystero/WebRTC room name β€” not the human-readable family code. Nostr relay operators see only a random hex string.

Layer 2: Admin Approval Gate (Data Protection)

When a new device joins the Trystero room, it does NOT receive any family data automatically. Instead:

New Device                          Admin Device
    β”‚                                    β”‚
    β”œβ”€β”€ Joins room (via room ID) ─────────
    β”œβ”€β”€ Sends "join-request" ───────────→│
    β”‚                                    β”œβ”€β”€ Shows approval dialog
    β”‚                                    β”œβ”€β”€ Admin taps [Approve] or [Reject]
    │←── Receives approval + data ─────────
    β”œβ”€β”€ Shows login form                 β”‚
  • No data is sent until admin explicitly approves the new device
  • The approval dialog shows the requesting device's name
  • Admin can reject unknown devices

Layer 3: Approval Tokens (Persistent Trust)

Once approved, a device receives a cryptographically random approval token (32 bytes). This token enables seamless reconnection without re-approval:

Storage What Purpose
Approved device Raw token (localStorage) Present on next connection
Admin device SHA-256 hash of token Verify without storing raw token

Reconnection flow:

  1. Previously approved device joins room β†’ sends join-request with stored token
  2. Admin device receives β†’ computes SHA-256 of incoming token β†’ checks against stored hashes
  3. Match found β†’ auto-approves (no dialog) β†’ sends family data
  4. No match β†’ shows approval dialog (new/unknown device)

Revocation: Admin can remove any approved device from Settings β†’ Connected Devices. The device will need re-approval on next connection.

Security Properties Summary

Attack Vector Protection Layer
Relay operator sees family code Random room ID replaces family code Layer 1
Anyone with share link gets data Admin must approve before data is sent Layer 2
Approved device reconnects Token-based auto-approval (no dialog) Layer 3
Stolen share link Still needs admin approval Layer 2
Device lost/stolen Admin revokes token Layer 3

PIN Security

PINs are used for UI-level identity verification within the app (not as a cryptographic gate):

  • SHA-256 hash with fixed salt (task-schedule-salt)
  • 4-6 digit numeric PINs
  • Grace period: after entering PIN, won't be asked again for configurable duration
  • Settings entry: always requires PIN (no grace period)
  • Data reset: always requires PIN (no grace period)

Data-at-Rest

Data is stored in plain JSON in localStorage. This is acceptable for a family app because:

  • Each family member has physical access to their own device
  • Browser isolation prevents cross-origin access
  • No cloud backup means no server-side data breach risk

Transport Security

  • WebRTC DTLS: All peer-to-peer data is encrypted in transit by WebRTC
  • Nostr relays: Used only for signaling (peer discovery), not data transfer
  • No CDN, no server: All dependencies bundled locally, zero external calls

Known Limitations

  • Both devices must be online simultaneously for initial P2P connection
  • Nostr relay servers used for signaling only (some may be temporarily down)
  • Data is device-local β€” no cloud backup
  • If localStorage is cleared, device needs a new share link to rejoin
  • PWA background sync limited by browser policies

License

MIT

About

Family task schedule PWA with peer-to-peer sync via WebRTC. Zero servers zero cloud. All data stored locally. Admin approval gate. Arabic-first.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages