This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
flutter-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Show scaffold
|
||||
run: find . -maxdepth 3 -type f | sort
|
||||
- name: Flutter placeholder
|
||||
run: echo "Configure Flutter runner before enabling analyze/test in Gitea Actions."
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
# Flutter/Dart
|
||||
.dart_tool/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
.packages
|
||||
.pub-cache/
|
||||
.pub/
|
||||
build/
|
||||
coverage/
|
||||
|
||||
# Android/iOS generated/local files
|
||||
app/android/.gradle/
|
||||
app/android/local.properties
|
||||
app/ios/Pods/
|
||||
app/ios/.symlinks/
|
||||
app/ios/Flutter/ephemeral/
|
||||
app/ios/Flutter/Generated.xcconfig
|
||||
app/ios/Flutter/flutter_export_environment.sh
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
*.iml
|
||||
.vscode/*.log
|
||||
|
||||
# Env/secrets
|
||||
.env
|
||||
.env.*
|
||||
*.keystore
|
||||
*.jks
|
||||
*.p8
|
||||
*.mobileprovision
|
||||
*.cer
|
||||
*.pem
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"Dart-Code.dart-code",
|
||||
"Dart-Code.flutter",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"humao.rest-client"
|
||||
]
|
||||
}
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dart.flutterSdkPath": null,
|
||||
"editor.formatOnSave": true,
|
||||
"files.eol": "\n"
|
||||
}
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "flutter analyze",
|
||||
"type": "shell",
|
||||
"command": "cd app && flutter analyze",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "flutter test",
|
||||
"type": "shell",
|
||||
"command": "cd app && flutter test",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "docker compose up",
|
||||
"type": "shell",
|
||||
"command": "docker compose up baron-safe-web",
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
# Baron Safe App
|
||||
|
||||
Baron Safe is a PWA/WebView hybrid mobile app for Baron SSO login confirmation, session review, and suspicious session blocking.
|
||||
|
||||
## Development Direction
|
||||
|
||||
- Keep the existing `userfront` repository unchanged.
|
||||
- Reuse applicable `userfront` UI flow, Flutter patterns, routing, and API interaction style.
|
||||
- Use WebView for information display and user interaction.
|
||||
- Delegate push, biometric authentication, secure storage, and future device signing to native or Flutter plugin layers.
|
||||
|
||||
## Initial Flow
|
||||
|
||||
1. User enters a phone number in Baron SSO or an RP login screen.
|
||||
2. Baron SSO proceeds with the existing login policy.
|
||||
3. Login/session history is recorded.
|
||||
4. Baron Safe receives a login notification via FCM/APNs.
|
||||
5. User checks service, IP, device, time, and auth method in Baron Safe.
|
||||
6. If suspicious, the user blocks the session or linked RP.
|
||||
|
||||
## Repository Layout
|
||||
|
||||
```text
|
||||
baron-safe-app/
|
||||
docs/
|
||||
app/
|
||||
docker/
|
||||
scripts/
|
||||
.vscode/
|
||||
.gitea/workflows/
|
||||
```
|
||||
@@ -0,0 +1,33 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const ProviderScope(child: BaronSafeApp()));
|
||||
}
|
||||
|
||||
class BaronSafeApp extends StatelessWidget {
|
||||
const BaronSafeApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Baron Safe',
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: const BaronSafeHome(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class BaronSafeHome extends StatelessWidget {
|
||||
const BaronSafeHome({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Baron Safe')),
|
||||
body: const Center(
|
||||
child: Text('Baron Safe hybrid app scaffold'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
name: baron_safe_app
|
||||
description: Baron Safe hybrid mobile app for Baron SSO.
|
||||
publish_to: "none"
|
||||
version: 0.1.0+1
|
||||
|
||||
environment:
|
||||
sdk: ">=3.4.0 <4.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_riverpod: ^3.0.3
|
||||
go_router: ^17.0.1
|
||||
http: ^1.6.0
|
||||
webview_flutter: ^4.10.0
|
||||
local_auth: ^2.3.0
|
||||
flutter_secure_storage: ^9.2.2
|
||||
firebase_core: ^3.8.0
|
||||
firebase_messaging: ^15.1.5
|
||||
logging: ^1.2.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^4.0.0
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
@@ -0,0 +1,15 @@
|
||||
services:
|
||||
baron-safe-web:
|
||||
image: nginx:1.27-alpine
|
||||
ports:
|
||||
- "18080:80"
|
||||
volumes:
|
||||
- ./docker/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
- ./app/build/web:/usr/share/nginx/html:ro
|
||||
|
||||
flutter-ci:
|
||||
build:
|
||||
context: ./docker
|
||||
dockerfile: Dockerfile.flutter-ci
|
||||
volumes:
|
||||
- ./app:/workspace/app
|
||||
@@ -0,0 +1,3 @@
|
||||
FROM ghcr.io/cirruslabs/flutter:stable
|
||||
WORKDIR /workspace/app
|
||||
CMD ["flutter", "--version"]
|
||||
@@ -0,0 +1,2 @@
|
||||
FROM nginx:1.27-alpine
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
@@ -0,0 +1,11 @@
|
||||
server {
|
||||
listen 8080;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# API Contract Draft
|
||||
|
||||
## Initial APIs
|
||||
|
||||
- `POST /api/v1/baron-safe/devices/register`
|
||||
- `POST /api/v1/baron-safe/devices/push-token`
|
||||
- `DELETE /api/v1/baron-safe/devices/{deviceId}`
|
||||
- `GET /api/v1/baron-safe/sessions`
|
||||
- `GET /api/v1/baron-safe/sessions/{sessionId}`
|
||||
- `POST /api/v1/baron-safe/sessions/{sessionId}/block`
|
||||
- `GET /api/v1/baron-safe/linked-apps`
|
||||
- `POST /api/v1/baron-safe/linked-apps/{clientId}/block`
|
||||
|
||||
## Future High-Risk Approval APIs
|
||||
|
||||
- `POST /api/v1/auth/baron-safe/login/init`
|
||||
- `GET /api/v1/auth/baron-safe/requests/{authReqId}`
|
||||
- `POST /api/v1/auth/baron-safe/requests/{authReqId}/decision`
|
||||
- `POST /api/v1/auth/baron-safe/login/poll`
|
||||
@@ -0,0 +1,19 @@
|
||||
# Architecture
|
||||
|
||||
## Principle
|
||||
|
||||
Baron Safe is developed as a hybrid app. The WebView layer presents session, linked app, QR, and portal-style screens. Native or Flutter plugin layers handle sensitive capabilities.
|
||||
|
||||
## Layers
|
||||
|
||||
| Layer | Responsibility |
|
||||
| --- | --- |
|
||||
| WebView | Display session history, linked apps, details, and user actions |
|
||||
| Native/Plugin | Push, biometric prompt, secure storage, future key signing |
|
||||
| Backend | Device registration, push trigger, session query, session blocking, audit logs |
|
||||
|
||||
## Default UX
|
||||
|
||||
The initial model is post-login confirmation and blocking:
|
||||
|
||||
`phone number login -> login allowed -> Baron Safe notification -> user confirmation -> block if suspicious`
|
||||
@@ -0,0 +1,19 @@
|
||||
# WebView-Native Bridge Policy
|
||||
|
||||
## Allowed Commands
|
||||
|
||||
| Command | Description |
|
||||
| --- | --- |
|
||||
| `getDeviceInfo` | Return device id, platform, app version |
|
||||
| `registerPushToken` | Register current push token |
|
||||
| `openBiometricPrompt` | Run biometric or device PIN prompt |
|
||||
| `blockSession` | Block a session after native verification |
|
||||
| `blockLinkedApp` | Block a linked RP after native verification |
|
||||
| `openSettings` | Open native app settings |
|
||||
|
||||
## Rules
|
||||
|
||||
- Do not pass private keys to WebView.
|
||||
- Do not store long-lived refresh tokens in WebView storage.
|
||||
- Validate origin and session before processing bridge commands.
|
||||
- Native layer must verify sensitive commands before calling backend APIs.
|
||||
@@ -0,0 +1,23 @@
|
||||
# Release Policy Draft
|
||||
|
||||
## Channels
|
||||
|
||||
| Channel | Purpose |
|
||||
| --- | --- |
|
||||
| local | Developer verification |
|
||||
| staging | Internal QA and SSO integration testing |
|
||||
| production | Internal/partner release |
|
||||
|
||||
## Targets
|
||||
|
||||
- Android: APK/AAB, internal distribution or managed store
|
||||
- iOS: TestFlight, Apple Business Manager, or MDM
|
||||
|
||||
## Required Checks
|
||||
|
||||
- Static analysis
|
||||
- Unit/widget tests
|
||||
- Push registration test
|
||||
- WebView session test
|
||||
- Biometric blocking test
|
||||
- Audit log verification
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/../app"
|
||||
flutter pub get
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/../app"
|
||||
flutter build apk
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/../app"
|
||||
flutter build ios --no-codesign
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/../app"
|
||||
flutter analyze
|
||||
flutter test
|
||||
Reference in New Issue
Block a user