Skip to content

Commit

Permalink
fixed menu app password verification
Browse files Browse the repository at this point in the history
  • Loading branch information
twocanoes committed Dec 28, 2023
1 parent b54cf49 commit 93ac8b9
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 255 deletions.
12 changes: 6 additions & 6 deletions Profile Manifest/com.twocanoes.xcreds.plist
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<key>pfm_app_url</key>
<string>https://github.com/twocanoes/xcreds</string>
<key>pfm_description</key>
<string>XCreds 4.0 (6100) OAuth Settings</string>
<string>XCreds 4.0 (6174) OAuth Settings</string>
<key>pfm_documentation_url</key>
<string>https://twocanoes.com/knowledge-base/xcreds-admin-guide/#preferences</string>
<key>pfm_domain</key>
Expand Down Expand Up @@ -462,7 +462,7 @@ Note that Google does not support the offline_access scope so instead use the pr
<key>pfm_default</key>
<false/>
<key>pfm_description</key>
<string>Favor using XCreds&apos; local login screen over the cloud login UI.</string>
<string>Favor using XCreds' local login screen over the cloud login UI.</string>
<key>pfm_documentation_url</key>
<string>https://twocanoes.com/knowledge-base/xcreds-admin-guide/#preferences</string>
<key>pfm_name</key>
Expand Down Expand Up @@ -514,7 +514,7 @@ Note that Google does not support the offline_access scope so instead use the pr
</dict>
<dict>
<key>pfm_description</key>
<string>Name of OIDC claim that contains an alias to add to a user account. Usually this is the &quot;upn&quot; (eg syd@twocanoes.com) so the user can log in at the standard login window the same as the IdP login window. Adds the value to record name of the user account as an alias.</string>
<string>Name of OIDC claim that contains an alias to add to a user account. Usually this is the "upn" (eg syd@twocanoes.com) so the user can log in at the standard login window the same as the IdP login window. Adds the value to record name of the user account as an alias.</string>
<key>pfm_documentation_url</key>
<string>https://twocanoes.com/knowledge-base/xcreds-admin-guide/#preferences</string>
<key>pfm_name</key>
Expand Down Expand Up @@ -772,7 +772,7 @@ Note that Google does not support the offline_access scope so instead use the pr
<key>pfm_default</key>
<false/>
<key>pfm_description</key>
<string>Reset the keychain without prompting if the login password doesn&apos;t match the local password.</string>
<string>Reset the keychain without prompting if the login password doesn't match the local password.</string>
<key>pfm_documentation_url</key>
<string>https://twocanoes.com/knowledge-base/xcreds-admin-guide/#preferences</string>
<key>pfm_name</key>
Expand Down Expand Up @@ -881,9 +881,9 @@ Note that Google does not support the offline_access scope so instead use the pr
</dict>
<dict>
<key>pfm_description</key>
<string>Password element id of the html element that has the password. It is read by using JavaScript to get the value (for example, for Azure, the JavaScript document.getElementById(&apos;i0118&apos;).value is sent. If this default is not set, standard values for Azure and Google Cloud will be used. To find out this value, use a browser to inspect the source of the page that has the password on it. Find the id of the textfield that has the password. Fill in the password and then open the JavaScript console. Run:
<string>Password element id of the html element that has the password. It is read by using JavaScript to get the value (for example, for Azure, the JavaScript document.getElementById('i0118').value is sent. If this default is not set, standard values for Azure and Google Cloud will be used. To find out this value, use a browser to inspect the source of the page that has the password on it. Find the id of the textfield that has the password. Fill in the password and then open the JavaScript console. Run:
document.getElementById(&apos;passwordID&apos;).value
document.getElementById('passwordID').value
changing “passwordID” to the correct element ID. If the value you typed into the textfield is returned, this is the correct ID.</string>
<key>pfm_documentation_url</key>
Expand Down
245 changes: 80 additions & 165 deletions XCreds/MainController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,91 +7,7 @@

import Cocoa
import OIDCLite
class MainController: NSObject, NoMADUserSessionDelegate, TokenManagerFeedbackDelegate {
func credentialsUpdated(_ credentials: Creds) {



DispatchQueue.main.async {
sharedMainMenu.windowController.window?.close()


// guard let tokens = credentials else {
// let alert = NSAlert()
// alert.addButton(withTitle: "OK")
// alert.messageText="Invalid tokens or password not determined. Please check the log."
// alert.runModal()
// return
// }
if let refreshToken = credentials.refreshToken, refreshToken.count>0 {
// Mark()
sharedMainMenu.statusBarItem.button?.image=NSImage(named: "xcreds menu icon check")
}
let localAccountAndPassword = self.localAccountAndPassword()
if var localPassword=localAccountAndPassword.1{
if (localPassword != credentials.password){
var updatePassword = true
if DefaultsOverride.standardOverride.bool(forKey: PrefKeys.verifyPassword.rawValue)==true {
let verifyOIDPassword = VerifyOIDCPasswordWindowController.init(windowNibName: NSNib.Name("VerifyOIDCPassword"))
NSApp.activate(ignoringOtherApps: true)

while true {
let response = NSApp.runModal(for: verifyOIDPassword.window!)
if response == .cancel {

let alert = NSAlert()
alert.addButton(withTitle: "Skip Updating Password")
alert.addButton(withTitle: "Cancel")
alert.messageText="Are you sure you want to skip updating the local password and keychain? You local password and keychain will be out of sync with your cloud password. "
let resp = alert.runModal()
if resp == .alertFirstButtonReturn {
NSApp.stopModal(withCode: .cancel)
verifyOIDPassword.window?.close()
updatePassword=false
break

}
}
let verifyCloudPassword = verifyOIDPassword.password
if verifyCloudPassword == credentials.password {

updatePassword=true

verifyOIDPassword.window?.close()
break;
}
else {
verifyOIDPassword.window?.shake(self)
}

}
}
if updatePassword {
let updatedLocalAccountAndPassword = self.localAccountAndPassword()
if let updatedLocalPassword = updatedLocalAccountAndPassword.1{

localPassword=updatedLocalPassword
try? PasswordUtils.changeLocalUserAndKeychainPassword(updatedLocalPassword, newPassword: localPassword)
}


}
}
}
if TokenManager.saveTokensToKeychain(creds: credentials, setACL: true, password:credentials.password ) == false {
TCSLogErrorWithMark("error saving tokens to keychain")
}
ScheduleManager.shared.startCredentialCheck()

}
}



func tokenError(_ err: String) {
TCSLogWithMark("Token error: \(err)")
}

class MainController: NSObject, NoMADUserSessionDelegate {
func NoMADAuthenticationSucceded() {
session?.userInfo()

Expand Down Expand Up @@ -185,86 +101,85 @@ class MainController: NSObject, NoMADUserSessionDelegate, TokenManagerFeedbackDe
})

}
// NotificationCenter.default.addObserver(forName: Notification.Name("TCSTokensUpdated"), object: nil, queue: nil) { notification in
//
//
// DispatchQueue.main.async {
// sharedMainMenu.windowController.window?.close()
//
// guard let tokenInfo = notification.userInfo else {
// return
// }
//
// guard let tokens = tokenInfo["tokens"] as? Creds else {
// let alert = NSAlert()
// alert.addButton(withTitle: "OK")
// alert.messageText="Invalid tokens or password not determined. Please check the log."
// alert.runModal()
// return
// }
// if let refreshToken = tokens.refreshToken, refreshToken.count>0 {
// // Mark()
// sharedMainMenu.statusBarItem.button?.image=NSImage(named: "xcreds menu icon check")
// }
// let localAccountAndPassword = self.localAccountAndPassword()
// if var localPassword=localAccountAndPassword.1{
// if (localPassword != tokens.password){
// var updatePassword = true
// if DefaultsOverride.standardOverride.bool(forKey: PrefKeys.verifyPassword.rawValue)==true {
// let verifyOIDPassword = VerifyOIDCPasswordWindowController.init(windowNibName: NSNib.Name("VerifyOIDCPassword"))
// NSApp.activate(ignoringOtherApps: true)
//
// while true {
// let response = NSApp.runModal(for: verifyOIDPassword.window!)
// if response == .cancel {
//
// let alert = NSAlert()
// alert.addButton(withTitle: "Skip Updating Password")
// alert.addButton(withTitle: "Cancel")
// alert.messageText="Are you sure you want to skip updating the local password and keychain? You local password and keychain will be out of sync with your cloud password. "
// let resp = alert.runModal()
// if resp == .alertFirstButtonReturn {
// NSApp.stopModal(withCode: .cancel)
// verifyOIDPassword.window?.close()
// updatePassword=false
// break
//
// }
// }
// let verifyCloudPassword = verifyOIDPassword.password
// if verifyCloudPassword == tokens.password {
//
// updatePassword=true
//
// verifyOIDPassword.window?.close()
// break;
// }
// else {
// verifyOIDPassword.window?.shake(self)
// }
//
// }
// }
// if updatePassword {
// let updatedLocalAccountAndPassword = self.localAccountAndPassword()
// if let updatedLocalPassword = updatedLocalAccountAndPassword.1{
//
// localPassword=updatedLocalPassword
// try? PasswordUtils.changeLocalUserAndKeychainPassword(updatedLocalPassword, newPassword: localPassword)
// }
//
//
// }
// }
// }
// if TokenManager.saveTokensToKeychain(creds: tokens, setACL: true, password:tokens.password ) == false {
// TCSLogErrorWithMark("error saving tokens to keychain")
// }
// ScheduleManager.shared.startCredentialCheck()
//
// }
// }
ScheduleManager.shared.feedbackDelegate=self
NotificationCenter.default.addObserver(forName: Notification.Name("TCSTokensUpdated"), object: nil, queue: nil) { notification in


DispatchQueue.main.async {
sharedMainMenu.windowController.window?.close()

guard let tokenInfo = notification.userInfo else {
return
}

guard let tokens = tokenInfo["credentials"] as? Creds else {
let alert = NSAlert()
alert.addButton(withTitle: "OK")
alert.messageText="Invalid tokens or password not determined. Please check the log."
alert.runModal()
return
}
if let refreshToken = tokens.refreshToken, refreshToken.count>0 {
// Mark()
sharedMainMenu.statusBarItem.button?.image=NSImage(named: "xcreds menu icon check")
}
let localAccountAndPassword = self.localAccountAndPassword()
if var localPassword=localAccountAndPassword.1{
if (localPassword != tokens.password){
var updatePassword = true
if DefaultsOverride.standardOverride.bool(forKey: PrefKeys.verifyPassword.rawValue)==true {
let verifyOIDPassword = VerifyOIDCPasswordWindowController.init(windowNibName: NSNib.Name("VerifyOIDCPassword"))
NSApp.activate(ignoringOtherApps: true)

while true {
let response = NSApp.runModal(for: verifyOIDPassword.window!)
if response == .cancel {

let alert = NSAlert()
alert.addButton(withTitle: "Skip Updating Password")
alert.addButton(withTitle: "Cancel")
alert.messageText="Are you sure you want to skip updating the local password and keychain? You local password and keychain will be out of sync with your cloud password. "
let resp = alert.runModal()
if resp == .alertFirstButtonReturn {
NSApp.stopModal(withCode: .cancel)
verifyOIDPassword.window?.close()
updatePassword=false
break

}
}
let verifyCloudPassword = verifyOIDPassword.password
if verifyCloudPassword == tokens.password {

updatePassword=true

verifyOIDPassword.window?.close()
break;
}
else {
verifyOIDPassword.window?.shake(self)
}

}
}
if updatePassword {
let updatedLocalAccountAndPassword = self.localAccountAndPassword()
if let updatedLocalPassword = updatedLocalAccountAndPassword.1{

localPassword=updatedLocalPassword
try? PasswordUtils.changeLocalUserAndKeychainPassword(updatedLocalPassword, newPassword: localPassword)
}


}
}
}
if TokenManager.saveTokensToKeychain(creds: tokens, setACL: true, password:tokens.password ) == false {
TCSLogErrorWithMark("error saving tokens to keychain")
}
ScheduleManager.shared.startCredentialCheck()

}
}
//delay startup to give network time to settle.
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { timer in
ScheduleManager.shared.startCredentialCheck()
Expand Down
62 changes: 24 additions & 38 deletions XCreds/ScheduleManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,41 @@
//

import Cocoa
import OIDCLite

class ScheduleManager:TokenManagerFeedbackDelegate {
func credentialsUpdated(_ credentials: Creds) {

if DefaultsOverride.standardOverride.bool(forKey: PrefKeys.showDebug.rawValue) == true {
NotifyManager.shared.sendMessage(message: "Password check successful")
}
DispatchQueue.main.async {
sharedMainMenu.signedIn=true
sharedMainMenu.buildMenu()
}

}


func tokenError(_ err: String) {
feedbackDelegate?.tokenError(err)
TCSLogErrorWithMark("authFailure: \(err)")
// NotificationCenter.default.post(name: Notification.Name("TCSTokensUpdated"), object: self, userInfo:[:])
if DefaultsOverride.standardOverride.bool(forKey: PrefKeys.showDebug.rawValue) == true {

NotifyManager.shared.sendMessage(message: "Password changed or not set")
}
DispatchQueue.main.async {

SignInMenuItem().doAction()
}

}


static let shared=ScheduleManager()
var tokenManager=TokenManager()
var nextCheckTime = Date()
var timer:Timer?
var feedbackDelegate:TokenManagerFeedbackDelegate?
// var feedbackDelegate:TokenManagerFeedbackDelegate?
func setNextCheckTime() {
var rate = DefaultsOverride.standardOverride.double(forKey: PrefKeys.refreshRateHours.rawValue)
var minutesRate = DefaultsOverride.standardOverride.double(forKey: PrefKeys.refreshRateMinutes.rawValue)
Expand Down Expand Up @@ -75,42 +92,11 @@ class ScheduleManager:TokenManagerFeedbackDelegate {
setNextCheckTime()
TCSLogWithMark("Checking token now (\(Date())). Next token check will be at \(nextCheckTime)")

tokenManager.getNewAccessToken { res in

switch res {

case .success:
if DefaultsOverride.standardOverride.bool(forKey: PrefKeys.showDebug.rawValue) == true {
NotifyManager.shared.sendMessage(message: "Password check successful")
}
DispatchQueue.main.async {
sharedMainMenu.signedIn=true
sharedMainMenu.buildMenu()
}

case .passwordChanged:
//don't stop cred check otherwise it doesn't get restarted.
// self.stopCredentialCheck()
if DefaultsOverride.standardOverride.bool(forKey: PrefKeys.showDebug.rawValue) == true {

NotifyManager.shared.sendMessage(message: "Password changed or not set")
}
DispatchQueue.main.async {

SignInMenuItem().doAction()
}

case .error (let message):
if DefaultsOverride.standardOverride.bool(forKey: PrefKeys.showDebug.rawValue) == true {

NotifyManager.shared.sendMessage(message: message)
}

return

}
tokenManager.feedbackDelegate=self
tokenManager.getNewAccessToken()



}

}

Expand Down

0 comments on commit 93ac8b9

Please sign in to comment.