diff --git a/example/EasterEggs/icanhazdadjokes/ReadMe.md b/example/EasterEggs/icanhazdadjokes/ReadMe.md new file mode 100755 index 0000000..6aaaac3 --- /dev/null +++ b/example/EasterEggs/icanhazdadjokes/ReadMe.md @@ -0,0 +1,9 @@ +## icanhazdadjoke +--- +##### Author: [Zack McCauley](https://www.github.com/wardsparadox) + +### Description: +Curls on click icanhazdadjoke.com's API for a fun joke +Would recommend using the optionalDisplay:true keys to hide it + +### Preference Keys diff --git a/example/EasterEggs/icanhazdadjokes/com.github.wardsparadox.hello-it.eastereggs.icanhazdadjokes.sh b/example/EasterEggs/icanhazdadjokes/com.github.wardsparadox.hello-it.eastereggs.icanhazdadjokes.sh new file mode 100755 index 0000000..15c4233 --- /dev/null +++ b/example/EasterEggs/icanhazdadjokes/com.github.wardsparadox.hello-it.eastereggs.icanhazdadjokes.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Pending Updates Script for Managed Software Center +### The following line load the Hello IT bash script lib +. "$HELLO_IT_SCRIPT_SH_LIBRARY/com.github.ygini.hello-it.scriptlib.sh" + +function displayJoke { +osascript -e "display dialog \"$(curl -s -H "User-Agent: HelloIT" -H "Accept: text/plain" https://icanhazdadjoke.com/)\" buttons {\"Haha\"} with icon POSIX file \"/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ErasingIcon.icns\"" +} + + +function onClickAction { + displayJoke +} + +function setTitleAction { + updateTitle "Would you like to see a joke?" + updateState "${STATE[4]}" + updateTooltip "Brought to you by icanhazdadjoke.com" +} + +### The only things to do outside of a bash function is to call the main function defined by the Hello IT bash lib. +main "$@" + +exit 0 diff --git a/example/HelloITConfiguration_example.mobileconfig b/example/HelloITConfiguration_example.mobileconfig index 8251ee1..13fd8eb 100644 --- a/example/HelloITConfiguration_example.mobileconfig +++ b/example/HelloITConfiguration_example.mobileconfig @@ -87,7 +87,7 @@ com.github.ygini.hello-it.computerdetails.storagespace.sh title storagespace - periodic-run + repeat 3600 @@ -146,8 +146,6 @@ com.github.ygini.hello-it.ip.sh repeat 60 - periodic-run - 60 @@ -168,8 +166,6 @@ com.github.ygini.hello-it.networkdetails.macaddress.sh repeat 60 - periodic-run - 60 @@ -204,7 +200,7 @@ script com.github.ygini.hello-it.munki.pendingmscupdates.sh - periodic-run + repeat 360 title pendingupdatescount diff --git a/example/computer_details/ComputerUpTime/ReadMe.md b/example/computer_details/ComputerUpTime/ReadMe.md index c33be17..211f29c 100644 --- a/example/computer_details/ComputerUpTime/ReadMe.md +++ b/example/computer_details/ComputerUpTime/ReadMe.md @@ -18,7 +18,7 @@ Click to show a prompt to restart. com.github.wardsparadox.hello-it.computerdetails.uptime.sh title uptime - periodic-run + repeat 3600 diff --git a/example/munki_related/MSC Pending Updates/ReadMe.md b/example/munki_related/MSC Pending Updates/ReadMe.md index 29917c0..66f1e01 100644 --- a/example/munki_related/MSC Pending Updates/ReadMe.md +++ b/example/munki_related/MSC Pending Updates/ReadMe.md @@ -13,7 +13,7 @@ Provides user feedback as to how many Managed Software Center updates are availa script com.github.wardsparadox.hello-it.munki.pendingmscupdates.sh - periodic-run + repeat 360 title pendingupdatescount diff --git a/example/munki_related/com.github.ygini.Hello-IT.munkirelated.plist b/example/munki_related/com.github.ygini.Hello-IT.munkirelated.plist index 2f7cc65..2071c45 100644 --- a/example/munki_related/com.github.ygini.Hello-IT.munkirelated.plist +++ b/example/munki_related/com.github.ygini.Hello-IT.munkirelated.plist @@ -28,7 +28,7 @@ script com.github.wardsparadox.hello-it.munki.pendingmscupdates.sh - periodic-run + repeat 360 title pendingupdatescount diff --git a/package/BuildAndPackage.command b/package/BuildAndPackage.command index 562eec3..0eeec09 100755 --- a/package/BuildAndPackage.command +++ b/package/BuildAndPackage.command @@ -3,7 +3,9 @@ CONFIGURATION="Release" DEFAULT_DEVELOPER_ID_INSTALLER="Developer ID Installer: Yoann GINI (CRXPBZF3N4)" +DEFAULT_DEVELOPER_ID_APP="Developer ID Application: Yoann GINI (CRXPBZF3N4)" DEVELOPER_ID_INSTALLER=${CUSTOM_DEVELOPER_ID_INSTALLER:-${DEFAULT_DEVELOPER_ID_INSTALLER}} +DEVELOPER_ID_APP=${CUSTOM_DEVELOPER_ID_APP:-${DEFAULT_DEVELOPER_ID_APP}} NOTARIZATION_DEFAULT_DEVELOPER_ID_LOGIN="yoann.gini@gmail.com" NOTARIZATION_DEVELOPER_ID_LOGIN=${NOTARIZATION_CUSTOM_DEVELOPER_ID_LOGIN:-${NOTARIZATION_DEFAULT_DEVELOPER_ID_LOGIN}} @@ -185,6 +187,12 @@ RELEASE_DSYM_LOCATION="${RELEASE_LOCATION}/dSYM" PKG_ROOT="$(mktemp -d)" +if [[ -d "${RELEASE_LOCATION}" ]] +then + echo "Previous build found, cleaning all related files" + rm -rf "${RELEASE_LOCATION}" +fi + mkdir -p "${BUILT_PRODUCTS_DIR}/dSYM" mkdir -p "${BUILT_PRODUCTS_DIR}/Products" mkdir -p "${RELEASE_PRODUCT_LOCATION}" @@ -200,25 +208,32 @@ echo "### Start building Hello IT" xcodebuild -UseModernBuildSystem=NO -quiet -project "${PROJECT_DIR}/Hello IT.xcodeproj" -configuration ${CONFIGURATION} -target "Hello IT" CONFIGURATION_TEMP_DIR="${BUILT_PRODUCTS_DIR}/Intermediates" CONFIGURATION_BUILD_DIR="${BUILT_PRODUCTS_DIR}/Products" DWARF_DSYM_FOLDER_PATH="${BUILT_PRODUCTS_DIR}/dSYM" OTHER_CODE_SIGN_FLAGS="--timestamp" -cp -r "${BUILT_PRODUCTS_DIR}/Products/Hello IT.app" "${RELEASE_PRODUCT_LOCATION}" +if [[ $? != 0 ]]; then + echo "Building failed" + exit 1 +fi + +cp -a "${BUILT_PRODUCTS_DIR}/Products/Hello IT.app" "${RELEASE_PRODUCT_LOCATION}" + +codesign --deep --force --verbose --timestamp --options runtime --sign "${DEVELOPER_ID_APP}" "${RELEASE_PRODUCT_LOCATION}/Hello IT.app" echo "" echo "" -cp -r "${BUILT_PRODUCTS_DIR}/dSYM" "${RELEASE_DSYM_LOCATION}" +cp -a "${BUILT_PRODUCTS_DIR}/dSYM" "${RELEASE_DSYM_LOCATION}" echo "####### Create package from build" mkdir -p "${PKG_ROOT}//Applications/Utilities" -cp -r "${RELEASE_PRODUCT_LOCATION}/Hello IT.app" "${PKG_ROOT}/Applications/Utilities" +cp -a "${RELEASE_PRODUCT_LOCATION}/Hello IT.app" "${PKG_ROOT}/Applications/Utilities" mkdir -p "${PKG_ROOT}/Library/Application Support/com.github.ygini.hello-it/CustomImageForItem" mkdir -p "${PKG_ROOT}/Library/Application Support/com.github.ygini.hello-it/CustomStatusBarIcon" -cp -r "${PROJECT_DIR}/Plugins/ScriptedItem/CustomScripts" "${PKG_ROOT}/Library/Application Support/com.github.ygini.hello-it" +cp -a "${PROJECT_DIR}/Plugins/ScriptedItem/CustomScripts" "${PKG_ROOT}/Library/Application Support/com.github.ygini.hello-it" mkdir -p "${PKG_ROOT}/Library/LaunchAgents" -cp -r "${GIT_ROOT_DIR}/package/LaunchAgents/com.github.ygini.hello-it.plist" "${PKG_ROOT}/Library/LaunchAgents" +cp -a "${GIT_ROOT_DIR}/package/LaunchAgents/com.github.ygini.hello-it.plist" "${PKG_ROOT}/Library/LaunchAgents" #sudo chown -R root:wheel "${PKG_ROOT}" @@ -231,6 +246,11 @@ pkgbuild --component-plist "${PBK_BUILD_COMPONENT}" --sign "${DEVELOPER_ID_INSTA productbuild --product "${GIT_ROOT_DIR}/package/requirements.plist" --sign "${DEVELOPER_ID_INSTALLER}" --version "${PKG_VERSION}" --package "${RELEASE_LOCATION}/Hello-IT-${PKG_VERSION}-${CONFIGURATION}.pkg" "${RELEASE_LOCATION}/Hello-IT-${PKG_VERSION}-${CONFIGURATION}-Distribution.pkg" +if [[ $? != 0 ]]; then + echo "Package creation failed" + exit 1 +fi + rm "${RELEASE_LOCATION}/Hello-IT-${PKG_VERSION}-${CONFIGURATION}.pkg" notarizePayloadWithBundleID "${RELEASE_LOCATION}/Hello-IT-${PKG_VERSION}-${CONFIGURATION}-Distribution.pkg" "com.github.ygini.hello-it" diff --git a/src/HITDevKit/HITDevKit.xcodeproj/project.pbxproj b/src/HITDevKit/HITDevKit.xcodeproj/project.pbxproj index 2313e37..abc0b9a 100644 --- a/src/HITDevKit/HITDevKit.xcodeproj/project.pbxproj +++ b/src/HITDevKit/HITDevKit.xcodeproj/project.pbxproj @@ -203,7 +203,7 @@ E1B2C8C81B59351B005A9936 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1140; ORGANIZATIONNAME = "Yoann Gini (Open Source Project)"; TargetAttributes = { E1B2C8D01B59351B005A9936 = { @@ -415,7 +415,7 @@ E1B2C8E81B59351B005A9936 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEFINES_MODULE = YES; @@ -437,7 +437,7 @@ E1B2C8E91B59351B005A9936 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEFINES_MODULE = YES; diff --git a/src/HITDevKit/HITDevKit/HITBasicPlugin.m b/src/HITDevKit/HITDevKit/HITBasicPlugin.m index e9db6fe..e71c659 100644 --- a/src/HITDevKit/HITDevKit/HITBasicPlugin.m +++ b/src/HITDevKit/HITDevKit/HITBasicPlugin.m @@ -8,7 +8,7 @@ #import "HITBasicPlugin.h" -#define kHITPPptionalDisplay @"optionalDisplay" +#define kHITPOptionalDisplay @"optionalDisplay" @interface HITBasicPlugin () { NSMenuItem *_menuItem; @@ -33,7 +33,7 @@ - (instancetype)initWithSettings:(NSDictionary*)settings _allowedToRun = YES; _settings = settings; - _optionalDisplay = [[settings objectForKey:kHITPPptionalDisplay] boolValue]; + _optionalDisplay = [[settings objectForKey:kHITPOptionalDisplay] boolValue]; } return self; } diff --git a/src/HITDevKit/HITDevKit/Info.plist b/src/HITDevKit/HITDevKit/Info.plist index c05d1f1..d1f54ee 100644 --- a/src/HITDevKit/HITDevKit/Info.plist +++ b/src/HITDevKit/HITDevKit/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 351 + 367 NSHumanReadableCopyright Copyright © 2015 Yoann Gini (Open Source Project). All rights reserved. NSPrincipalClass diff --git a/src/Hello IT.xcodeproj/project.pbxproj b/src/Hello IT.xcodeproj/project.pbxproj index faff728..207e76a 100644 --- a/src/Hello IT.xcodeproj/project.pbxproj +++ b/src/Hello IT.xcodeproj/project.pbxproj @@ -45,6 +45,7 @@ F8340B9F1C96CF9000C820D7 /* statusbar@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F8340B8B1C96CF9000C820D7 /* statusbar@2x.png */; }; F84238FF20C8748200FB5410 /* CachetHQComponent.hitp in Copy Default Plugins */ = {isa = PBXBuildFile; fileRef = F8D61B8A20C8731A00DE2453 /* CachetHQComponent.hitp */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; F89B593B1DA7DC350028D75F /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = F89B593A1DA7DC350028D75F /* Reachability.m */; }; + F8F07637244EEFA200E3DF7B /* Command.hitp in Copy Default Plugins */ = {isa = PBXBuildFile; fileRef = F89A03522368A51D0059281B /* Command.hitp */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -146,6 +147,20 @@ remoteGlobalIDString = F83294A41F773076009DA574; remoteInfo = ADPass; }; + F89A03512368A51D0059281B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F89A034C2368A51C0059281B /* Command.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = F89A03432368A51C0059281B; + remoteInfo = Command; + }; + F8A258762452F66B00BB8A05 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F89A034C2368A51C0059281B /* Command.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = F89A03422368A51C0059281B; + remoteInfo = Command; + }; F8CF084221A729190070C049 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = F8D61B8520C8731A00DE2453 /* CachetHQ.xcodeproj */; @@ -232,6 +247,7 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( + F8F07637244EEFA200E3DF7B /* Command.hitp in Copy Default Plugins */, F84238FF20C8748200FB5410 /* CachetHQComponent.hitp in Copy Default Plugins */, F83294DD1F7736B5009DA574 /* ADPass.hitp in Copy Default Plugins */, E14B67DA1B59110D00941A27 /* ScriptedItem.hitp in Copy Default Plugins */, @@ -302,6 +318,7 @@ F8340B891C96CF9000C820D7 /* statusbar-warning@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "statusbar-warning@2x.png"; sourceTree = ""; }; F8340B8A1C96CF9000C820D7 /* statusbar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = statusbar.png; sourceTree = ""; }; F8340B8B1C96CF9000C820D7 /* statusbar@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "statusbar@2x.png"; sourceTree = ""; }; + F89A034C2368A51C0059281B /* Command.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Command.xcodeproj; path = Command/Command.xcodeproj; sourceTree = ""; }; F89B59391DA7DC350028D75F /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = ""; }; F89B593A1DA7DC350028D75F /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Reachability.m; sourceTree = ""; }; F8B315891FA6BB1400839784 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/MainMenu.strings; sourceTree = ""; }; @@ -354,6 +371,7 @@ E17743301B51E6E600A5B406 /* Plugins */ = { isa = PBXGroup; children = ( + F89A034C2368A51C0059281B /* Command.xcodeproj */, F8D61B8520C8731A00DE2453 /* CachetHQ.xcodeproj */, F83294AE1F773076009DA574 /* ADPass.xcodeproj */, E17743591B51EA8500A5B406 /* OpenResource.xcodeproj */, @@ -516,6 +534,14 @@ name = statusbar; sourceTree = ""; }; + F89A034D2368A51C0059281B /* Products */ = { + isa = PBXGroup; + children = ( + F89A03522368A51D0059281B /* Command.hitp */, + ); + name = Products; + sourceTree = ""; + }; F8D61B8620C8731A00DE2453 /* Products */ = { isa = PBXGroup; children = ( @@ -543,6 +569,7 @@ ); dependencies = ( F8F4E5771F1A73CC004E8789 /* PBXTargetDependency */, + F8A258772452F66B00BB8A05 /* PBXTargetDependency */, F842390220C8748800FB5410 /* PBXTargetDependency */, F86CCC0B1F790D250043CF55 /* PBXTargetDependency */, F8F4E5791F1A73CC004E8789 /* PBXTargetDependency */, @@ -623,6 +650,10 @@ ProductGroup = F8D61B8620C8731A00DE2453 /* Products */; ProjectRef = F8D61B8520C8731A00DE2453 /* CachetHQ.xcodeproj */; }, + { + ProductGroup = F89A034D2368A51C0059281B /* Products */; + ProjectRef = F89A034C2368A51C0059281B /* Command.xcodeproj */; + }, { ProductGroup = E1B2C8EE1B59351B005A9936 /* Products */; ProjectRef = E1B2C8ED1B59351B005A9936 /* HITDevKit.xcodeproj */; @@ -746,6 +777,13 @@ remoteRef = F83294B21F773078009DA574 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + F89A03522368A51D0059281B /* Command.hitp */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = Command.hitp; + remoteRef = F89A03512368A51D0059281B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; F8CF084321A729190070C049 /* CachetHQIncidents.hitp */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; @@ -856,6 +894,11 @@ name = ADPass; targetProxy = F86CCC0A1F790D250043CF55 /* PBXContainerItemProxy */; }; + F8A258772452F66B00BB8A05 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Command; + targetProxy = F8A258762452F66B00BB8A05 /* PBXContainerItemProxy */; + }; F8F4E5771F1A73CC004E8789 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = HITDevKit; diff --git a/src/Hello IT/Info.plist b/src/Hello IT/Info.plist index ebdcd56..d0cad90 100644 --- a/src/Hello IT/Info.plist +++ b/src/Hello IT/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.4.4 + 1.5.0 CFBundleSignature ???? CFBundleVersion - 351 + 367 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/src/Plugins/ADPass/ADPass.xcodeproj/project.pbxproj b/src/Plugins/ADPass/ADPass.xcodeproj/project.pbxproj index 2eaf891..666f2a4 100644 --- a/src/Plugins/ADPass/ADPass.xcodeproj/project.pbxproj +++ b/src/Plugins/ADPass/ADPass.xcodeproj/project.pbxproj @@ -81,6 +81,7 @@ isa = PBXNativeTarget; buildConfigurationList = F83294AB1F773076009DA574 /* Build configuration list for PBXNativeTarget "ADPass" */; buildPhases = ( + F89A03592368A5CF0059281B /* GitVersion */, F83294A11F773076009DA574 /* Sources */, F83294A21F773076009DA574 /* Frameworks */, F83294A31F773076009DA574 /* Resources */, @@ -140,6 +141,27 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + F89A03592368A5CF0059281B /* GitVersion */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = GitVersion; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "set -o errexit\nset -o nounset\n\nVERSION=$(git rev-list HEAD | wc -l)\n\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $VERSION\" \"${INFOPLIST_FILE}\"\n"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ F83294A11F773076009DA574 /* Sources */ = { isa = PBXSourcesBuildPhase; diff --git a/src/Plugins/ADPass/ADPass/HITPADPass.m b/src/Plugins/ADPass/ADPass/HITPADPass.m index df67a36..93d04cc 100644 --- a/src/Plugins/ADPass/ADPass/HITPADPass.m +++ b/src/Plugins/ADPass/ADPass/HITPADPass.m @@ -132,118 +132,121 @@ - (void)mainAction:(id)sender { } - (void)periodicAction:(NSTimer *)timer { - [self getPasswordExpiryDate]; - if (self.passwordExpiryDate) { - self.menuItem.hidden = NO; - [self updateTitle]; - } else { - asl_log(NULL, NULL, ASL_LEVEL_INFO, "No AD Password expiry date found, hidding menu item."); - self.menuItem.hidden = YES; - } + [self backgroundFetchPasswordExpiryDate]; } - (void)updateTitle { - NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay fromDate:[NSDate date] toDate:self.passwordExpiryDate options:0]; - long daysBeforeExpiry = (long)[components day]; - if (daysBeforeExpiry < 0) daysBeforeExpiry = 0; - - self.menuItem.title = [NSString stringWithFormat:self.willExpireFormat, daysBeforeExpiry]; - - if (self.lastADRequestSucceded) { - self.menuItem.target = self; - self.menuItem.toolTip = self.tooltip; - } else { - self.menuItem.target = nil; - self.menuItem.toolTip = self.offlineTooltip; - } - - if (daysBeforeExpiry <= self.alertXDaysBefore) { - NSDate *dateOfLastNotification = [[NSUserDefaults standardUserDefaults] objectForKey:kHITPADPassLastNotifKey]; + if (self.passwordExpiryDate) { + self.menuItem.hidden = NO; + NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay fromDate:[NSDate date] toDate:self.passwordExpiryDate options:0]; + long daysBeforeExpiry = (long)[components day]; + if (daysBeforeExpiry < 0) daysBeforeExpiry = 0; - BOOL notifNeeded = NO; + self.menuItem.title = [NSString stringWithFormat:self.willExpireFormat, daysBeforeExpiry]; - if (dateOfLastNotification) { - NSDateComponents *previousNotifComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitDay fromDate:dateOfLastNotification toDate:self.passwordExpiryDate options:0]; - notifNeeded = [previousNotifComponents day] != daysBeforeExpiry; + if (self.lastADRequestSucceded) { + self.menuItem.target = self; + self.menuItem.toolTip = self.tooltip; } else { - notifNeeded = YES; + self.menuItem.target = nil; + self.menuItem.toolTip = self.offlineTooltip; } - NSDateComponents* components = [[NSCalendar currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute fromDate:[NSDate date]]; - - if (components.hour >= 10 && notifNeeded) { - [self sendUserNotification]; + if (daysBeforeExpiry <= self.alertXDaysBefore) { + NSDate *dateOfLastNotification = [[NSUserDefaults standardUserDefaults] objectForKey:kHITPADPassLastNotifKey]; + + BOOL notifNeeded = NO; + + if (dateOfLastNotification) { + NSDateComponents *previousNotifComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitDay fromDate:dateOfLastNotification toDate:self.passwordExpiryDate options:0]; + notifNeeded = [previousNotifComponents day] != daysBeforeExpiry; + } else { + notifNeeded = YES; + } + + NSDateComponents* components = [[NSCalendar currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute fromDate:[NSDate date]]; + + if (components.hour >= 10 && notifNeeded) { + [self sendUserNotification]; + } } + } else { + asl_log(NULL, NULL, ASL_LEVEL_INFO, "No AD Password expiry date found, hidding menu item."); + self.menuItem.hidden = YES; } } -- (void)getPasswordExpiryDate { - NSError *error = nil; - - ODSession *searchSession = [ODSession sessionWithOptions:nil error:&error]; - - ODNode *searchNode = [ODNode nodeWithSession:searchSession - type:kODNodeTypeAuthentication - error:&error]; - - ODQuery *recordQuery = [ODQuery queryWithNode:searchNode - forRecordTypes:kODRecordTypeUsers - attribute:kODAttributeTypeRecordName - matchType:kODMatchEqualTo - queryValues:NSUserName() - returnAttributes:kHITPADPassExpiryTimeField - maximumResults:0 - error:&error]; - - NSArray *records = [recordQuery resultsAllowingPartial:NO error:&error]; - NSNumber *expiryTime = nil; - for (ODRecord *record in records) { - NSArray *values = [record valuesForAttribute:kHITPADPassExpiryTimeField error:&error]; - expiryTime = [values lastObject]; +- (void)backgroundFetchPasswordExpiryDate { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0) , ^{ + NSError *error = nil; - if (expiryTime) { - break; - } - } - - // Thank you Microsoft to use Jan 1, 1601 at 00:00 UTC as reference date… - if (expiryTime) { - asl_log(NULL, NULL, ASL_LEVEL_INFO, "AD Password expiry date requested with success."); + ODSession *searchSession = [ODSession sessionWithOptions:nil error:&error]; - if ([expiryTime integerValue] == 0x7FFFFFFFFFFFFFFF) { - asl_log(NULL, NULL, ASL_LEVEL_INFO, "AD Password expiry date is mean no expiry."); - self.passwordExpiryDate = nil; - self.lastADRequestSucceded = YES; - [[NSUserDefaults standardUserDefaults] setInteger:-1 forKey:kHITPADPassExpiryTimeKey]; - } else { - asl_log(NULL, NULL, ASL_LEVEL_INFO, "AD Password expiry date is a valid date."); - - NSDateComponents *adRefenreceDateComponents = [[NSDateComponents alloc] init]; - [adRefenreceDateComponents setDay:1]; - [adRefenreceDateComponents setMonth:1]; - [adRefenreceDateComponents setYear:1601]; - [adRefenreceDateComponents setEra:1]; - - NSDate *adRefenreceDate = [[NSCalendar calendarWithIdentifier:NSCalendarIdentifierISO8601] dateFromComponents:adRefenreceDateComponents]; - NSTimeInterval expiryTimeInterval = [expiryTime integerValue] / 10000000.0; - - - self.passwordExpiryDate = [NSDate dateWithTimeInterval:expiryTimeInterval sinceDate:adRefenreceDate]; - self.lastADRequestSucceded = YES; + ODNode *searchNode = [ODNode nodeWithSession:searchSession + type:kODNodeTypeAuthentication + error:&error]; + + ODQuery *recordQuery = [ODQuery queryWithNode:searchNode + forRecordTypes:kODRecordTypeUsers + attribute:kODAttributeTypeRecordName + matchType:kODMatchEqualTo + queryValues:NSUserName() + returnAttributes:kHITPADPassExpiryTimeField + maximumResults:0 + error:&error]; + + NSArray *records = [recordQuery resultsAllowingPartial:NO error:&error]; + NSNumber *expiryTime = nil; + for (ODRecord *record in records) { + NSArray *values = [record valuesForAttribute:kHITPADPassExpiryTimeField error:&error]; + expiryTime = [values lastObject]; - [[NSUserDefaults standardUserDefaults] setInteger:[self.passwordExpiryDate timeIntervalSince1970] forKey:kHITPADPassExpiryTimeKey]; + if (expiryTime) { + break; + } } - } else { - asl_log(NULL, NULL, ASL_LEVEL_INFO, "Unable to reach AD, working with old expiry date for AD Password."); - NSInteger expirySince1970 = [[NSUserDefaults standardUserDefaults] integerForKey:kHITPADPassExpiryTimeKey]; - if (expirySince1970 == -1) { - self.passwordExpiryDate = nil; + + // Thank you Microsoft to use Jan 1, 1601 at 00:00 UTC as reference date… + if (expiryTime) { + asl_log(NULL, NULL, ASL_LEVEL_INFO, "AD Password expiry date requested with success."); + + if ([expiryTime integerValue] == 0x7FFFFFFFFFFFFFFF) { + asl_log(NULL, NULL, ASL_LEVEL_INFO, "AD Password expiry date is mean no expiry."); + self.passwordExpiryDate = nil; + self.lastADRequestSucceded = YES; + [[NSUserDefaults standardUserDefaults] setInteger:-1 forKey:kHITPADPassExpiryTimeKey]; + } else { + asl_log(NULL, NULL, ASL_LEVEL_INFO, "AD Password expiry date is a valid date."); + + NSDateComponents *adRefenreceDateComponents = [[NSDateComponents alloc] init]; + [adRefenreceDateComponents setDay:1]; + [adRefenreceDateComponents setMonth:1]; + [adRefenreceDateComponents setYear:1601]; + [adRefenreceDateComponents setEra:1]; + + NSDate *adRefenreceDate = [[NSCalendar calendarWithIdentifier:NSCalendarIdentifierISO8601] dateFromComponents:adRefenreceDateComponents]; + NSTimeInterval expiryTimeInterval = [expiryTime integerValue] / 10000000.0; + + + self.passwordExpiryDate = [NSDate dateWithTimeInterval:expiryTimeInterval sinceDate:adRefenreceDate]; + self.lastADRequestSucceded = YES; + + [[NSUserDefaults standardUserDefaults] setInteger:[self.passwordExpiryDate timeIntervalSince1970] forKey:kHITPADPassExpiryTimeKey]; + } } else { - self.passwordExpiryDate = expirySince1970 > 0 ? [NSDate dateWithTimeIntervalSince1970:expirySince1970] : nil; + asl_log(NULL, NULL, ASL_LEVEL_INFO, "Unable to reach AD, working with old expiry date for AD Password."); + NSInteger expirySince1970 = [[NSUserDefaults standardUserDefaults] integerForKey:kHITPADPassExpiryTimeKey]; + if (expirySince1970 == -1) { + self.passwordExpiryDate = nil; + } else { + self.passwordExpiryDate = expirySince1970 > 0 ? [NSDate dateWithTimeIntervalSince1970:expirySince1970] : nil; + } + self.lastADRequestSucceded = NO; } - self.lastADRequestSucceded = NO; - - } + dispatch_async(dispatch_get_main_queue() , ^{ + [self updateTitle]; + }); + }); } - (void)sendUserNotification { diff --git a/src/Plugins/ADPass/ADPass/Info.plist b/src/Plugins/ADPass/ADPass/Info.plist index 57469a3..e73a0ed 100644 --- a/src/Plugins/ADPass/ADPass/Info.plist +++ b/src/Plugins/ADPass/ADPass/Info.plist @@ -17,12 +17,12 @@ CFBundleShortVersionString 1.0 CFBundleVersion - 1 + 367 + HITPFunctionIdentifier + public.ad.pass NSHumanReadableCopyright Copyright © 2017 Yoann Gini (Open Source Project). All rights reserved. NSPrincipalClass HITPADPass - HITPFunctionIdentifier - public.ad.pass diff --git a/src/Plugins/CachetHQ/CachetHQ.xcodeproj/project.pbxproj b/src/Plugins/CachetHQ/CachetHQ.xcodeproj/project.pbxproj index a8ecfb4..09dbc0a 100644 --- a/src/Plugins/CachetHQ/CachetHQ.xcodeproj/project.pbxproj +++ b/src/Plugins/CachetHQ/CachetHQ.xcodeproj/project.pbxproj @@ -99,6 +99,7 @@ isa = PBXNativeTarget; buildConfigurationList = F811AD342149A07E00BD15AD /* Build configuration list for PBXNativeTarget "CachetHQIncidents" */; buildPhases = ( + F89A035A2368A5E00059281B /* GitVersion */, F811AD2B2149A07E00BD15AD /* Sources */, F811AD2C2149A07E00BD15AD /* Frameworks */, F811AD2D2149A07E00BD15AD /* Resources */, @@ -182,6 +183,27 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + F89A035A2368A5E00059281B /* GitVersion */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = GitVersion; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "set -o errexit\nset -o nounset\n\nVERSION=$(git rev-list HEAD | wc -l)\n\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $VERSION\" \"${INFOPLIST_FILE}\"\n"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ F811AD2B2149A07E00BD15AD /* Sources */ = { isa = PBXSourcesBuildPhase; diff --git a/src/Plugins/Command/Command.xcodeproj/project.pbxproj b/src/Plugins/Command/Command.xcodeproj/project.pbxproj new file mode 100644 index 0000000..112a85c --- /dev/null +++ b/src/Plugins/Command/Command.xcodeproj/project.pbxproj @@ -0,0 +1,330 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + F89A03562368A53C0059281B /* HITDevKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F89A03552368A53C0059281B /* HITDevKit.framework */; }; + F89A035E2368A69D0059281B /* HITPCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = F89A035D2368A69D0059281B /* HITPCommand.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + F89A03432368A51C0059281B /* Command.hitp */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Command.hitp; sourceTree = BUILT_PRODUCTS_DIR; }; + F89A03462368A51C0059281B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F89A03552368A53C0059281B /* HITDevKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = HITDevKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F89A035C2368A69D0059281B /* HITPCommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HITPCommand.h; sourceTree = ""; }; + F89A035D2368A69D0059281B /* HITPCommand.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HITPCommand.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + F89A03402368A51C0059281B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F89A03562368A53C0059281B /* HITDevKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + F89A033A2368A51C0059281B = { + isa = PBXGroup; + children = ( + F89A03452368A51C0059281B /* Command */, + F89A03442368A51C0059281B /* Products */, + F89A03542368A53C0059281B /* Frameworks */, + ); + sourceTree = ""; + }; + F89A03442368A51C0059281B /* Products */ = { + isa = PBXGroup; + children = ( + F89A03432368A51C0059281B /* Command.hitp */, + ); + name = Products; + sourceTree = ""; + }; + F89A03452368A51C0059281B /* Command */ = { + isa = PBXGroup; + children = ( + F89A03462368A51C0059281B /* Info.plist */, + F89A035C2368A69D0059281B /* HITPCommand.h */, + F89A035D2368A69D0059281B /* HITPCommand.m */, + ); + path = Command; + sourceTree = ""; + }; + F89A03542368A53C0059281B /* Frameworks */ = { + isa = PBXGroup; + children = ( + F89A03552368A53C0059281B /* HITDevKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + F89A03422368A51C0059281B /* Command */ = { + isa = PBXNativeTarget; + buildConfigurationList = F89A03492368A51C0059281B /* Build configuration list for PBXNativeTarget "Command" */; + buildPhases = ( + F89A035B2368A5EF0059281B /* GitVersion */, + F89A033F2368A51C0059281B /* Sources */, + F89A03402368A51C0059281B /* Frameworks */, + F89A03412368A51C0059281B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Command; + productName = Command; + productReference = F89A03432368A51C0059281B /* Command.hitp */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + F89A033B2368A51C0059281B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Yoann Gini (Open Source Project)"; + TargetAttributes = { + F89A03422368A51C0059281B = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = F89A033E2368A51C0059281B /* Build configuration list for PBXProject "Command" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = F89A033A2368A51C0059281B; + productRefGroup = F89A03442368A51C0059281B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + F89A03422368A51C0059281B /* Command */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + F89A03412368A51C0059281B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + F89A035B2368A5EF0059281B /* GitVersion */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = GitVersion; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "set -o errexit\nset -o nounset\n\nVERSION=$(git rev-list HEAD | wc -l)\n\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $VERSION\" \"${INFOPLIST_FILE}\"\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + F89A033F2368A51C0059281B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F89A035E2368A69D0059281B /* HITPCommand.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + F89A03472368A51C0059281B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + F89A03482368A51C0059281B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + }; + name = Release; + }; + F89A034A2368A51C0059281B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = CRXPBZF3N4; + INFOPLIST_FILE = Command/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; + MACOSX_DEPLOYMENT_TARGET = 10.10; + PRODUCT_BUNDLE_IDENTIFIER = com.github.ygini.hitp.Command; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + WRAPPER_EXTENSION = hitp; + }; + name = Debug; + }; + F89A034B2368A51C0059281B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = CRXPBZF3N4; + INFOPLIST_FILE = Command/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; + MACOSX_DEPLOYMENT_TARGET = 10.10; + PRODUCT_BUNDLE_IDENTIFIER = com.github.ygini.hitp.Command; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + WRAPPER_EXTENSION = hitp; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + F89A033E2368A51C0059281B /* Build configuration list for PBXProject "Command" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F89A03472368A51C0059281B /* Debug */, + F89A03482368A51C0059281B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F89A03492368A51C0059281B /* Build configuration list for PBXNativeTarget "Command" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F89A034A2368A51C0059281B /* Debug */, + F89A034B2368A51C0059281B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = F89A033B2368A51C0059281B /* Project object */; +} diff --git a/src/Plugins/Command/Command/HITPCommand.h b/src/Plugins/Command/Command/HITPCommand.h new file mode 100644 index 0000000..86d4075 --- /dev/null +++ b/src/Plugins/Command/Command/HITPCommand.h @@ -0,0 +1,17 @@ +// +// HITPCommand.h +// Command +// +// Created by Yoann Gini on 29/10/2019. +// Copyright © 2019 Yoann Gini (Open Source Project). All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface HITPCommand : HITSimplePlugin + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/Plugins/Command/Command/HITPCommand.m b/src/Plugins/Command/Command/HITPCommand.m new file mode 100644 index 0000000..5f20700 --- /dev/null +++ b/src/Plugins/Command/Command/HITPCommand.m @@ -0,0 +1,84 @@ +// +// HITPCommand.m +// Command +// +// Created by Yoann Gini on 29/10/2019. +// Copyright © 2019 Yoann Gini (Open Source Project). All rights reserved. +// + +#import "HITPCommand.h" + +#import + + +@interface HITPCommand () +@property BOOL scriptChecked; +@property NSArray *programArguments; +@end + +#define kHITPProgramArguments @"programArguments" +#define kHITPDenyUserWritableScript @"denyUserWritableScript" + +@implementation HITPCommand + +- (instancetype)initWithSettings:(NSDictionary*)settings +{ + self = [super initWithSettings:settings]; + if (self) { + _programArguments = [settings objectForKey:kHITPProgramArguments]; + + asl_log(NULL, NULL, ASL_LEVEL_INFO, "Loading command plugin with program arguments %s", [[_programArguments description] cStringUsingEncoding:NSUTF8StringEncoding]); + + if ([_programArguments count] > 0) { + NSString * command = [_programArguments firstObject]; + if ([[NSFileManager defaultManager] fileExistsAtPath:command]) { + if ([[NSFileManager defaultManager] isWritableFileAtPath:command] && [[NSUserDefaults standardUserDefaults] boolForKey:kHITPDenyUserWritableScript]) { +#ifdef DEBUG + _scriptChecked = YES; +#else + _scriptChecked = NO; +#endif + asl_log(NULL, NULL, ASL_LEVEL_ERR, "Target command is writable, security restriction deny such a scenario %s", [command cStringUsingEncoding:NSUTF8StringEncoding]); + } else { + _scriptChecked = YES; + } + } else { + _scriptChecked = NO; + asl_log(NULL, NULL, ASL_LEVEL_ERR, "Target command not accessible %s", [command cStringUsingEncoding:NSUTF8StringEncoding]); + } + } else { + _scriptChecked = NO; + asl_log(NULL, NULL, ASL_LEVEL_ERR, "No valid value for %s", [kHITPProgramArguments cStringUsingEncoding:NSUTF8StringEncoding]); + } + } + return self; +} + +-(void)mainAction:(id)sender { + if (self.scriptChecked && self.allowedToRun) { + NSMutableArray *arguments = [self.programArguments mutableCopy]; + [arguments removeObjectAtIndex:0]; + + NSString *command = [self.programArguments firstObject]; + + asl_log(NULL, NULL, ASL_LEVEL_INFO, "Will run command %s", [command cStringUsingEncoding:NSUTF8StringEncoding]); + + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + NSTask *task = [[NSTask alloc] init]; + [task setLaunchPath:command]; + [task setArguments:arguments]; + + @try { + [task launch]; + [task waitUntilExit]; + asl_log(NULL, NULL, ASL_LEVEL_INFO, "Command exited with code %i", [task terminationStatus]); + } @catch (NSException *exception) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, "Command failed to run: %s", [[exception reason] UTF8String]); + } + }]; + } + +} + + +@end diff --git a/src/Plugins/Command/Command/Info.plist b/src/Plugins/Command/Command/Info.plist new file mode 100644 index 0000000..6d5bdac --- /dev/null +++ b/src/Plugins/Command/Command/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 367 + HITPFunctionIdentifier + public.command + NSHumanReadableCopyright + Copyright © 2019 Yoann Gini (Open Source Project). All rights reserved. + NSPrincipalClass + HITPCommand + + diff --git a/src/Plugins/OpenApplication/OpenApplication/Info.plist b/src/Plugins/OpenApplication/OpenApplication/Info.plist index f49b3a1..b6ab794 100644 --- a/src/Plugins/OpenApplication/OpenApplication/Info.plist +++ b/src/Plugins/OpenApplication/OpenApplication/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 351 + 367 HITPFunctionIdentifier public.open.application NSHumanReadableCopyright diff --git a/src/Plugins/OpenResource/OpenResource.xcodeproj/project.pbxproj b/src/Plugins/OpenResource/OpenResource.xcodeproj/project.pbxproj index d93ca70..0ffa367 100644 --- a/src/Plugins/OpenResource/OpenResource.xcodeproj/project.pbxproj +++ b/src/Plugins/OpenResource/OpenResource.xcodeproj/project.pbxproj @@ -144,7 +144,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -o errexit\nset -o nounset\n\nVERSION=$(git rev-list HEAD | wc -l)\n\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $VERSION\" \"${INFOPLIST_FILE}\""; + shellScript = "set -o errexit\nset -o nounset\n\nVERSION=$(git rev-list HEAD | wc -l)\n\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $VERSION\" \"${INFOPLIST_FILE}\"\n"; }; /* End PBXShellScriptBuildPhase section */ diff --git a/src/Plugins/OpenResource/OpenResource/Info.plist b/src/Plugins/OpenResource/OpenResource/Info.plist index 34eacc7..668a093 100644 --- a/src/Plugins/OpenResource/OpenResource/Info.plist +++ b/src/Plugins/OpenResource/OpenResource/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 351 + 367 HITPFunctionIdentifier public.open.resource NSHumanReadableCopyright diff --git a/src/Plugins/Quit/Quit/Info.plist b/src/Plugins/Quit/Quit/Info.plist index 906821a..0b2eba9 100644 --- a/src/Plugins/Quit/Quit/Info.plist +++ b/src/Plugins/Quit/Quit/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 351 + 367 HITPFunctionIdentifier public.quit NSHumanReadableCopyright diff --git a/src/Plugins/ScriptedItem/ScriptedItem/HITPScriptedItem.m b/src/Plugins/ScriptedItem/ScriptedItem/HITPScriptedItem.m index 604a0de..1056d8b 100644 --- a/src/Plugins/ScriptedItem/ScriptedItem/HITPScriptedItem.m +++ b/src/Plugins/ScriptedItem/ScriptedItem/HITPScriptedItem.m @@ -258,6 +258,15 @@ - (void)handleScriptRequest:(NSString*)request { self.menuItem.hidden = NO; } + } else if ([key isEqualToString:@"hitp-open"]) { + NSURL * valueURL = [NSURL URLWithString:value]; + + if (valueURL) { + [[NSWorkspace sharedWorkspace] openURL:valueURL]; + } else { + asl_log(NULL, NULL, ASL_LEVEL_INFO, "Unable to decode this as an URL conforms to RFCs 2396, 1738 and 1808.: %s", [value cStringUsingEncoding:NSUTF8StringEncoding]); + } + } else if ([key isEqualToString:@"hitp-notification"]) { [self sendNotificationWithMessage:value]; diff --git a/src/Plugins/ScriptedItem/ScriptedItem/Info.plist b/src/Plugins/ScriptedItem/ScriptedItem/Info.plist index 49d2ac4..9f7acd9 100644 --- a/src/Plugins/ScriptedItem/ScriptedItem/Info.plist +++ b/src/Plugins/ScriptedItem/ScriptedItem/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 351 + 367 HITPFunctionIdentifier public.script.item NSHumanReadableCopyright diff --git a/src/Plugins/Separator/Separator/Info.plist b/src/Plugins/Separator/Separator/Info.plist index 63d18e4..243d9de 100644 --- a/src/Plugins/Separator/Separator/Info.plist +++ b/src/Plugins/Separator/Separator/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 351 + 367 HITPFunctionIdentifier public.separator NSHumanReadableCopyright diff --git a/src/Plugins/SubMenu/SubMenu/Info.plist b/src/Plugins/SubMenu/SubMenu/Info.plist index 1ae4b7f..6bd8d68 100644 --- a/src/Plugins/SubMenu/SubMenu/Info.plist +++ b/src/Plugins/SubMenu/SubMenu/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 351 + 367 HITPFunctionIdentifier public.submenu NSHumanReadableCopyright diff --git a/src/Plugins/TestHTTP/TestHTTP/Info.plist b/src/Plugins/TestHTTP/TestHTTP/Info.plist index e07f3b9..9006f93 100644 --- a/src/Plugins/TestHTTP/TestHTTP/Info.plist +++ b/src/Plugins/TestHTTP/TestHTTP/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 351 + 367 HITPFunctionIdentifier public.test.http NSHumanReadableCopyright diff --git a/src/Plugins/Title/Title/Info.plist b/src/Plugins/Title/Title/Info.plist index db11805..1fa8b95 100644 --- a/src/Plugins/Title/Title/Info.plist +++ b/src/Plugins/Title/Title/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 351 + 367 HITPFunctionIdentifier public.title NSHumanReadableCopyright