Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
08e5126
chore (major updates): upgrade project dependencies, update Node.js t…
devakesu Jul 31, 2026
cfb77ac
chore: refactor code and improve linting standards across the codebase
devakesu Aug 1, 2026
3b2da09
improvement: remove unnecessary JWE encryption for unsensitive data r…
devakesu Aug 1, 2026
a5932e0
refactor: perform comprehensive project-wide cleanup, dependency upda…
devakesu Aug 1, 2026
4f35516
feat: add individual course targets support, include duty leave count…
devakesu Aug 1, 2026
5a6129c
refactor: optimize data fetching and caching with tailored TTLs, serv…
devakesu Aug 1, 2026
9c6c8ad
refactor: modularize auth context, improve cache performance, and sta…
devakesu Aug 2, 2026
ffcd074
feat: implement duty leave filtering in tracking page and improve cou…
devakesu Aug 2, 2026
72f8500
refactor: centralize transient error detection, add robust app lifecy…
devakesu Aug 2, 2026
3143ebd
feat: add visual blocked state overlay and submit button feedback to …
devakesu Aug 2, 2026
5ca0001
feat: automate mobile configuration by extracting Firebase and app me…
devakesu Aug 2, 2026
504cd1f
feat: implement streaming response support with size limits and remov…
devakesu Aug 2, 2026
29e575c
chore: update actions/setup-node to version 8207627 in CI workflows
devakesu Aug 2, 2026
dab7d91
fix: escape regex special characters in fetch URL expectations in cli…
devakesu Aug 2, 2026
e49365c
chore: add step to prepare app_secrets.dart in CodeQL workflow
devakesu Aug 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
490 changes: 287 additions & 203 deletions .devcontainer/Dockerfile

Large diffs are not rendered by default.

399 changes: 172 additions & 227 deletions .devcontainer/Start.ps1

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions .devcontainer/pinned-artifacts.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
{
"npm": {
"url": "https://registry.npmjs.org/npm/-/npm-11.11.0.tgz",
"shasum": "db5ad0ed255e1a29cf241c4112ee81d2220a4edb"
"url": "https://registry.npmjs.org/npm/-/npm-12.0.2.tgz",
"shasum": "788d93dc8869000b1078e0395c60748a0aadc4f1"
},
"playwright": {
"url": "https://registry.npmjs.org/playwright/-/playwright-1.60.0.tgz",
"shasum": "89710863a51f21112633ef8b6b182594d3bfd7b5"
"url": "https://registry.npmjs.org/playwright/-/playwright-1.62.1.tgz",
"shasum": "8447b6755e8aec85a3cb7207c823e3ed2fc66700"
},
"firebase": {
"url": "https://registry.npmjs.org/firebase-tools/-/firebase-tools-15.18.0.tgz",
"shasum": "179b592d2cbdae7b7b8d5844477e81844c6ef5a5"
"url": "https://registry.npmjs.org/firebase-tools/-/firebase-tools-15.25.1.tgz",
"shasum": "56f46b47cafdf89dbb3f9c14e039a3095da9c50c"
},
"supabase": {
"url": "https://github.com/supabase/cli/releases/download/v2.98.2/supabase_linux_amd64.tar.gz",
"sha256": "0f59df9e6837e876f309e0b4f47005133c51296e85a02727b2927f33ed9adb2d"
"url": "https://github.com/supabase/cli/releases/download/v2.111.0/supabase_2.111.0_linux_amd64.tar.gz",
"sha256": "31ee8a152e9c8c8eddae072c6bc7c9119748a96c8cdaf21a6d31c9ce7e62cc18"
},
"infisical": {
"url": "https://registry.npmjs.org/@infisical/cli/-/cli-0.43.84.tgz",
"shasum": "1be194be8a50c38706d3bd1f5852d22bc393827d"
"url": "https://registry.npmjs.org/@infisical/cli/-/cli-0.43.114.tgz",
"shasum": "f6c8ec4b7c0efcb568694653455f96fb947e4993"
}
}
26 changes: 16 additions & 10 deletions .example.env
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ NEXT_PUBLIC_APP_NAME=GhostClass

# ⚠️ App version displayed in footer and health checks
# 🔨 Build-time (Infisical `/build-time` folder)
NEXT_PUBLIC_APP_VERSION=4.4.9
NEXT_PUBLIC_APP_VERSION=4.5.0

# ⚠️ Your production domain WITHOUT https://
# All URL-based variables are derived from this.
Expand Down Expand Up @@ -236,20 +236,32 @@ NEXT_PUBLIC_ENABLE_SW_IN_DEV=false
# ----------------------------------------------------------------------------

# ℹ️ Android Package Name (e.g., com.ghostclass.app)
# 🔨 Build-time (Infisical `/build-time` folder )
# 🔨 Build-time (Infisical `/build-time` folder)
NEXT_PUBLIC_ANDROID_PACKAGE_NAME=com.devakesu.apps.ghostclass

# ℹ️ iOS App Store ID (e.g., 6478952324)
# 🔨 Build-time (Infisical `/build-time` folder — optional)
IOS_APP_ID=6478952324

# ⚠️ Base64-encoded google-services.json file for Firebase / Google Services Plugin
# Required for building the release APK. Encode using: base64 -w 0 -i google-services.json
# 🔨 Build-time (Infisical `/build-time` folder)
GOOGLE_SERVICES_JSON_BASE64=

# 🔑 Dynamic Firebase Client API Keys (Overrides for firebase_options.dart)
# 🔑 Dynamic Firebase Client Options (Overrides for firebase_options.dart)
# Used by Flutter build (String.fromEnvironment) & generate-firebase-json to configure firebase_options.dart.
# FIREBASE_API_KEY_ANDROID is automatically derived from google-services.json during CI releases.
# Populating these variables overrides the auto-derived values.
# 🔨 Build-time (Infisical `/build-time` folder)
FIREBASE_API_KEY_ANDROID=
FIREBASE_API_KEY_IOS=
FIREBASE_ANDROID_APP_ID=
FIREBASE_IOS_APP_ID=
FIREBASE_MESSAGING_SENDER_ID=
FIREBASE_PROJECT_ID=
FIREBASE_STORAGE_BUCKET=
FIREBASE_IOS_BUNDLE_ID=


# ----------------------------------------------------------------------------
# Development / Local Sync Utilities
Expand Down Expand Up @@ -353,19 +365,13 @@ CRON_SECRET=
# 🚀 Runtime (Infisical `/runtime` folder → Server Env Var — optional)
REQUEST_SIGNATURE_MAX_AGE=600

# ⚠️ RSA Private Key for JWE bi-directional encryption/decryption
# Generate: node scripts/generate-jwe-keys.js
# Paste the PEM content (replace newlines with \n for .env)
# 🚀 Runtime (Infisical `/runtime` folder → Server Env Var)
JWE_PRIVATE_KEY=

# ----------------------------------------------------------------------------
# Mobile Security & Attestation (Zero-Trust)
# ----------------------------------------------------------------------------

# ⚠️ Minimum supported app version required to bypass forced update
# 🚀 Runtime (Infisical `/runtime` folder → Server Env Var)
MIN_APP_VERSION=4.4.9
MIN_APP_VERSION=4.5.0

# ℹ️ Enforce Firebase App Check for all mobile clients in production
# Valid: "true", "false" (default: false in dev, true recommended in prod)
Expand Down
7 changes: 7 additions & 0 deletions .github/ISSUE_TEMPLATE/custom.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
name: Custom issue template
about: Describe this issue template's purpose here.
title: ""
labels: ""
assignees: ""
---
3 changes: 2 additions & 1 deletion .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ assignees: []

## Checklist

- [ ] I have searched existing issues and this feature has not been requested before
- [ ] I have searched existing issues and this feature has not been requested
before
- [ ] This feature would benefit the majority of GhostClass users
- [ ] I am willing to help implement this feature (optional)
48 changes: 32 additions & 16 deletions .github/actions/flutter-action/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,28 +102,38 @@ runs:
- name: Set action inputs
id: flutter-action
shell: bash
env:
INPUT_FLUTTER_VERSION: ${{ inputs.flutter-version }}
INPUT_FLUTTER_VERSION_FILE: ${{ inputs.flutter-version-file }}
INPUT_ARCHITECTURE: ${{ inputs.architecture }}
INPUT_CACHE_KEY: ${{ inputs.cache-key }}
INPUT_CACHE_PATH: ${{ inputs.cache-path }}
INPUT_PUB_CACHE_KEY: ${{ inputs.pub-cache-key }}
INPUT_PUB_CACHE_PATH: ${{ inputs.pub-cache-path }}
INPUT_GIT_SOURCE: ${{ inputs.git-source }}
INPUT_CHANNEL: ${{ inputs.channel }}
run: |
$GITHUB_ACTION_PATH/setup.sh -p \
-n '${{ inputs.flutter-version }}' \
-f '${{ inputs.flutter-version-file }}' \
-a '${{ inputs.architecture }}' \
-k '${{ inputs.cache-key }}' \
-c '${{ inputs.cache-path }}' \
-l '${{ inputs.pub-cache-key }}' \
-d '${{ inputs.pub-cache-path }}' \
-g '${{ inputs.git-source }}' \
${{ inputs.channel }}
-n "$INPUT_FLUTTER_VERSION" \
-f "$INPUT_FLUTTER_VERSION_FILE" \
-a "$INPUT_ARCHITECTURE" \
-k "$INPUT_CACHE_KEY" \
-c "$INPUT_CACHE_PATH" \
-l "$INPUT_PUB_CACHE_KEY" \
-d "$INPUT_PUB_CACHE_PATH" \
-g "$INPUT_GIT_SOURCE" \
"$INPUT_CHANNEL"

- name: Cache Flutter
id: cache-flutter
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.3
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
if: ${{ inputs.cache == 'true' }}
with:
path: ${{ steps.flutter-action.outputs.CACHE-PATH }}
key: ${{ steps.flutter-action.outputs.CACHE-KEY }}

- name: Cache pub dependencies
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.3
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
id: cache-pub
if: ${{ (inputs.pub-cache == '' && inputs.cache == 'true') || inputs.pub-cache == 'true' }}
with:
Expand All @@ -133,10 +143,16 @@ runs:
- name: Run setup script
shell: bash
if: ${{ inputs.dry-run != 'true' && inputs.dry-run != true }}
env:
OUTPUT_VERSION: ${{ steps.flutter-action.outputs.VERSION }}
OUTPUT_ARCHITECTURE: ${{ steps.flutter-action.outputs.ARCHITECTURE }}
OUTPUT_CACHE_PATH: ${{ steps.flutter-action.outputs.CACHE-PATH }}
OUTPUT_PUB_CACHE_PATH: ${{ steps.flutter-action.outputs.PUB-CACHE-PATH }}
OUTPUT_CHANNEL: ${{ steps.flutter-action.outputs.CHANNEL }}
run: |
$GITHUB_ACTION_PATH/setup.sh \
-n '${{ steps.flutter-action.outputs.VERSION }}' \
-a '${{ steps.flutter-action.outputs.ARCHITECTURE }}' \
-c '${{ steps.flutter-action.outputs.CACHE-PATH }}' \
-d '${{ steps.flutter-action.outputs.PUB-CACHE-PATH }}' \
${{ steps.flutter-action.outputs.CHANNEL }}
-n "$OUTPUT_VERSION" \
-a "$OUTPUT_ARCHITECTURE" \
-c "$OUTPUT_CACHE_PATH" \
-d "$OUTPUT_PUB_CACHE_PATH" \
"$OUTPUT_CHANNEL"
Loading
Loading