forked from baron/baron-sso
WASM 빌드 호환성을 위한 Web API Interop 교체
This commit is contained in:
@@ -1,6 +1,16 @@
|
|||||||
// ignore_for_file: avoid_web_libraries_in_flutter, deprecated_member_use
|
// ignore_for_file: avoid_web_libraries_in_flutter
|
||||||
|
|
||||||
import 'dart:html' as html;
|
import 'dart:js_interop';
|
||||||
|
|
||||||
|
@JS('window.localStorage')
|
||||||
|
external _JSStorage get _localStorage;
|
||||||
|
|
||||||
|
@JS()
|
||||||
|
extension type _JSStorage(JSObject _) implements JSObject {
|
||||||
|
external String? getItem(String key);
|
||||||
|
external void setItem(String key, String value);
|
||||||
|
external void removeItem(String key);
|
||||||
|
}
|
||||||
|
|
||||||
class AuthTokenStore {
|
class AuthTokenStore {
|
||||||
static const _tokenKey = 'baron_auth_token';
|
static const _tokenKey = 'baron_auth_token';
|
||||||
@@ -8,43 +18,77 @@ class AuthTokenStore {
|
|||||||
static const _cookieModeKey = 'baron_auth_cookie_mode';
|
static const _cookieModeKey = 'baron_auth_cookie_mode';
|
||||||
static const _pendingProviderKey = 'baron_auth_pending_provider';
|
static const _pendingProviderKey = 'baron_auth_pending_provider';
|
||||||
|
|
||||||
String? getToken() => html.window.localStorage[_tokenKey];
|
String? getToken() {
|
||||||
|
try {
|
||||||
|
return _localStorage.getItem(_tokenKey);
|
||||||
|
} catch (_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String? getProvider() => html.window.localStorage[_providerKey];
|
String? getProvider() {
|
||||||
|
try {
|
||||||
|
return _localStorage.getItem(_providerKey);
|
||||||
|
} catch (_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool usesCookie() => html.window.localStorage[_cookieModeKey] == '1';
|
bool usesCookie() {
|
||||||
|
try {
|
||||||
|
return _localStorage.getItem(_cookieModeKey) == '1';
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setToken(String token, {String? provider}) {
|
void setToken(String token, {String? provider}) {
|
||||||
html.window.localStorage[_tokenKey] = token;
|
try {
|
||||||
html.window.localStorage.remove(_cookieModeKey);
|
_localStorage.setItem(_tokenKey, token);
|
||||||
if (provider != null) {
|
_localStorage.removeItem(_cookieModeKey);
|
||||||
html.window.localStorage[_providerKey] = provider;
|
if (provider != null) {
|
||||||
|
_localStorage.setItem(_providerKey, provider);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print("[AuthTokenStore] CRITICAL - Failed to set token: $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCookieMode({String? provider}) {
|
void setCookieMode({String? provider}) {
|
||||||
html.window.localStorage[_cookieModeKey] = '1';
|
try {
|
||||||
html.window.localStorage.remove(_tokenKey);
|
_localStorage.setItem(_cookieModeKey, '1');
|
||||||
if (provider != null) {
|
_localStorage.removeItem(_tokenKey);
|
||||||
html.window.localStorage[_providerKey] = provider;
|
if (provider != null) {
|
||||||
|
_localStorage.setItem(_providerKey, provider);
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
String? getPendingProvider() {
|
||||||
|
try {
|
||||||
|
return _localStorage.getItem(_pendingProviderKey);
|
||||||
|
} catch (_) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String? getPendingProvider() => html.window.localStorage[_pendingProviderKey];
|
|
||||||
|
|
||||||
void setPendingProvider(String? provider) {
|
void setPendingProvider(String? provider) {
|
||||||
if (provider == null || provider.isEmpty) {
|
try {
|
||||||
html.window.localStorage.remove(_pendingProviderKey);
|
if (provider == null || provider.isEmpty) {
|
||||||
return;
|
_localStorage.removeItem(_pendingProviderKey);
|
||||||
}
|
return;
|
||||||
html.window.localStorage[_pendingProviderKey] = provider;
|
}
|
||||||
|
_localStorage.setItem(_pendingProviderKey, provider);
|
||||||
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
html.window.localStorage.remove(_tokenKey);
|
try {
|
||||||
html.window.localStorage.remove(_providerKey);
|
_localStorage.removeItem(_tokenKey);
|
||||||
html.window.localStorage.remove(_cookieModeKey);
|
_localStorage.removeItem(_providerKey);
|
||||||
html.window.localStorage.remove(_pendingProviderKey);
|
_localStorage.removeItem(_cookieModeKey);
|
||||||
|
_localStorage.removeItem(_pendingProviderKey);
|
||||||
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export 'web_window_stub.dart' if (dart.library.html) 'web_window_web.dart';
|
export 'web_window_web.dart';
|
||||||
|
|||||||
@@ -1,11 +1,45 @@
|
|||||||
// ignore_for_file: avoid_web_libraries_in_flutter, deprecated_member_use
|
// ignore_for_file: avoid_web_libraries_in_flutter, deprecated_member_use
|
||||||
|
|
||||||
import 'dart:html' as html;
|
import 'dart:html' as html;
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: avoid_web_libraries_in_flutter
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:js_interop';
|
||||||
|
|
||||||
|
@JS('window')
|
||||||
|
external _JSWindow get _window;
|
||||||
|
|
||||||
|
@JS('document')
|
||||||
|
external _JSDocument get _document;
|
||||||
|
|
||||||
|
@JS()
|
||||||
|
extension type _JSWindow(JSObject _) implements JSObject {
|
||||||
|
external void alert(JSString message);
|
||||||
|
external void close();
|
||||||
|
external JSObject? get opener;
|
||||||
|
external _JSLocation get location;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JS()
|
||||||
|
extension type _JSDocument(JSObject _) implements JSObject {
|
||||||
|
external set title(JSString value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JS()
|
||||||
|
extension type _JSOpener(JSObject _) implements JSObject {
|
||||||
|
external _JSLocation get location;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JS()
|
||||||
|
extension type _JSLocation(JSObject _) implements JSObject {
|
||||||
|
external set href(JSString value);
|
||||||
|
}
|
||||||
|
|
||||||
class WebWindow {
|
class WebWindow {
|
||||||
void setTitle(String title) {
|
void setTitle(String title) {
|
||||||
html.document.title = title;
|
try {
|
||||||
|
_document.title = title.toJS;
|
||||||
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
void redirectTo(String url) {
|
void redirectTo(String url) {
|
||||||
@@ -28,7 +62,17 @@ class WebWindow {
|
|||||||
"[WebWindow] redirectTo start: current=$currentHref, target=$url, target_host=${targetUri?.host ?? ''}, target_path=${targetUri?.path ?? ''}, same_origin=$sameOrigin",
|
"[WebWindow] redirectTo start: current=$currentHref, target=$url, target_host=${targetUri?.host ?? ''}, target_path=${targetUri?.path ?? ''}, same_origin=$sameOrigin",
|
||||||
);
|
);
|
||||||
|
|
||||||
html.window.location.href = url;
|
print("[WebWindow] FINAL REDIRECT ATTEMPT. URL: $url");
|
||||||
|
// Explicitly use the href setter on the window.location object.
|
||||||
|
// This is the most standard-compliant way for JS Interop in WASM.
|
||||||
|
Future.delayed(Duration.zero, () {
|
||||||
|
try {
|
||||||
|
print("[WebWindow] Executing JS href assignment for: $url");
|
||||||
|
_window.location.href = url.toJS;
|
||||||
|
} catch (e) {
|
||||||
|
print("[WebWindow] CRITICAL JS ERROR: $e");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 이동이 차단되거나 즉시 원위치되는 경우를 추적하기 위한 후속 로그입니다.
|
// 이동이 차단되거나 즉시 원위치되는 경우를 추적하기 위한 후속 로그입니다.
|
||||||
Future<void>.delayed(const Duration(milliseconds: 800), () {
|
Future<void>.delayed(const Duration(milliseconds: 800), () {
|
||||||
@@ -54,24 +98,30 @@ class WebWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void alert(String message) {
|
void alert(String message) {
|
||||||
html.window.alert(message);
|
try {
|
||||||
|
_window.alert(message.toJS);
|
||||||
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
void close() {
|
void close() {
|
||||||
html.window.close();
|
try {
|
||||||
|
_window.close();
|
||||||
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasOpener() {
|
bool hasOpener() {
|
||||||
return html.window.opener != null;
|
try {
|
||||||
|
return _window.opener != null;
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool redirectOpenerTo(String url) {
|
bool redirectOpenerTo(String url) {
|
||||||
final opener = html.window.opener;
|
|
||||||
if (opener == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
opener.location.href = url;
|
final opener = _window.opener;
|
||||||
|
if (opener == null) return false;
|
||||||
|
(_JSOpener(opener)).location.href = url.toJS;
|
||||||
return true;
|
return true;
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user