Route passkey button through browser auth
This commit is contained in:
@@ -13,6 +13,19 @@ private final class WeakScriptMessageHandler: NSObject, WKScriptMessageHandler {
|
||||
}
|
||||
|
||||
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
||||
if message.name == "shdDesktopAuth" {
|
||||
let origin = message.frameInfo.securityOrigin
|
||||
let trustedHosts = ["shd.xyz.su", "dev-shd.xyz.su"]
|
||||
guard message.frameInfo.isMainFrame,
|
||||
origin.protocol.lowercased() == "https",
|
||||
trustedHosts.contains(origin.host.lowercased()) else {
|
||||
return
|
||||
}
|
||||
let environment: MainWindowController.Environment = origin.host.lowercased() == "dev-shd.xyz.su" ? .dev : .production
|
||||
controller?.signInWithPasskeyInBrowser(for: environment)
|
||||
return
|
||||
}
|
||||
|
||||
if message.name == "shdNativePrint" {
|
||||
controller?.printCurrentPage()
|
||||
}
|
||||
@@ -123,7 +136,43 @@ final class MainWindowController: NSWindowController, NSWindowDelegate, WKNaviga
|
||||
"""
|
||||
let userScript = WKUserScript(source: darkScript, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||
config.userContentController.addUserScript(userScript)
|
||||
|
||||
let passkeyBridgeScript = """
|
||||
(function() {
|
||||
document.addEventListener('click', function(event) {
|
||||
var path = window.location.pathname;
|
||||
while (path.length > 1 && path.endsWith('/')) {
|
||||
path = path.slice(0, -1);
|
||||
}
|
||||
if (path !== '/login' && path !== '/login/two-factor') {
|
||||
return;
|
||||
}
|
||||
|
||||
var target = event.target instanceof Element
|
||||
? event.target
|
||||
: (event.target && event.target.parentElement);
|
||||
if (!target || !target.closest('#btnPasskeyLogin, #twoFactorPasskey')) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
var bridge = window.webkit && window.webkit.messageHandlers
|
||||
? window.webkit.messageHandlers.shdDesktopAuth
|
||||
: null;
|
||||
if (bridge) {
|
||||
bridge.postMessage('passkey-login');
|
||||
}
|
||||
}, true);
|
||||
})();
|
||||
"""
|
||||
config.userContentController.addUserScript(
|
||||
WKUserScript(source: passkeyBridgeScript, injectionTime: .atDocumentStart, forMainFrameOnly: true)
|
||||
)
|
||||
config.userContentController.add(WeakScriptMessageHandler(controller: self), name: "shdNativePrint")
|
||||
config.userContentController.add(WeakScriptMessageHandler(controller: self), name: "shdDesktopAuth")
|
||||
|
||||
let container = NSView()
|
||||
container.translatesAutoresizingMaskIntoConstraints = false
|
||||
@@ -199,14 +248,18 @@ final class MainWindowController: NSWindowController, NSWindowDelegate, WKNaviga
|
||||
updateTitle()
|
||||
}
|
||||
|
||||
func signInWithPasskeyInBrowser() {
|
||||
func signInWithPasskeyInBrowser(for environment: Environment) {
|
||||
guard authSession == nil else { return }
|
||||
|
||||
guard environment == .dev else {
|
||||
presentDesktopAuthError("Вход по passkey в приложении пока подключён только для DEV.")
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
let verifier = try Self.randomBase64URLString(byteCount: 32)
|
||||
let state = try Self.randomBase64URLString(byteCount: 32)
|
||||
let challenge = Self.base64URLString(for: Data(SHA256.hash(data: Data(verifier.utf8))))
|
||||
let environment = currentEnv
|
||||
|
||||
guard let authorizationURL = makeAuthorizationURL(
|
||||
environment: environment,
|
||||
@@ -469,6 +522,7 @@ final class MainWindowController: NSWindowController, NSWindowDelegate, WKNaviga
|
||||
authSession?.cancel()
|
||||
authSession = nil
|
||||
webView.configuration.userContentController.removeScriptMessageHandler(forName: "shdNativePrint")
|
||||
webView.configuration.userContentController.removeScriptMessageHandler(forName: "shdDesktopAuth")
|
||||
AppDelegate.shared?.removeWindowController(self)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user