1
0
forked from baron/baron-sso

namecard 연동

This commit is contained in:
2026-01-06 09:49:11 +09:00
parent c56368d1cb
commit c512f0f4e6
13 changed files with 693 additions and 50 deletions

View File

@@ -0,0 +1,38 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter_dotenv/flutter_dotenv.dart';
class AuditService {
static final String _baseUrl = dotenv.env['BACKEND_URL'] ?? 'http://localhost:3000';
static Future<void> logEvent({
required String userId,
required String eventType,
required String status,
String? details,
}) async {
final url = Uri.parse('$_baseUrl/api/v1/audit');
try {
final response = await http.post(
url,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'user_id': userId,
'event_type': eventType,
'status': status,
'details': details,
'timestamp': DateTime.now().toIso8601String(),
}),
);
if (response.statusCode >= 200 && response.statusCode < 300) {
print("Audit log sent successfully");
} else {
print("Failed to send audit log: ${response.statusCode} ${response.body}");
}
} catch (e) {
print("Error sending audit log: $e");
}
}
}

View File

@@ -0,0 +1,76 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter_dotenv/flutter_dotenv.dart';
class AuthProxyService {
static final String _baseUrl = dotenv.env['BACKEND_URL'] ?? 'http://localhost:3000';
static Future<Map<String, dynamic>> initEnchantedLink(String loginId) async {
final url = Uri.parse('$_baseUrl/api/v1/auth/enchanted-link/init');
final response = await http.post(
url,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'loginId': loginId,
'uri': 'http://localhost:5000', // Use 5000 as it's definitely allowed
}),
);
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Failed to init login: ${response.body}');
}
}
static Future<Map<String, dynamic>> pollEnchantedLink(String pendingRef) async {
final url = Uri.parse('$_baseUrl/api/v1/auth/enchanted-link/poll');
final response = await http.post(
url,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'pendingRef': pendingRef,
}),
);
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Polling failed: ${response.body}');
}
}
static Future<void> verifyMagicLink(String token) async {
final url = Uri.parse('$_baseUrl/api/v1/auth/magic-link/verify');
final response = await http.post(
url,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'token': token,
}),
);
if (response.statusCode != 200) {
throw Exception('Verification failed: ${response.body}');
}
}
static Future<void> logError(String message) async {
final url = Uri.parse('$_baseUrl/api/v1/client-log');
try {
await http.post(
url,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'level': 'ERROR',
'message': message,
}),
);
} catch (_) {
// Ignore logging errors to prevent loops
}
}
}

View File

@@ -0,0 +1,13 @@
import 'web_auth_integration_stub.dart'
if (dart.library.html) 'web_auth_integration_web.dart';
abstract class WebAuthIntegration {
static void sendLoginSuccess(String token) {
// Platform-specific implementation
implSendLoginSuccess(token);
}
static bool isPopup() {
return implIsPopup();
}
}

View File

@@ -0,0 +1,8 @@
void implSendLoginSuccess(String token) {
// No-op on non-web platforms
print("Not on web: Login Success with token: $token");
}
bool implIsPopup() {
return false;
}

View File

@@ -0,0 +1,37 @@
import 'dart:html' as html;
void implSendLoginSuccess(String token) {
final message = {'type': 'LOGIN_SUCCESS', 'token': token};
bool sent = false;
// 1. Try postMessage
if (html.window.opener != null) {
try {
html.window.opener!.postMessage(message, '*');
sent = true;
print("Sent login success message to opener");
} catch (e) {
print("Failed to postMessage: $e");
}
// 2. Fallback: Redirect opener directly (Force refresh with token)
try {
// Only redirect if it's localhost:8000 to be safe, or just do it.
// This will cause the parent window to reload, which is fine for login.
html.window.opener!.location.href = "http://localhost:8000?token=$token";
sent = true;
} catch (e) {
print("Failed to redirect opener: $e");
}
}
if (!sent) {
print("No opener found. Redirecting current window to target.");
// Fallback: Redirect THIS window to localhost:8000 with token
html.window.location.href = "http://localhost:8000?token=$token";
}
}
bool implIsPopup() {
return html.window.opener != null;
}