fix: update auth screens to use ALTCHA instead of Turnstile
This commit is contained in:
parent
95be179a38
commit
602a139349
|
|
@ -1,12 +0,0 @@
|
||||||
@echo off
|
|
||||||
echo Deploying create-beacon edge function to Supabase...
|
|
||||||
echo.
|
|
||||||
|
|
||||||
supabase functions deploy create-beacon --no-verify-jwt
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo Deployment complete!
|
|
||||||
echo.
|
|
||||||
echo The beacon feature should now work properly.
|
|
||||||
echo Test by opening the Beacon tab in the app and creating a beacon.
|
|
||||||
pause
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
# Deploy all Edge Functions to Supabase
|
|
||||||
# Run this after updating supabase-js version
|
|
||||||
|
|
||||||
Write-Host "=== Deploying All Edge Functions ===" -ForegroundColor Cyan
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "This will deploy all functions with --no-verify-jwt (default for this script)" -ForegroundColor Yellow
|
|
||||||
Write-Host ""
|
|
||||||
|
|
||||||
$functions = @(
|
|
||||||
"appreciate",
|
|
||||||
"block",
|
|
||||||
"deactivate-account",
|
|
||||||
"delete-account",
|
|
||||||
"feed-personal",
|
|
||||||
"feed-sojorn",
|
|
||||||
"follow",
|
|
||||||
"manage-post",
|
|
||||||
"notifications",
|
|
||||||
"profile",
|
|
||||||
"profile-posts",
|
|
||||||
"publish-comment",
|
|
||||||
"publish-post",
|
|
||||||
"push-notification",
|
|
||||||
"report",
|
|
||||||
"save",
|
|
||||||
"search",
|
|
||||||
"sign-media",
|
|
||||||
"signup",
|
|
||||||
"tone-check",
|
|
||||||
"trending",
|
|
||||||
"upload-image"
|
|
||||||
)
|
|
||||||
|
|
||||||
$totalFunctions = $functions.Count
|
|
||||||
$currentFunction = 0
|
|
||||||
$noVerifyJwt = "--no-verify-jwt"
|
|
||||||
|
|
||||||
foreach ($func in $functions) {
|
|
||||||
$currentFunction++
|
|
||||||
Write-Host "[$currentFunction/$totalFunctions] Deploying $func..." -ForegroundColor Yellow
|
|
||||||
|
|
||||||
try {
|
|
||||||
supabase functions deploy $func $noVerifyJwt 2>&1 | Out-Null
|
|
||||||
if ($LASTEXITCODE -eq 0) {
|
|
||||||
Write-Host " OK $func deployed successfully" -ForegroundColor Green
|
|
||||||
} else {
|
|
||||||
Write-Host " FAILED to deploy $func" -ForegroundColor Red
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
Write-Host " ERROR deploying $func : $_" -ForegroundColor Red
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "=== Deployment Complete ===" -ForegroundColor Cyan
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "Next steps:" -ForegroundColor Yellow
|
|
||||||
Write-Host "1. Restart your Flutter app" -ForegroundColor Yellow
|
|
||||||
Write-Host "2. Sign in again" -ForegroundColor Yellow
|
|
||||||
Write-Host "3. The JWT 401 errors should be gone!" -ForegroundColor Green
|
|
||||||
Write-Host ""
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Fix FCM configuration and restart backend
|
|
||||||
# Run with: bash fix_fcm_and_restart.sh
|
|
||||||
|
|
||||||
echo "=== Fixing FCM Configuration ==="
|
|
||||||
|
|
||||||
# Kill old backend process
|
|
||||||
echo "Killing old backend process on port 8080..."
|
|
||||||
sudo kill -9 $(sudo lsof -ti:8080) 2>/dev/null || echo "No process to kill"
|
|
||||||
|
|
||||||
# Verify Firebase JSON exists
|
|
||||||
if [ -f "/opt/sojorn/firebase-service-account.json" ]; then
|
|
||||||
echo "✓ Firebase service account JSON exists"
|
|
||||||
ls -lh /opt/sojorn/firebase-service-account.json
|
|
||||||
else
|
|
||||||
echo "✗ Firebase service account JSON not found!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add FIREBASE_CREDENTIALS_FILE to .env if not present
|
|
||||||
if ! grep -q "FIREBASE_CREDENTIALS_FILE" /opt/sojorn/.env; then
|
|
||||||
echo "Adding FIREBASE_CREDENTIALS_FILE to .env..."
|
|
||||||
echo "" | sudo tee -a /opt/sojorn/.env > /dev/null
|
|
||||||
echo "FIREBASE_CREDENTIALS_FILE=/opt/sojorn/firebase-service-account.json" | sudo tee -a /opt/sojorn/.env > /dev/null
|
|
||||||
echo "✓ Added FIREBASE_CREDENTIALS_FILE"
|
|
||||||
else
|
|
||||||
echo "✓ FIREBASE_CREDENTIALS_FILE already in .env"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Restart backend
|
|
||||||
echo ""
|
|
||||||
echo "=== Restarting Backend ==="
|
|
||||||
sudo systemctl restart sojorn-api
|
|
||||||
sleep 3
|
|
||||||
|
|
||||||
# Check status
|
|
||||||
sudo systemctl status sojorn-api --no-pager | head -20
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== Checking FCM Initialization ==="
|
|
||||||
sudo journalctl -u sojorn-api --since "30 seconds ago" | grep -i "push\|fcm\|firebase" || echo "No FCM logs yet"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== Done! ==="
|
|
||||||
echo "If you see 'Server started on port 8080' with no errors, FCM is working!"
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Restart backend cleanly
|
|
||||||
systemctl stop sojorn-api
|
|
||||||
pkill -9 sojorn-api
|
|
||||||
sleep 2
|
|
||||||
systemctl start sojorn-api
|
|
||||||
sleep 3
|
|
||||||
echo "=== Backend Status ==="
|
|
||||||
systemctl status sojorn-api --no-pager | head -15
|
|
||||||
echo ""
|
|
||||||
echo "=== FCM Logs ==="
|
|
||||||
journalctl -u sojorn-api --since "10 seconds ago" | grep -i "server started\|failed\|fcm\|firebase\|push" || echo "No relevant logs"
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name api.sojorn.net;
|
|
||||||
|
|
||||||
# Allow Certbot to validate (it uses .well-known/acme-challenge)
|
|
||||||
location /.well-known/acme-challenge/ {
|
|
||||||
root /var/www/html;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
return 301 https://$host$request_uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name api.sojorn.net;
|
|
||||||
return 301 https://api.sojorn.net$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name api.sojorn.net;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/api.sojorn.net/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/api.sojorn.net/privkey.pem;
|
|
||||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
|
||||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
|
||||||
|
|
||||||
# Allow larger uploads (Video/Image)
|
|
||||||
client_max_body_size 100M;
|
|
||||||
|
|
||||||
location /ws {
|
|
||||||
proxy_pass http://127.0.0.1:8080;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:8080;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name api.sojorn.net;
|
|
||||||
return 301 https://api.sojorn.net$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name api.sojorn.net;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/sojorn.net/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/sojorn.net/privkey.pem;
|
|
||||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
|
||||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
|
||||||
|
|
||||||
# Allow larger uploads (Video/Image)
|
|
||||||
client_max_body_size 100M;
|
|
||||||
|
|
||||||
location /ws {
|
|
||||||
proxy_pass http://127.0.0.1:8080;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:8080;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,7 @@ import 'package:local_auth/local_auth.dart';
|
||||||
import '../../providers/auth_provider.dart';
|
import '../../providers/auth_provider.dart';
|
||||||
import '../../providers/api_provider.dart';
|
import '../../providers/api_provider.dart';
|
||||||
import '../../theme/app_theme.dart';
|
import '../../theme/app_theme.dart';
|
||||||
import '../widgets/altcha_widget.dart';
|
import '../../widgets/altcha_widget.dart';
|
||||||
import '../../widgets/sojorn_button.dart';
|
import '../../widgets/sojorn_button.dart';
|
||||||
import '../../widgets/sojorn_input.dart';
|
import '../../widgets/sojorn_input.dart';
|
||||||
import 'sign_up_screen.dart';
|
import 'sign_up_screen.dart';
|
||||||
|
|
@ -398,7 +398,7 @@ class _SignInScreenState extends ConsumerState<SignInScreen> {
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
textInputAction: TextInputAction.done,
|
textInputAction: TextInputAction.done,
|
||||||
prefixIcon: Icons.lock_outline,
|
prefixIcon: Icons.lock_outline,
|
||||||
onEditingComplete: _turnstileToken != null ? _signIn : null,
|
onEditingComplete: _altchaToken != null ? _signIn : null,
|
||||||
autofillHints: const [AutofillHints.password],
|
autofillHints: const [AutofillHints.password],
|
||||||
onChanged: (_) {
|
onChanged: (_) {
|
||||||
if (_errorMessage != null) {
|
if (_errorMessage != null) {
|
||||||
|
|
@ -507,7 +507,7 @@ class _SignInScreenState extends ConsumerState<SignInScreen> {
|
||||||
],
|
],
|
||||||
sojornButton(
|
sojornButton(
|
||||||
label: 'Sign In',
|
label: 'Sign In',
|
||||||
onPressed: (isSubmitting || _turnstileToken == null) ? null : _signIn,
|
onPressed: (isSubmitting || _altchaToken == null) ? null : _signIn,
|
||||||
isLoading: isSubmitting,
|
isLoading: isSubmitting,
|
||||||
isFullWidth: true,
|
isFullWidth: true,
|
||||||
variant: sojornButtonVariant.primary,
|
variant: sojornButtonVariant.primary,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import 'package:url_launcher/url_launcher.dart';
|
||||||
import '../../providers/auth_provider.dart';
|
import '../../providers/auth_provider.dart';
|
||||||
import '../../theme/app_theme.dart';
|
import '../../theme/app_theme.dart';
|
||||||
import '../../theme/tokens.dart';
|
import '../../theme/tokens.dart';
|
||||||
import '../../widgets/auth/turnstile_widget.dart';
|
import '../../widgets/altcha_widget.dart';
|
||||||
|
|
||||||
class SignUpScreen extends ConsumerStatefulWidget {
|
class SignUpScreen extends ConsumerStatefulWidget {
|
||||||
const SignUpScreen({super.key});
|
const SignUpScreen({super.key});
|
||||||
|
|
@ -25,8 +25,8 @@ class _SignUpScreenState extends ConsumerState<SignUpScreen> {
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
String? _errorMessage;
|
String? _errorMessage;
|
||||||
|
|
||||||
// Turnstile token
|
// ALTCHA token
|
||||||
String? _turnstileToken;
|
String? _altchaToken;
|
||||||
|
|
||||||
// Legal consent
|
// Legal consent
|
||||||
bool _acceptTerms = false;
|
bool _acceptTerms = false;
|
||||||
|
|
@ -58,8 +58,8 @@ class _SignUpScreenState extends ConsumerState<SignUpScreen> {
|
||||||
Future<void> _signUp() async {
|
Future<void> _signUp() async {
|
||||||
if (!_formKey.currentState!.validate()) return;
|
if (!_formKey.currentState!.validate()) return;
|
||||||
|
|
||||||
// Validate Turnstile token
|
// Validate ALTCHA token
|
||||||
if (_turnstileToken == null || _turnstileToken!.isEmpty) {
|
if (_altchaToken == null || _altchaToken!.isEmpty) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_errorMessage = 'Please complete the security verification';
|
_errorMessage = 'Please complete the security verification';
|
||||||
});
|
});
|
||||||
|
|
@ -101,7 +101,7 @@ class _SignUpScreenState extends ConsumerState<SignUpScreen> {
|
||||||
password: _passwordController.text,
|
password: _passwordController.text,
|
||||||
handle: _handleController.text.trim(),
|
handle: _handleController.text.trim(),
|
||||||
displayName: _displayNameController.text.trim(),
|
displayName: _displayNameController.text.trim(),
|
||||||
turnstileToken: _turnstileToken!,
|
altchaToken: _altchaToken!,
|
||||||
acceptTerms: _acceptTerms,
|
acceptTerms: _acceptTerms,
|
||||||
acceptPrivacy: _acceptPrivacy,
|
acceptPrivacy: _acceptPrivacy,
|
||||||
emailNewsletter: _emailUpdates,
|
emailNewsletter: _emailUpdates,
|
||||||
|
|
@ -133,7 +133,7 @@ class _SignUpScreenState extends ConsumerState<SignUpScreen> {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_errorMessage = e.toString().replaceAll('Exception: ', '');
|
_errorMessage = e.toString().replaceAll('Exception: ', '');
|
||||||
_turnstileToken = null; // Reset Turnstile on error
|
_altchaToken = null; // Reset ALTCHA on error
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|
@ -437,7 +437,7 @@ class _SignUpScreenState extends ConsumerState<SignUpScreen> {
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: _turnstileToken != null
|
color: _altchaToken != null
|
||||||
? AppTheme.success
|
? AppTheme.success
|
||||||
: AppTheme.egyptianBlue.withValues(alpha: 0.3),
|
: AppTheme.egyptianBlue.withValues(alpha: 0.3),
|
||||||
width: 1,
|
width: 1,
|
||||||
|
|
@ -447,12 +447,16 @@ class _SignUpScreenState extends ConsumerState<SignUpScreen> {
|
||||||
padding: const EdgeInsets.all(AppTheme.spacingMd),
|
padding: const EdgeInsets.all(AppTheme.spacingMd),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
if (_turnstileToken == null) ...[
|
if (_altchaToken == null) ...[
|
||||||
TurnstileWidget(
|
AltchaWidget(
|
||||||
siteKey: _turnstileSiteKey,
|
onVerified: (token) {
|
||||||
onToken: (token) {
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_turnstileToken = token;
|
_altchaToken = token;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (error) {
|
||||||
|
setState(() {
|
||||||
|
_errorMessage = error;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ class _AltchaWidgetState extends State<AltchaWidget> {
|
||||||
hash = ((hash << 5) - hash) + challenge.codeUnitAt(i);
|
hash = ((hash << 5) - hash) + challenge.codeUnitAt(i);
|
||||||
hash = hash & 0xFFFFFFFF;
|
hash = hash & 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
return hash.toRadix(16).padLeft(8, '0');
|
return hash.toRadixString(16).padLeft(8, '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -106,7 +106,7 @@ class _AltchaWidgetState extends State<AltchaWidget> {
|
||||||
Icon(Icons.error, color: Colors.red),
|
Icon(Icons.error, color: Colors.red),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text('Security verification failed',
|
Text('Security verification failed',
|
||||||
style: widget.style?['textStyle'] ??
|
style: widget.style?['textStyle'] as TextStyle? ??
|
||||||
const TextStyle(color: Colors.red)),
|
const TextStyle(color: Colors.red)),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
|
|
@ -150,7 +150,7 @@ class _AltchaWidgetState extends State<AltchaWidget> {
|
||||||
Icon(Icons.check_circle, color: Colors.green),
|
Icon(Icons.check_circle, color: Colors.green),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text('Security verified',
|
Text('Security verified',
|
||||||
style: widget.style?['textStyle'] ??
|
style: widget.style?['textStyle'] as TextStyle? ??
|
||||||
TextStyle(color: Colors.green)),
|
TextStyle(color: Colors.green)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -169,7 +169,7 @@ class _AltchaWidgetState extends State<AltchaWidget> {
|
||||||
Icon(Icons.security, color: Colors.blue),
|
Icon(Icons.security, color: Colors.blue),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text('Please complete security verification',
|
Text('Please complete security verification',
|
||||||
style: widget.style?['textStyle'] ??
|
style: widget.style?['textStyle'] as TextStyle? ??
|
||||||
TextStyle(color: Colors.blue)),
|
TextStyle(color: Colors.blue)),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue