- JavaScript 82.4%
- CSS 7.5%
- Shell 4.7%
- HTML 4.1%
- Dockerfile 0.7%
- Other 0.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
build-and-release / docker (push) Successful in 3s
The 3.7.0 reorganisation moved Dockerfile to deploy/docker/app.Dockerfile, but CI still ran "docker build ... ." which looks for it at the root. Run 72 failed on v3.7.0 because of this. Also fix the offline bundler: it passed the new -f path but kept "docker/" as the trailing build context, so building the SimpleAuth image failed with path "docker/" not found. Found by building the bundle on a real Docker host. |
||
| .forgejo/workflows | ||
| certs | ||
| deploy | ||
| docs | ||
| lib | ||
| public | ||
| test | ||
| tools | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| CHANGELOG.md | ||
| docker-compose.yml | ||
| package.json | ||
| README.md | ||
| server.js | ||
Give Me Update
An AI-powered platform for tracking team topics and updates.
You create a topic with a title only, and whoever works on it writes their update in any language or dialect and in any style, and the AI (DeepSeek) summarises each update in Modern Standard Arabic, then re-reads the whole topic to produce a topic summary and a full report with the progress percentage and the next step.
Features
- Title-only topics: Create a topic quickly and add the details later from inside the topic.
- Edit a topic: Change the title, the details and the topic owner at any time.
- Free-form updates: Anyone writes their update in any language or dialect with no formatting constraints.
- A summary for every update in Modern Standard Arabic (the update is saved immediately even if analysis fails, with a retry button).
- Topic summary + full report: Both are re-analysed after every update, with the progress percentage and the next step.
- Edit updates: Any update can be edited, and an edit re-analyses the whole topic.
- Search, filter and sort: Search by title, details or owner; filter (All/Active/Paused/Done/Stale/My topics); and sort by update, creation, title or percentage.
- "Stale" indicator: An active topic that has not received an update for 7 days shows an alert.
- Topic owner: Assign an owner to each topic and use the "My topics" filter.
- Export the report: Copy or download the topic summary and its report (Markdown).
- Archive separate from trash: Archive a topic to hide it from the list, or delete it to the trash and then restore it or delete it permanently.
- Backup: Download a copy of all your data and restore it (JSON).
- Built-in settings: the AI endpoint and key, plus the SimpleAuth connection, all from inside the app.
- Unified sign-in: identity comes from SimpleAuth (OIDC) with a secure server-side session and a sign-out button.
- Arabic/English with RTL/LTR direction switching, dark and light themes, and a bundled Tajawal font.
- No external dependencies at runtime.
Deploying to an isolated (offline) network
The app has zero runtime dependencies, so moving it to a machine with no internet needs only Node itself and (optionally) the SimpleAuth binary. A bundle script collects everything, verifies the checksums, and produces one tarball:
bash deploy/offline/bundle.sh # on a machine with internet
# -> dist/give-me-update-offline-<version>-linux-x64.tar.gz
# on the isolated machine
tar xzf give-me-update-offline-*.tar.gz && cd give-me-update-offline-*
bash app/deploy/offline/install.sh
Change the AI endpoint without a browser (the database owns it after the first run):
cd app && node deploy/offline/set-endpoint.mjs http://10.0.0.5:8200/v1 MyModel --list --test
Full walkthrough — including how to carry your existing data across and what does not work offline (building the Docker images): docs/OFFLINE.md.
Requirements
- Node.js 22.5 or newer (uses the built-in
node:sqlite).
Running locally
cp .env.example .env # (optional) initial settings
npm start
Then open http://localhost:4000 and go to Settings to set the AI key.
Sign-in is disabled unless you set
SAUTH_URL— see Users and sign-in.
Running with Docker Compose
docker compose up -d
The image is pulled from the Forgejo registry: git.majlis7.net/debe/give-me-update:latest
The data lives in a volume named give-me-update-data.
Time zone: the
docker-compose.ymlfile setsTZ=Asia/Riyadhand the image installstzdata, because without that the container runs on UTC and every time appears 3 hours behind. Change the value if your time zone is different.
Backup
- From inside the app: Settings → "Download a copy" (a JSON file with all topics and updates), and "Import a copy" to restore.
- Restoring replaces all current data with the data from the file.
- From outside the app: copy the volume:
docker run --rm -v give-me-update-data:/data -v "$PWD:/backup" alpine \
tar czf /backup/give-me-update-$(date +%F).tar.gz -C /data .
Tests
npm test
They cover: the database and migrations, the AI layer, the HTTP server, the UI, security, full end-to-end scenarios for everything a user does, and feature tests (saving before analysis, the archive, backup, incremental loading).
CI runs the tests before building the Docker image, so a failing version is never published.
Releases and CI
- Semantic Versioning via
versioninpackage.jsonandvX.Y.Ztags. - CI (Forgejo Actions): pushing to
mainruns the tests, then builds the image and pushes it to the registry. - Releases: pushing a
v*tag creates a Release automatically with theCHANGELOG.mdsection.
# release a new version
# 1) update version in package.json
# 2) add a section to CHANGELOG.md
git add -A && git commit -m "release: X.Y.Z"
git tag vX.Y.Z
git push origin main --tags
Project structure
.
├── server.js # The server (plain Node, no dependencies)
├── lib/
│ ├── db.js # The database (node:sqlite) + sessions
│ ├── ai.js # AI connection and analysis
│ ├── simpleauth.js # OIDC client (PKCE + JWKS + RS256)
│ └── auth.js # Session helpers and signed payloads
├── public/
│ ├── index.html
│ ├── styles.css # Color system (role-based tokens) + Tajawal font
│ ├── app.js
│ ├── i18n.js # Arabic/English translations
│ └── fonts/ # Tajawal font (woff2)
├── test/
│ ├── unit/ # One module in isolation
│ ├── integration/ # A running server over HTTP
│ └── migration/ # Upgrading an older database
├── deploy/
│ ├── docker/
│ │ ├── app.Dockerfile # The application image
│ │ └── simpleauth.Dockerfile # SimpleAuth (checksum-verified binary)
│ └── offline/ # Building and installing without internet
│ ├── bundle.sh # Build the transferable bundle
│ ├── install.sh # Install it on the isolated machine
│ ├── compose.py # Compose file without build contexts
│ └── set-endpoint.mjs # Change the AI endpoint from the terminal
├── tools/ # Publishing and releasing
│ ├── publish.sh # Push the image to the registry
│ ├── release.sh # Tag a release
│ └── release.mjs
├── certs/ # Your own TLS certificates (untracked)
├── docker-compose.yml # The app + SimpleAuth (stays at the root: compose
│ # resolves .env and ./certs against this folder)
├── .forgejo/workflows/ # CI pipeline
├── docs/ # Guides
├── CHANGELOG.md
└── package.json
Users and sign-in — SimpleAuth
The app never manages passwords at all. All identity comes from SimpleAuth via OIDC with PKCE:
Browser ──► /auth/login ──► SimpleAuth (sign-in page / SSO)
▲ │
└── /auth/callback ◄──┘ (?code=...)
│
└─► token exchange + local RS256 verification (JWKS) ⟹ a session of our own
- Local verification of the RS256 signature via
node:cryptoand JWKS keys — no network request per request, and no npm package. - The author name is pinned to the signed-in user: nobody can post under someone else's name.
- Roles: Whoever holds the admin role (
SAUTH_ADMIN_ROLE, defaultadmin) can open settings, delete and restore. Everyone else only sees topics and updates. - Automatic renewal: The session is renewed silently, and if the account is disabled in the directory the session is ended immediately.
- Sign-out goes through
/sauth/logoutso that the SSO session is cleared as well. - Leave
SAUTH_URLempty to disable sign-in entirely (development mode only — do not do this on a shared network).
Setup in 5 steps
cp .env.example .env # 1) fill in SAUTH_HOSTNAME, SAUTH_ADMIN_KEY and APP_URL
mkdir -p certs # 2) put your certificate: certs/fullchain.pem and certs/privkey.pem
docker compose up -d --build
- Open
https://<SAUTH_HOSTNAME>:<SAUTH_PORT>/sauth/adminwith the admin key. - Apps → create an app:
app_id = give-me-updatewithredirect_uris = ["https://<APP_URL>/auth/callback"]. Then Roles → defineadminandmember, and assignadminto whoever you want. - Create the users (or connect AD later) and sign in.
⚠️ Without setting
SAUTH_REDIRECT_URIS, SimpleAuth rejects every sign-in attempt — and that is intentional.
Environment variables: SAUTH_* vs AUTH_*
Two prefixes appear in this project, and the difference matters:
| Prefix | Where you set it | Who reads it |
|---|---|---|
SAUTH_* |
your .env file |
docker compose — it interpolates these |
AUTH_* |
inside the SimpleAuth container | SimpleAuth itself |
The compose file maps one to the other, for example
SAUTH_DEPLOYMENT_NAME → AUTH_DEPLOYMENT_NAME.
You almost always edit SAUTH_* in .env. The AUTH_* names are what SimpleAuth
documents upstream, so they show up in its own documentation and log output — if you see
AUTH_SOMETHING mentioned there, look for the matching SAUTH_SOMETHING in .env.
Runtime settings (
deployment_name,redirect_uris,cors_origins,default_roles, rate limiting, AD outage behaviour, auto-SSO) are seeded from the environment on the first run only. Afterwards the admin UI owns them and the env value is ignored.
Deployment name (SAUTH_DEPLOYMENT_NAME)
A small variable, but it matters for AD later:
| Constraint | 6 letters maximum, letters only (no digits or dashes) |
| Default | sauth |
| Purpose | Names the AD service account: svc-sauth-{name} |
It only matters if you run more than one SimpleAuth instance on the same AD (to avoid collisions
between account names and SPNs). With a single instance, leave it as sauth.
⚠️ Important: this is a "runtime" setting — it is read from
.envon the first run only. After that the source of truth is the panel: Settings → General. Changing it in.envlater has no effect.
Moving to Active Directory (later)
No change to the Give Me Update code is needed — the app sends the browser to SimpleAuth, and SimpleAuth takes care of the rest:
- Admin panel → LDAP Providers → AD Setup Script — enter the service account name and download the PowerShell script.
- Run it on any domain-joined machine: it creates the account, registers the SPNs and exports a configuration file (no
ktpassand no manual keytab). - Paste the configuration into the panel — SimpleAuth builds the keytab in memory and enables SSO immediately.
- For transparent SSO: enable
SAUTH_AUTO_SSO=true, and make sureSAUTH_HOSTNAMEis the same name users type, and that the clocks are in sync (SPNEGO allows only a 5-minute difference). On Windows: theAuthServerAllowlistpolicy in Chrome/Edge. On Firefox:network.negotiate-auth.trusted-uris=<SAUTH_HOSTNAME>.
After AD is connected: a user who is disabled, expired or deleted in AD is blocked automatically at the first renewal (within the access token lifetime), even if their Kerberos ticket is still valid.
Security
- No passwords in this app: no storage, no hashing and no reset — identity comes from SimpleAuth.
- Tokens are verified locally with the RS256 signature plus
issandaudchecks — so a token from another app is not accepted. - A session of our own: a random HttpOnly cookie with a record in the database (revocable immediately).
- The author name comes from the session — you cannot impersonate anyone else.
- Roles: settings, permanent deletion and restore are for the admin only.
- Idle sessions are cleaned up automatically at startup (older than 30 days).
- The DeepSeek key is stored on the server and is never sent to the browser in full (it is shown masked).
- There are no external dependencies at runtime.