Skip to content

Commit

Permalink
start of login window
Browse files Browse the repository at this point in the history
  • Loading branch information
twocanoes committed Jul 3, 2022
1 parent f1c4593 commit ce6cc87
Show file tree
Hide file tree
Showing 23 changed files with 771 additions and 67 deletions.
8 changes: 4 additions & 4 deletions Profile Manifest/com.twocanoes.xcreds.plist
Original file line number Diff line number Diff line change
Expand Up @@ -383,15 +383,15 @@ A profile can consist of payloads with different version numbers. For example, c

<dict>
<key>pfm_name</key>
<string>shouldHideAboutMenu</string>
<string>shouldShowAboutMenu</string>
<key>pfm_type</key>
<string>boolean</string>
<key>pfm_title</key>
<string>Hide About Menu</string>
<string>Show About Menu</string>
<key>pfm_description</key>
<string>Hide the about menu</string>
<string>Show the about menu</string>
<key>pfm_default</key>
<false/>
<true/>
</dict>
<dict>
<key>pfm_name</key>
Expand Down
2 changes: 1 addition & 1 deletion Sample Profile/xcreds_example_azure.mobileconfig
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<key>PayloadOrganization</key>
<string>Twocanoes</string>
<key>PayloadScope</key>
<string>User</string>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
Expand Down
18 changes: 18 additions & 0 deletions Shared/ManagedPreferences.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// ManagedPreferences.swift
// XCreds
//
// Created by Timothy Perfitt on 7/2/22.
//

import Foundation

class ManagedPreferences {
static let shared = ManagedPreferences()

init() {

}



2 changes: 1 addition & 1 deletion XCreds/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {

func applicationDidFinishLaunching(_ aNotification: Notification) {


// ManagedPreferences.shared.preference(forKey: .clientID)
mainController = MainController.init()
mainController?.run()
mainMenu.statusBarItem.menu = mainMenu.mainMenu
Expand Down
4 changes: 2 additions & 2 deletions XCreds/MainMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class MainMenu: NSObject, NSMenuDelegate {
mainMenu.removeAllItems()

// add menu items
if UserDefaults.standard.bool(forKey: PrefKeys.shouldHideAboutMenu.rawValue)==false{
if UserDefaults.standard.bool(forKey: PrefKeys.shouldShowAboutMenu.rawValue)==true{
mainMenu.addItem(AboutMenuItem())
mainMenu.addItem(NSMenuItem.separator())
firstItemShown = true
Expand All @@ -62,7 +62,7 @@ class MainMenu: NSObject, NSMenuDelegate {
mainMenu.addItem(SignInMenuItem())
mainMenu.addItem(CheckTokenMenuItem())
mainMenu.addItem(PrefsMenuItem())
if UserDefaults.standard.bool(forKey: PrefKeys.shouldHideQuit.rawValue)==false{
if UserDefaults.standard.bool(forKey: PrefKeys.shouldShowQuitMenu.rawValue)==true{
let quitMenuItem = NSMenuItem(title: "Quit", action:#selector(NSApp.terminate(_:)), keyEquivalent: "")

mainMenu.addItem(NSMenuItem.separator())
Expand Down
2 changes: 1 addition & 1 deletion XCreds/PrefKeys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
import Foundation

enum PrefKeys: String {
case clientID, clientSecret, discoveryURL, redirectURI, scopes, accessToken, idToken, refreshToken, tokenEndpoint, expirationDate, invalidToken, refreshRateHours, showDebug, verifyPassword, shouldHideQuit, shouldShowPreferencesOnStart, shouldSetGoogleAccessTypeToOffline, passwordChangeURL, shouldHideAboutMenu
case clientID, clientSecret, discoveryURL, redirectURI, scopes, accessToken, idToken, refreshToken, tokenEndpoint, expirationDate, invalidToken, refreshRateHours, showDebug, verifyPassword, shouldShowQuitMenu, shouldShowPreferencesOnStart, shouldSetGoogleAccessTypeToOffline, passwordChangeURL, shouldShowAboutMenu
}
2 changes: 1 addition & 1 deletion XCreds/SignInMenuItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class SignInMenuItem: NSMenuItem {
mainMenu.webView = WebViewController()
}
mainMenu.webView?.window!.forceToFrontAndFocus(nil)
mainMenu.webView?.run()
mainMenu.webView?.loadPage()
}
else {
if UserDefaults.standard.bool(forKey: PrefKeys.shouldShowPreferencesOnStart.rawValue)==true{
Expand Down
40 changes: 13 additions & 27 deletions XCreds/WebView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class WebViewController: NSWindowController {

var oidcLite: OIDCLite?
var password:String?
func run() {
func loadPage() {

var scopes: [String]?
var clientSecret: String?
Expand All @@ -40,7 +40,7 @@ class WebViewController: NSWindowController {
if UserDefaults.standard.bool(forKey: PrefKeys.shouldSetGoogleAccessTypeToOffline.rawValue) == true {
additionalParameters = ["access_type":"offline", "prompt":"consent"]
}

TCSLog("redirect URI: \(UserDefaults.standard.string(forKey: PrefKeys.redirectURI.rawValue) ?? "NONE")")
oidcLite = OIDCLite(discoveryURL: UserDefaults.standard.string(forKey: PrefKeys.discoveryURL.rawValue) ?? "NONE", clientID: UserDefaults.standard.string(forKey: PrefKeys.clientID.rawValue) ?? "NONE", clientSecret: clientSecret, redirectURI: UserDefaults.standard.string(forKey: PrefKeys.redirectURI.rawValue), scopes: scopes, additionalParameters:additionalParameters )
webView.navigationDelegate = self
oidcLite?.delegate = self
Expand Down Expand Up @@ -82,23 +82,18 @@ class WebViewController: NSWindowController {
extension WebViewController: WKNavigationDelegate {

public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
// print("WebDel:: Deciding Policy for: \(navigationAction.request.url?.absoluteString ?? "None")")
TCSLog("DecidePolicyFor: \(navigationAction.request.url?.absoluteString ?? "None")")

// if it's a POST let's see what we're posting...
if navigationAction.request.httpMethod == "POST" {
// Azure snarfing
TCSLog("Azure")
if navigationAction.request.url?.host == "login.microsoftonline.com" {
var javaScript = "document.getElementById('i0118').value"
webView.evaluateJavaScript(javaScript, completionHandler: { response, error in
if let rawPass = response as? String {
self.password=rawPass
}
// let alert = NSAlert.init()
// alert.messageText = "Your password is: \(rawPass)"
// RunLoop.main.perform {
// alert.runModal()
// }
// }
})
javaScript = "document.getElementById('confirmNewPassword').value"
webView.evaluateJavaScript(javaScript, completionHandler: { response, error in
Expand All @@ -108,32 +103,20 @@ extension WebViewController: WKNavigationDelegate {
})
} else if navigationAction.request.url?.host == "accounts.google.com" {
// Google snarfing
TCSLog("Google")
let javaScript = "document.querySelector('input[type=password]').value"
webView.evaluateJavaScript(javaScript, completionHandler: { response, error in
if let rawPass = response as? String {
self.password=rawPass
}

// if let rawPass = response as? String,
// rawPass != "" {
// let alert = NSAlert.init()
// alert.messageText = "Your password is: \(rawPass)"
// RunLoop.main.perform {
// alert.runModal()
// }
// }
})
} else if navigationAction.request.url?.path.contains("verify") ?? false {
// maybe OneLogin?
TCSLog("Other Provider")

let javaScript = "document.getElementById('input8').value"
webView.evaluateJavaScript(javaScript, completionHandler: { response, error in
// if let rawPass = response as? String {
// let alert = NSAlert.init()
// alert.messageText = "Your password is: \(rawPass)"
// RunLoop.main.perform {
// alert.runModal()
// }
// }
})
}
} else if navigationAction.request.httpMethod == "GET" && navigationAction.request.url?.path.contains("token/redirect") ?? false {
Expand Down Expand Up @@ -184,9 +167,11 @@ extension WebViewController: WKNavigationDelegate {
}

func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
print("WebDel:: Did Receive Redirect for: \(webView.url?.absoluteString ?? "None")")
TCSLog("WebDel:: Did Receive Redirect for: \(webView.url?.absoluteString ?? "None")")

if let redirectURI = oidcLite?.redirectURI {
TCSLog("redirectURI: \(redirectURI)")
TCSLog("URL: \(webView.url?.absoluteString ?? "NONE")")
if (webView.url?.absoluteString.starts(with: (redirectURI))) ?? false {
var code = ""
let fullCommand = webView.url?.absoluteString ?? ""
Expand Down Expand Up @@ -225,16 +210,17 @@ extension WebViewController: WKNavigationDelegate {
extension WebViewController: OIDCLiteDelegate {

func authFailure(message: String) {
print("Auth failure :(")
TCSLog("authFailure: \(message)")
NotificationCenter.default.post(name: Notification.Name("TCSTokensUpdated"), object: self, userInfo:[:])

}

func tokenResponse(tokens: OIDCLiteTokenResponse) {

TCSLog("tokenResponse")
RunLoop.main.perform {
self.window?.close()
if let password = self.password {
TCSLog("password received")
NotificationCenter.default.post(name: Notification.Name("TCSTokensUpdated"), object: self, userInfo:
[
"password":password,
Expand Down
33 changes: 10 additions & 23 deletions XCreds/WebView.xib
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,40 @@
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="WebViewController" customModule="XCreds" customModuleProvider="target">
<connections>
<outlet property="cancelButton" destination="k1y-g2-hDK" id="OP0-sn-o5u"/>
<outlet property="webView" destination="p1x-1L-05D" id="hJN-Xq-dh8"/>
<outlet property="window" destination="KxT-zM-Vnn" id="v4i-bY-4eE"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Sign In" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="KxT-zM-Vnn">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<window title="Sign In" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="KxT-zM-Vnn" customClass="LoginWindow">
<windowStyleMask key="styleMask" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="453" y="250" width="628" height="613"/>
<rect key="screenRect" x="0.0" y="0.0" width="1536" height="935"/>
<view key="contentView" wantsLayer="YES" id="2LH-tE-efn">
<rect key="frame" x="0.0" y="0.0" width="628" height="613"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<wkWebView wantsLayer="YES" translatesAutoresizingMaskIntoConstraints="NO" id="p1x-1L-05D">
<rect key="frame" x="0.0" y="64" width="628" height="549"/>
<wkWebViewConfiguration key="configuration">
<wkWebView wantsLayer="YES" allowsLinkPreview="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p1x-1L-05D">
<rect key="frame" x="0.0" y="0.0" width="628" height="613"/>
<wkWebViewConfiguration key="configuration" allowsAirPlayForMediaPlayback="NO" suppressesIncrementalRendering="YES">
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/>
<wkPreferences key="preferences"/>
<wkPreferences key="preferences" javaScriptCanOpenWindowsAutomatically="NO"/>
</wkWebViewConfiguration>
</wkWebView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="k1y-g2-hDK">
<rect key="frame" x="539" y="13" width="76" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ksj-eV-tj1">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="clickCancel:" target="-2" id="wA4-1u-JJQ"/>
<outlet property="UIDelegate" destination="-2" id="Qhy-Dl-wsg"/>
</connections>
</button>
</wkWebView>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="p1x-1L-05D" secondAttribute="trailing" id="3Xb-lz-75r"/>
<constraint firstAttribute="trailing" secondItem="k1y-g2-hDK" secondAttribute="trailing" constant="20" symbolic="YES" id="7i7-Zq-FS8"/>
<constraint firstAttribute="bottom" secondItem="k1y-g2-hDK" secondAttribute="bottom" constant="20" symbolic="YES" id="S7Q-4g-cc3"/>
<constraint firstItem="k1y-g2-hDK" firstAttribute="top" secondItem="p1x-1L-05D" secondAttribute="bottom" constant="24" id="bK2-wq-WpJ"/>
<constraint firstItem="p1x-1L-05D" firstAttribute="leading" secondItem="2LH-tE-efn" secondAttribute="leading" id="ejy-F7-Axt"/>
<constraint firstItem="p1x-1L-05D" firstAttribute="top" secondItem="2LH-tE-efn" secondAttribute="top" id="gmG-FO-hZc"/>
<constraint firstAttribute="bottom" secondItem="p1x-1L-05D" secondAttribute="bottom" id="vCP-fw-q3U"/>
</constraints>
</view>
<point key="canvasLocation" x="142" y="302.5"/>
<point key="canvasLocation" x="250" y="297.5"/>
</window>
</objects>
</document>
6 changes: 6 additions & 0 deletions XCreds/XCredsLoginPlugin-Bridging-Header.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//

#import "XCredsLoginPlugin.h"
#import "TCSUnifiedLogger.h"
6 changes: 4 additions & 2 deletions XCreds/defaults.plist
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
<true/>
<key>LogFileName</key>
<string>xcreds.log</string>
<key>shouldHideQuit</key>
<false/>
<key>shouldShowPreferencesOnStart</key>
<false/>
<key>shouldSetGoogleAccessTypeToOffline</key>
<false/>
<key>shouldShowAboutMenu</key>
<true/>
<key>shouldShowQuitMenu</key>
<true/>
</dict>
</plist>
46 changes: 46 additions & 0 deletions XCredsLoginPlugIn/LoginWebView.xib
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="20037" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="20037"/>
<plugIn identifier="com.apple.WebKit2IBPlugin" version="20037"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="WebViewController" customModule="XCredsLoginPlugin" customModuleProvider="target">
<connections>
<outlet property="webView" destination="p1x-1L-05D" id="hJN-Xq-dh8"/>
<outlet property="window" destination="KxT-zM-Vnn" id="v4i-bY-4eE"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Sign In" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" titleVisibility="hidden" id="KxT-zM-Vnn" customClass="LoginWindow" customModule="XCredsLoginPlugin" customModuleProvider="target">
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="453" y="250" width="628" height="613"/>
<rect key="screenRect" x="0.0" y="0.0" width="1536" height="935"/>
<view key="contentView" wantsLayer="YES" id="2LH-tE-efn">
<rect key="frame" x="0.0" y="0.0" width="628" height="613"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<wkWebView wantsLayer="YES" allowsLinkPreview="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p1x-1L-05D">
<rect key="frame" x="0.0" y="0.0" width="628" height="613"/>
<wkWebViewConfiguration key="configuration" allowsAirPlayForMediaPlayback="NO" suppressesIncrementalRendering="YES">
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/>
<wkPreferences key="preferences" javaScriptCanOpenWindowsAutomatically="NO"/>
</wkWebViewConfiguration>
<connections>
<outlet property="UIDelegate" destination="-2" id="Qhy-Dl-wsg"/>
</connections>
</wkWebView>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="p1x-1L-05D" secondAttribute="trailing" id="3Xb-lz-75r"/>
<constraint firstItem="p1x-1L-05D" firstAttribute="leading" secondItem="2LH-tE-efn" secondAttribute="leading" id="ejy-F7-Axt"/>
<constraint firstItem="p1x-1L-05D" firstAttribute="top" secondItem="2LH-tE-efn" secondAttribute="top" id="gmG-FO-hZc"/>
<constraint firstAttribute="bottom" secondItem="p1x-1L-05D" secondAttribute="bottom" id="vCP-fw-q3U"/>
</constraints>
</view>
<point key="canvasLocation" x="250" y="297.5"/>
</window>
</objects>
</document>
45 changes: 45 additions & 0 deletions XCredsLoginPlugIn/LoginWebViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// WebView.swift
// xCreds
//
// Created by Timothy Perfitt on 4/5/22.
//

import Foundation
import Cocoa
import WebKit
import OIDCLite

class LoginWebViewController: WebViewController {
override func windowDidLoad() {
super.windowDidLoad()
setupLoginWindowAppearance()
loadPage()
}
fileprivate func setupLoginWindowAppearance() {
self.window?.level = .screenSaver
self.window?.orderFrontRegardless()

self.window?.backgroundColor = NSColor.black

self.window?.titlebarAppearsTransparent = true

self.window?.isMovable = false
self.window?.canBecomeVisibleWithoutLogin = true

let screenRect = NSScreen.screens[0].frame
self.window?.setFrame(screenRect, display: true, animate: false)

}


@objc override var windowNibName: NSNib.Name {
return NSNib.Name("LoginWebView")
}




}


15 changes: 15 additions & 0 deletions XCredsLoginPlugIn/LoginWindow.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// LoginWindow.swift
// XCredsLoginPlugin
//
// Created by Timothy Perfitt on 7/2/22.
//

import Cocoa

class LoginWindow: NSWindow {
override var canBecomeKey: Bool {
return true
}

}

0 comments on commit ce6cc87

Please sign in to comment.