Commit graph

57 commits

Author SHA1 Message Date
github-actions[bot]
91f7f905ff Release v7.3.0 2026-05-06 21:35:12 +00:00
github-actions[bot]
db230f2cb8 Release v7.2.1 2026-05-06 21:32:00 +00:00
github-actions[bot]
e57ca2ff0a Release v7.2.0 2026-05-06 21:29:30 +00:00
github-actions[bot]
919ddb1382 Release v7.1.5 2026-05-06 21:08:07 +00:00
github-actions[bot]
dd4e3bad61 Release v7.1.4 2026-05-06 21:04:49 +00:00
github-actions[bot]
2a2cf417b6 Release v7.1.3 2026-05-06 06:19:42 +00:00
github-actions[bot]
f485afa282 Release v7.1.2 2026-05-06 06:04:06 +00:00
github-actions[bot]
838924665f Release v7.1.1 2026-05-06 05:42:13 +00:00
Daniel
e821895bbc Release v7.0.0 2026-04-28 03:11:55 +02:00
Daniel
c9d869cc59 feat(mobile): biometric sign-in (Face ID / Touch ID / fingerprint)
Adds opt-in biometric login to the Capacitor app. Replaces the password
step on subsequent sign-ins; the 2FA step (if any) still applies — by
design, defense in depth.

How it works:
- After a successful password sign-in on a Capacitor build, prompt the
  user to enroll. If they accept, capacitor-native-biometric.setCredentials
  stores the (email, password) pair in the iOS Keychain / Android Keystore
  with biometric-protected access. The local flag ped_bio_enabled=1 is
  set so the next launch knows to probe.
- On the login form, if isNativeApp() + bioStored() + bioAvailable.ok,
  reveal the "Sign in with Face ID / Touch ID / fingerprint" button at
  the top. Label is set from the actual biometryType returned by the
  plugin so users see what their device supports.
- Tap → verifyIdentity (OS prompt) → getCredentials → fill the email +
  password fields → fire the existing form submit so all the regular
  flow runs (turnstile, 2FA prompt, error handling, session storage).
- Explicit logout deletes credentials AND clears the local flag,
  hiding the button on the next visit. Auto-logout (token expiry,
  network) does NOT come through that path, so biometric persists
  across silent session resets.

Storage choice — password not JWT:
- JWTs expire and the storage would constantly need refresh.
- Storing the password lets the standard /api/auth/login flow run,
  which already handles password-rotation (a stale stored password
  just fails 401 → user falls back to typing the new one → re-enrolls).
- The password sits in OS-level secure storage, accessible only after
  successful biometric verification — same security posture as a
  password manager autofill.

Files:
- mobile/package.json: add capacitor-native-biometric@^5.0.0 (Capacitor 6
  compat)
- mobile/android/app/src/main/AndroidManifest.xml: add USE_BIOMETRIC
  uses-permission
- mobile/ios/App/App/Info.plist: add NSFaceIDUsageDescription string
- public/js/auth.js: bioPlugin/bioAvailable/bioStored/bioEnroll/
  bioRetrieve/bioForget helpers; window.PedBio surface; reveal-on-load;
  click handler; post-login enrollment prompt; logout cleanup
- public/index.html: hidden #btn-bio-login + #bio-divider above the
  email field on the login form
- public/css/styles.css: themed gradient button + hover lift
- mobile/README.md: feature list updated

Build steps for Daniel:
  cd mobile && npm install        # picks up capacitor-native-biometric
  npx cap sync                    # ports the plugin into android/ + ios/
  # then build APK / IPA as usual
2026-04-28 03:09:38 +02:00
github-actions[bot]
062276e9cc Release v6.53.2 2026-04-24 23:44:32 +00:00
github-actions[bot]
b3b233974a Release v6.53.1 2026-04-24 23:35:20 +00:00
github-actions[bot]
b0e553c02a Release v6.53.0 2026-04-24 23:02:58 +00:00
github-actions[bot]
ed516adb7a Release v6.52.1 2026-04-24 11:22:36 +00:00
github-actions[bot]
c1a615aaa7 Release v6.52.0 2026-04-24 10:49:31 +00:00
github-actions[bot]
ce7245d3a0 Release v6.51.0 2026-04-24 10:45:40 +00:00
github-actions[bot]
f57553585d Release v6.50.0 2026-04-24 04:18:56 +00:00
github-actions[bot]
03259224ca Release v6.20.0 2026-04-22 20:57:21 +00:00
github-actions[bot]
2f8a95f137 Release v6.19.0 2026-04-22 19:51:04 +00:00
github-actions[bot]
d79a05f591 Release v6.18.0 2026-04-22 19:10:45 +00:00
github-actions[bot]
e250ee6522 Release v6.17.1 2026-04-22 19:04:54 +00:00
github-actions[bot]
ba2e0031e0 Release v6.17.0 2026-04-22 19:00:54 +00:00
github-actions[bot]
32d6dae7a5 Release v6.16.0 2026-04-22 18:15:16 +00:00
github-actions[bot]
859b5eb84c Release v6.15.0 2026-04-22 18:10:04 +00:00
github-actions[bot]
c3ba66cc15 Release v6.14.0 2026-04-22 17:35:12 +00:00
github-actions[bot]
3cef4d5451 Release v6.13.1 2026-04-22 17:30:03 +00:00
github-actions[bot]
50dcde4d80 Release v6.13.0 2026-04-22 16:54:37 +00:00
github-actions[bot]
571f2945a9 Release v6.12.0 2026-04-22 15:15:37 +00:00
github-actions[bot]
669908b711 Release v6.11.0 2026-04-22 14:52:24 +00:00
github-actions[bot]
b411dbbbf0 Release v6.10.3 2026-04-22 11:11:43 +00:00
github-actions[bot]
b101207d9f Release v6.10.2 2026-04-22 10:41:25 +00:00
github-actions[bot]
11b4751bb4 Release v6.10.1 2026-04-22 03:52:10 +00:00
github-actions[bot]
e5c909d459 Release v6.10.0 2026-04-22 01:59:19 +00:00
github-actions[bot]
1a3c6d312f Release v6.9.0 2026-04-21 23:01:09 +00:00
github-actions[bot]
6f9bc7fb1e Release v6.8.0 2026-04-21 20:20:21 +00:00
github-actions[bot]
2aae439f71 Release v6.7.0 2026-04-20 21:20:01 +00:00
github-actions[bot]
c4e30b4f3e Release v6.6.0 2026-04-20 02:23:33 +00:00
github-actions[bot]
c38c1a3127 Release v6.5.0 2026-04-20 01:51:30 +00:00
github-actions[bot]
441a872186 Release v6.4.0 2026-04-20 00:49:55 +00:00
github-actions[bot]
bce3c94f19 Release v6.3.1 2026-04-19 19:26:56 +00:00
github-actions[bot]
fde65a3380 Release v6.3.0 2026-04-19 00:17:21 +00:00
github-actions[bot]
c34bdede93 Release v6.2.1 2026-04-14 22:10:45 +00:00
github-actions[bot]
6365790e4b Release v6.2.0 2026-04-14 21:51:17 +00:00
Daniel
39833fff0d Release v6.1.1 2026-04-14 23:40:10 +02:00
Daniel
61fbcaa072 Untrack Capacitor-generated files + node_modules in mobile/
The mobile/ wrapper had 1700+ node_modules files tracked, plus the
Capacitor-regenerated artifacts that get rewritten on every
`npx cap sync android` (capacitor.build.gradle, capacitor.config.json,
capacitor.plugins.json, capacitor.settings.gradle, the cordova-android-
plugins subtree). Every local dev or CI sync caused noisy drift that
blocked scripts/release.sh from running.

Added mobile/.gitignore covering node_modules, cap-sync outputs,
Android build outputs, .jks/.apk/.aab files, and .DS_Store.
Kept package-lock.json tracked for reproducible npm install.

No logic changes — only stopped tracking files that are always
regenerated.
2026-04-14 23:35:23 +02:00
Daniel
753884999e Version alignment + release script — single source of truth
Aligns every version string in the repo to 6.1.0:
  - package.json: 6.0.0 → 6.1.0
  - mobile/package.json: 1.0.0 → 6.1.0
  - mobile/android/app/build.gradle: versionCode 1 → 610,
      versionName "1.0" → "6.1.0"
  - server.js: hardcoded "v6.0" → reads root package.json at boot
  - /api/health/detailed now reports APP_VERSION from package.json

Adds scripts/release.sh — a one-command bump:
  scripts/release.sh 6.1.1                # local bump + tag
  scripts/release.sh 6.1.1 --push         # + git push
  scripts/release.sh 6.1.1 --push --gh    # + GitHub release (uploads
                                            APK if already built)

Updates all three version sites, commits "Release v6.1.1",
creates annotated tag, optionally pushes and opens a release.
versionCode encoded as MAJ*100000 + MIN*1000 + PATCH so patch
updates always increment monotonically.
2026-04-14 23:18:47 +02:00
Daniel
931d75c55c Mobile app hardening — security + Android 14 compat
capacitor.config.json:
  - webContentsDebuggingEnabled: true → false
    (was leaving Chrome DevTools able to attach to released builds)
  - allowMixedContent: true → false
    (API is HTTPS-only; no need to permit cleartext loads)
  - server.allowNavigation: ["*"] → restricted to pedshub.com /
    peds.danvics.com origins
    (prevents WebView following an attacker-controlled redirect)

AndroidManifest.xml:
  - android:allowBackup="false" + data_extraction_rules.xml
    (Android system backup would otherwise copy EncryptedSharedPreferences
     containing the auth token into Google Cloud backups)
  - Removed USE_BIOMETRIC permission (feature removed earlier)

AudioRecordingService.java:
  - startForeground(id, notif, TYPE_MICROPHONE) on Android 14+
    (without the explicit type Android 14 kills the service with
     MissingForegroundServiceTypeException)
  - WakeLock cap: 1h → 8h (still bounded, onDestroy releases early)

MainActivity.java:
  - Removed dead biometric code path and androidx.biometric imports

mobile/package.json:
  - Dropped @aparajita/capacitor-biometric-auth — orphan dependency
2026-04-14 04:15:27 +02:00
Daniel
f0c7705cd8 Remove biometric prompt (will implement properly with token-based auth later) 2026-04-11 03:57:40 +02:00
Daniel
8ca1fafe41 Native Android: biometric auth, foreground service bridge, mic fix
Major Android native improvements:

Biometric authentication:
- Native AndroidX BiometricPrompt on app launch (2nd launch onwards)
- Supports fingerprint, face, iris, and device PIN/password fallback
- Gracefully skips if no biometric hardware or first launch
- Uses SharedPreferences to track first launch

Microphone permission:
- Added MODIFY_AUDIO_SETTINGS permission (required for WebView audio)
- Added androidScheme: "https" in Capacitor config (getUserMedia requires
  secure context)
- WebChromeClient properly grants WebView permission after Android
  runtime permission is obtained
- Handles pending permission request across the async flow

Background recording bridge:
- NativeRecording JavaScript interface exposed to WebView
- startForegroundService() / stopForegroundService() callable from JS
- Web app calls these on recording start/stop in liveEncounter.js
- AudioRecordingService keeps CPU awake + shows notification when recording
- Recording survives screen lock via foreground service + wake lock

Also:
- USE_BIOMETRIC permission added to manifest
- androidx.biometric:biometric dependency added to build.gradle
- Haptic fallback to navigator.vibrate when Capacitor plugins unavailable
2026-04-11 03:42:23 +02:00
Daniel
ac806f2bc0 Fix WebView mic: grant both Android runtime + WebView permissions
The WebView has its own permission layer separate from Android runtime
permissions. Both must be granted. Now when the web page requests mic
access, the WebChromeClient checks if Android permission exists, grants
the WebView request if yes, or requests Android permission first then
grants the pending WebView request in the callback.
2026-04-11 03:37:45 +02:00