mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-22 17:39:24 +00:00
Merge branch 'master' into feature/import_plugins
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -24,3 +24,4 @@ Docs/Acknowlegements/*.fls
|
||||
Docs/Acknowlegements/*.log
|
||||
Docs/Acknowlegements/*.synctex.gz
|
||||
docs/acknowledgement/*.lb
|
||||
MacPass/en.lproj/Localizable.strings.updated
|
||||
|
||||
@@ -206,6 +206,7 @@
|
||||
4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */; };
|
||||
4C8DEAA21C314D2C00D24C32 /* MPTestAutotypeDelay.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */; };
|
||||
4C8E889222C223620002C7C8 /* createdTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C8E889122C223620002C7C8 /* createdTemplate.pdf */; };
|
||||
4C8E889422C227270002C7C8 /* plugins.json in Resources */ = {isa = PBXBuildFile; fileRef = 4C8E889322C227270002C7C8 /* plugins.json */; };
|
||||
4C8F0C6E1FCEE9B900BE157F /* MPPluginConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8F0C6D1FCEE9B900BE157F /* MPPluginConstants.m */; };
|
||||
4C8F0C711FCEF91400BE157F /* MPPickcharsParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8F0C701FCEF91400BE157F /* MPPickcharsParser.m */; };
|
||||
4C8F0C731FCF1B7A00BE157F /* MPTestPickcharsParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8F0C721FCF1B7A00BE157F /* MPTestPickcharsParser.m */; };
|
||||
@@ -734,6 +735,7 @@
|
||||
4C8C10061FC489D8003DDD5E /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/PluginPreferences.strings; sourceTree = "<group>"; };
|
||||
4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTestAutotypeDelay.m; sourceTree = "<group>"; };
|
||||
4C8E889122C223620002C7C8 /* createdTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = createdTemplate.pdf; sourceTree = "<group>"; };
|
||||
4C8E889322C227270002C7C8 /* plugins.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = plugins.json; path = Resources/plugins.json; sourceTree = "<group>"; };
|
||||
4C8F0C6C1FCEE98900BE157F /* MPPluginConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPPluginConstants.h; sourceTree = "<group>"; };
|
||||
4C8F0C6D1FCEE9B900BE157F /* MPPluginConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPPluginConstants.m; sourceTree = "<group>"; };
|
||||
4C8F0C6F1FCEF91400BE157F /* MPPickcharsParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPPickcharsParser.h; sourceTree = "<group>"; };
|
||||
@@ -1504,6 +1506,7 @@
|
||||
4C77E36D15B84A240093A587 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4C8E889322C227270002C7C8 /* plugins.json */,
|
||||
FA13910A1F9CD9EB0033D256 /* Localizable.stringsdict */,
|
||||
4C888C8E16EB6C91003D34A1 /* Localizable.strings */,
|
||||
4CB9339716D3A0DD00A13B5D /* Credits.rtf */,
|
||||
@@ -1949,6 +1952,7 @@
|
||||
6021FE4B18E13F1D00C3BC51 /* GroupInspectorView.xib in Resources */,
|
||||
4C3826BF1AD04D8E007D7D67 /* 52_EncryptedTemplate.pdf in Resources */,
|
||||
4C3826BD1AD04D8E007D7D67 /* 50_FolderTarTemplate.pdf in Resources */,
|
||||
4C8E889422C227270002C7C8 /* plugins.json in Resources */,
|
||||
6021FE3B18E1341900C3BC51 /* EntryInspectorView.xib in Resources */,
|
||||
4C3826AD1AD04D8E007D7D67 /* 32_FileSystemViewTemplate.pdf in Resources */,
|
||||
6021FE6118E15D9100C3BC51 /* WorkflowPreferences.xib in Resources */,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPPluginPreferencesController">
|
||||
<connections>
|
||||
<outlet property="addRemovePluginsControl" destination="B9Q-hq-K4N" id="Oqj-Ko-8UR"/>
|
||||
<outlet property="allowRemoteConnectionCheckButton" destination="K0z-aD-K2P" id="VDW-fd-evK"/>
|
||||
<outlet property="fallbackDescriptionTextField" destination="qPL-FR-ky7" id="xCb-ED-NIX"/>
|
||||
<outlet property="fallbackSettingsView" destination="wIk-iw-Tcz" id="dHl-zW-0aI"/>
|
||||
<outlet property="forceIncompatiblePluginsCheckButton" destination="XIl-03-JZP" id="Aj4-rc-Ao0"/>
|
||||
@@ -21,19 +22,19 @@
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Hz6-mo-xeY">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="473"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="607" height="502"/>
|
||||
<subviews>
|
||||
<box borderType="line" title="Box" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="vBs-Ga-aq0">
|
||||
<rect key="frame" x="175" y="46" width="408" height="321"/>
|
||||
<rect key="frame" x="175" y="46" width="415" height="306"/>
|
||||
<view key="contentView" id="tD5-Na-7XI">
|
||||
<rect key="frame" x="3" y="3" width="402" height="315"/>
|
||||
<rect key="frame" x="3" y="3" width="409" height="300"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="wIk-iw-Tcz">
|
||||
<rect key="frame" x="20" y="20" width="362" height="275"/>
|
||||
<rect key="frame" x="20" y="20" width="369" height="260"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qPL-FR-ky7">
|
||||
<rect key="frame" x="18" y="238" width="326" height="17"/>
|
||||
<rect key="frame" x="18" y="223" width="333" height="17"/>
|
||||
<textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" title="Plugin Settings Info" id="OOr-SW-jZb">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -58,14 +59,14 @@
|
||||
</view>
|
||||
</box>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="CqP-oK-S8k">
|
||||
<rect key="frame" x="18" y="437" width="159" height="18"/>
|
||||
<rect key="frame" x="18" y="422" width="159" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Load unsecure Plugins" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="C4B-6z-ZqX">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aoG-FD-ds8">
|
||||
<rect key="frame" x="18" y="403" width="564" height="28"/>
|
||||
<rect key="frame" x="18" y="388" width="571" height="28"/>
|
||||
<textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" id="2bX-8S-9XM">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<string key="title">If enabled, Plugins without proper signatures will be allowed to load. Keep in mind, that Plugins have full access to your data! Changes take affect on restart.</string>
|
||||
@@ -74,13 +75,13 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<scrollView autohidesScrollers="YES" horizontalLineScroll="37" horizontalPageScroll="10" verticalLineScroll="37" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fCk-fL-jU8">
|
||||
<rect key="frame" x="20" y="50" width="150" height="315"/>
|
||||
<rect key="frame" x="20" y="50" width="150" height="300"/>
|
||||
<clipView key="contentView" id="lTL-Q2-k45">
|
||||
<rect key="frame" x="1" y="1" width="148" height="313"/>
|
||||
<rect key="frame" x="1" y="1" width="148" height="298"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="35" rowSizeStyle="automatic" viewBased="YES" id="Ocu-C0-03d">
|
||||
<rect key="frame" x="0.0" y="0.0" width="148" height="313"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="148" height="298"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -167,7 +168,7 @@
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SNe-cc-CZs">
|
||||
<rect key="frame" x="406" y="19" width="174" height="23"/>
|
||||
<rect key="frame" x="413" y="19" width="174" height="23"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Browse Available Plugins…" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="sqO-8H-n1y">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -177,30 +178,51 @@
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XIl-03-JZP">
|
||||
<rect key="frame" x="18" y="371" width="250" height="18"/>
|
||||
<rect key="frame" x="18" y="356" width="250" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Force loading of incompatible Plugins" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="yak-fS-jtA">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="K0z-aD-K2P">
|
||||
<rect key="frame" x="18" y="466" width="243" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Download current plugin information" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="uHR-uL-Ddm">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nrf-Hz-0vB">
|
||||
<rect key="frame" x="18" y="446" width="349" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" selectable="YES" title="If enabled, a remote connection is established to macpassapp.org" id="i3S-9b-Bpf">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="CqP-oK-S8k" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" id="1Rj-zS-7t2"/>
|
||||
<constraint firstItem="CqP-oK-S8k" firstAttribute="top" secondItem="nrf-Hz-0vB" secondAttribute="bottom" constant="8" symbolic="YES" id="1Rj-zS-7t2"/>
|
||||
<constraint firstItem="XIl-03-JZP" firstAttribute="top" secondItem="aoG-FD-ds8" secondAttribute="bottom" constant="16" id="2Wk-4D-AHu"/>
|
||||
<constraint firstItem="vBs-Ga-aq0" firstAttribute="top" secondItem="fCk-fL-jU8" secondAttribute="top" id="2h6-C9-4N5"/>
|
||||
<constraint firstItem="nrf-Hz-0vB" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="2hE-FW-30g"/>
|
||||
<constraint firstItem="B9Q-hq-K4N" firstAttribute="top" secondItem="fCk-fL-jU8" secondAttribute="bottom" constant="8" symbolic="YES" id="3vA-Oh-cFO"/>
|
||||
<constraint firstAttribute="bottom" secondItem="B9Q-hq-K4N" secondAttribute="bottom" constant="20" symbolic="YES" id="7HD-ji-Whc"/>
|
||||
<constraint firstAttribute="trailing" secondItem="SNe-cc-CZs" secondAttribute="trailing" constant="20" symbolic="YES" id="8Je-yg-f1l"/>
|
||||
<constraint firstAttribute="trailing" secondItem="aoG-FD-ds8" secondAttribute="trailing" constant="20" symbolic="YES" id="95O-Jh-0KG"/>
|
||||
<constraint firstItem="vBs-Ga-aq0" firstAttribute="bottom" secondItem="fCk-fL-jU8" secondAttribute="bottom" id="BQ2-Wp-Fsh"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="K0z-aD-K2P" secondAttribute="trailing" constant="20" symbolic="YES" id="CFf-LD-G7q"/>
|
||||
<constraint firstAttribute="bottom" secondItem="SNe-cc-CZs" secondAttribute="bottom" constant="20" symbolic="YES" id="Fqe-ch-vsS"/>
|
||||
<constraint firstAttribute="trailing" secondItem="vBs-Ga-aq0" secondAttribute="trailing" constant="20" id="LUb-Un-azV"/>
|
||||
<constraint firstItem="aoG-FD-ds8" firstAttribute="leading" secondItem="CqP-oK-S8k" secondAttribute="leading" id="NcW-ya-DPx"/>
|
||||
<constraint firstItem="B9Q-hq-K4N" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="Rtj-Ad-zkg"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="CqP-oK-S8k" secondAttribute="trailing" constant="20" symbolic="YES" id="TXL-mf-nxu"/>
|
||||
<constraint firstItem="K0z-aD-K2P" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="XzM-3L-OgP"/>
|
||||
<constraint firstItem="SNe-cc-CZs" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="B9Q-hq-K4N" secondAttribute="trailing" constant="8" symbolic="YES" id="a62-en-kDA"/>
|
||||
<constraint firstItem="fCk-fL-jU8" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="fzW-4b-L8S"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="nrf-Hz-0vB" secondAttribute="trailing" constant="20" symbolic="YES" id="hMs-HE-d8h"/>
|
||||
<constraint firstItem="nrf-Hz-0vB" firstAttribute="top" secondItem="K0z-aD-K2P" secondAttribute="bottom" constant="8" symbolic="YES" id="ohE-9y-xO4"/>
|
||||
<constraint firstItem="XIl-03-JZP" firstAttribute="leading" secondItem="CqP-oK-S8k" secondAttribute="leading" id="oqX-wa-jm0"/>
|
||||
<constraint firstItem="K0z-aD-K2P" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="q4N-Jc-F3L"/>
|
||||
<constraint firstItem="SNe-cc-CZs" firstAttribute="top" secondItem="vBs-Ga-aq0" secondAttribute="bottom" constant="8" symbolic="YES" id="r4X-iM-iYU"/>
|
||||
<constraint firstItem="CqP-oK-S8k" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="rN1-3Z-BBi"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="XIl-03-JZP" secondAttribute="trailing" constant="20" symbolic="YES" id="rkN-ew-RtP"/>
|
||||
@@ -208,7 +230,7 @@
|
||||
<constraint firstItem="vBs-Ga-aq0" firstAttribute="leading" secondItem="fCk-fL-jU8" secondAttribute="trailing" constant="8" id="xNu-Sj-xQO"/>
|
||||
<constraint firstItem="aoG-FD-ds8" firstAttribute="top" secondItem="CqP-oK-S8k" secondAttribute="bottom" constant="8" symbolic="YES" id="zSW-h3-BrT"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="110" y="-97"/>
|
||||
<point key="canvasLocation" x="179" y="115"/>
|
||||
</customView>
|
||||
</objects>
|
||||
<resources>
|
||||
|
||||
@@ -464,6 +464,7 @@ NSString *const MPImportPluginUTIKey = @"MPImportPluginUTIKey";
|
||||
- (NSArray<MPPlugin *> *)importPlugins {
|
||||
return [self _pluginsConformingToProtocoll:@protocol(MPImportPlugin)];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPPluginHost (MPWindowTitleResolverSupport)
|
||||
|
||||
@@ -42,6 +42,7 @@ typedef NS_ENUM(NSUInteger, MPPluginSegmentType) {
|
||||
|
||||
@interface MPPluginPreferencesController () <NSTableViewDataSource, NSTableViewDelegate>
|
||||
|
||||
@property (strong) IBOutlet NSButton *allowRemoteConnectionCheckButton;
|
||||
@property (strong) IBOutlet NSTableView *pluginTableView;
|
||||
@property (strong) IBOutlet NSView *settingsView;
|
||||
@property (strong) IBOutlet NSView *fallbackSettingsView;
|
||||
@@ -83,6 +84,10 @@ typedef NS_ENUM(NSUInteger, MPPluginSegmentType) {
|
||||
toObject:NSUserDefaultsController.sharedUserDefaultsController
|
||||
withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyLoadIncompatiblePlugins]
|
||||
options:nil];
|
||||
[self.allowRemoteConnectionCheckButton bind:NSValueBinding
|
||||
toObject:NSUserDefaultsController.sharedUserDefaultsController
|
||||
withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository]
|
||||
options:nil];
|
||||
[self.pluginTableView registerForDraggedTypes:@[(NSString *)kUTTypeFileURL]];
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#import "MPPluginRepository.h"
|
||||
#import "MPConstants.h"
|
||||
#import "MPPluginRepositoryItem.h"
|
||||
#import "MPSettingsHelper.h"
|
||||
|
||||
NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.hicknhack.macpass.MPPluginRepositoryDidInitializeAvailablePluginsNotification";
|
||||
|
||||
@@ -56,7 +57,7 @@ NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.
|
||||
if(self) {
|
||||
_isInitialized = NO;
|
||||
_lastDataFetchTime = NSDate.distantPast.timeIntervalSinceReferenceDate;
|
||||
[self fetchRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
|
||||
[self _fetchAppropriateRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
|
||||
self.availablePlugins = availablePlugins;
|
||||
self.isInitialized = YES;
|
||||
}];
|
||||
@@ -65,10 +66,12 @@ NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.
|
||||
}
|
||||
|
||||
- (NSArray<MPPluginRepositoryItem *> *)availablePlugins {
|
||||
/* update cache on every read if it's older than 5 minutes */
|
||||
/* FIXME: Invalidate fetch when settings have changed!
|
||||
update cache on every read if it's older than 5 minutes
|
||||
*/
|
||||
if((NSDate.timeIntervalSinceReferenceDate - self.lastDataFetchTime) > 60*5 ) {
|
||||
NSLog(@"%@: updating available plugins cache.", self.className);
|
||||
[self fetchRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
|
||||
[self _fetchAppropriateRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
|
||||
self.availablePlugins = availablePlugins;
|
||||
}];
|
||||
}
|
||||
@@ -87,59 +90,99 @@ NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.
|
||||
}
|
||||
}
|
||||
|
||||
- (void)fetchRepositoryDataCompletionHandler:(void (^)(NSArray<MPPluginRepositoryItem *> * _Nonnull))completionHandler {
|
||||
- (void)_fetchAppropriateRepositoryDataCompletionHandler:(void (^)(NSArray<MPPluginRepositoryItem *> * _Nonnull))completionHandler {
|
||||
/* dispatch the call to allow for direct return and handle result later on */
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
BOOL allowRemoteConnection = [self _askForPluginRepositoryPermission];
|
||||
if(!allowRemoteConnection) {
|
||||
[self _fetchLocalFallbackRepositoryData:completionHandler];
|
||||
}
|
||||
else {
|
||||
[self _fetchRepositoryDataCompletionHandler:completionHandler];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)_fetchRepositoryDataCompletionHandler:(void (^)(NSArray<MPPluginRepositoryItem *> * _Nonnull))completionHandler {
|
||||
NSString *urlString = NSBundle.mainBundle.infoDictionary[MPBundlePluginRepositoryURLKey];
|
||||
if(!urlString) {
|
||||
if(completionHandler) {
|
||||
completionHandler(@[]);
|
||||
}
|
||||
[self _fetchLocalFallbackRepositoryData:completionHandler];
|
||||
return;
|
||||
}
|
||||
NSURL *jsonURL = [NSURL URLWithString:urlString];
|
||||
if(!jsonURL) {
|
||||
if(completionHandler) {
|
||||
completionHandler(@[]);
|
||||
}
|
||||
[self _fetchLocalFallbackRepositoryData:completionHandler];
|
||||
return;
|
||||
}
|
||||
|
||||
NSURLSessionTask *downloadTask = [NSURLSession.sharedSession dataTaskWithURL:jsonURL completionHandler:^(NSData * _Nullable jsonData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
|
||||
if(![response isKindOfClass:NSHTTPURLResponse.class]) {
|
||||
if(completionHandler) {
|
||||
completionHandler(@[]);
|
||||
}
|
||||
[self _fetchLocalFallbackRepositoryData:completionHandler];
|
||||
return;
|
||||
}
|
||||
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
|
||||
if(httpResponse.statusCode != 200 || jsonData.length == 0) {
|
||||
if(completionHandler) {
|
||||
completionHandler(@[]);
|
||||
}
|
||||
[self _fetchLocalFallbackRepositoryData:completionHandler];
|
||||
return;
|
||||
}
|
||||
id jsonRoot = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
|
||||
if(!jsonRoot || ![jsonRoot isKindOfClass:NSArray.class]) {
|
||||
if(completionHandler) {
|
||||
completionHandler(@[]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
NSMutableArray *items = [[NSMutableArray alloc] init];
|
||||
for(id item in jsonRoot) {
|
||||
if(![item isKindOfClass:NSDictionary.class]) {
|
||||
continue;
|
||||
}
|
||||
MPPluginRepositoryItem *pluginItem = [MPPluginRepositoryItem pluginItemFromDictionary:item];
|
||||
if(pluginItem.isVaid) {
|
||||
[items addObject:pluginItem];
|
||||
}
|
||||
}
|
||||
|
||||
NSArray *items = [self _parseJSONData:jsonData];
|
||||
|
||||
if(completionHandler) {
|
||||
completionHandler([items copy]);
|
||||
}
|
||||
}];
|
||||
|
||||
[downloadTask resume];
|
||||
}
|
||||
|
||||
- (void)_fetchLocalFallbackRepositoryData:(void (^)(NSArray<MPPluginRepositoryItem *> * _Nonnull))completionHandler {
|
||||
NSURL *jsonURL = [NSBundle.mainBundle URLForResource:@"plugins" withExtension:@"json"];
|
||||
NSData *localJsonData = [NSData dataWithContentsOfURL:jsonURL];
|
||||
if(!localJsonData) {
|
||||
if(completionHandler) {
|
||||
completionHandler(@[]);
|
||||
}
|
||||
}
|
||||
NSArray<MPPluginRepositoryItem *> *items = [self _parseJSONData:localJsonData];
|
||||
if(completionHandler) {
|
||||
completionHandler(items);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray<MPPluginRepositoryItem *> *)_parseJSONData:(NSData *)jsonData {
|
||||
NSError *error;
|
||||
id jsonRoot = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
|
||||
if(!jsonRoot || ![jsonRoot isKindOfClass:NSArray.class]) {
|
||||
return @[];
|
||||
}
|
||||
NSMutableArray *items = [[NSMutableArray alloc] init];
|
||||
for(id item in jsonRoot) {
|
||||
if(![item isKindOfClass:NSDictionary.class]) {
|
||||
continue;
|
||||
}
|
||||
MPPluginRepositoryItem *pluginItem = [MPPluginRepositoryItem pluginItemFromDictionary:item];
|
||||
if(pluginItem.isVaid) {
|
||||
[items addObject:pluginItem];
|
||||
}
|
||||
}
|
||||
return [items copy];
|
||||
}
|
||||
|
||||
- (BOOL)_askForPluginRepositoryPermission {
|
||||
if(![NSUserDefaults.standardUserDefaults objectForKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository]) {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
alert.alertStyle = NSAlertStyleWarning;
|
||||
alert.informativeText = NSLocalizedString(@"ALERT_ASK_FOR_PLUGIN_REPOSITORY_CONNECTION_PERMISSION_INFORMATIVE_TEXT", @"Informative text displayed on the alert that shows up when MacPass asks for permssion to download the plugin repository JSON file");
|
||||
alert.messageText = NSLocalizedString(@"ALERT_ASK_FOR_PLUGIN_REPOSITORY_CONNECTION_PERMISSION_MESSAGE", @"Message displayed on the alert that askf for permission to download the plugin repository JSON file");
|
||||
alert.showsSuppressionButton = YES;
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"ALERT_ASK_FOR_PLUGIN_REPOSITORY_DISALLOW_DOWNLOAD", @"Disallow the download of the plugin repository file")];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"ALERT_ASK_FOR_PLUGIN_REPOSITORY_ALLOW_DOWNLOAD", @"Allow the download of the plugin repository file")];
|
||||
NSModalResponse repsonse = [alert runModal];
|
||||
BOOL allow = (repsonse == NSAlertFirstButtonReturn);
|
||||
[NSUserDefaults.standardUserDefaults setBool:allow forKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository];
|
||||
return allow;
|
||||
}
|
||||
return [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -87,6 +87,8 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyLoadUnsecurePlugins; // I
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyDisabledPlugins; // NSArray of bundle identifiers of disabled plugins
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyLoadIncompatiblePlugins; // If set to YES incompatible plugins (no version info, marked as incompatible, etc) will be loaded regardless
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyHideIncopatiblePluginsWarning; // Do not show an alert, when MacPass encounteres incompatible plugins
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyAllowRemoteFetchOfPluginRepository; // Allow the download of the plugin repository file
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyPluginHideAksForRemoveConnectionPermission;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MPFileChangeStrategy) {
|
||||
MPFileChangeStrategyAsk,
|
||||
|
||||
@@ -84,6 +84,7 @@ NSString *const kMPSettingsKeyLoadUnsecurePlugins = @"LoadUn
|
||||
NSString *const kMPSettingsKeyLoadIncompatiblePlugins = @"LoadIncompatiblePlugins";
|
||||
NSString *const kMPSettingsKeyDisabledPlugins = @"DisabledPlugins";
|
||||
NSString *const kMPSettingsKeyHideIncopatiblePluginsWarning = @"HideIncopatiblePluginsWarning";
|
||||
NSString *const kMPSettingsKeyAllowRemoteFetchOfPluginRepository = @"AllowRemoteFetchOfPluginRepository";
|
||||
|
||||
/* Deprecated */
|
||||
NSString *const kMPDeprecatedSettingsKeyRememberKeyFilesForDatabases = @"kMPSettingsKeyRememberKeyFilesForDatabases";
|
||||
|
||||
26
MacPass/Resources/plugins.json
Normal file
26
MacPass/Resources/plugins.json
Normal file
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"name": "MacPassHTTP",
|
||||
"description": "KeePassHTTP support for MacPass",
|
||||
"download": "https://github.com/MacPass/MacPassHTTP/releases/download/0.3.1/MacPassHTTP.mpplugin-0.3.1.zip",
|
||||
"source": "https://github.com/MacPass/MacPassHTTP",
|
||||
"currentVersion": "0.3.1",
|
||||
"bundleIdentifier": "com.hicknhacksoftware.MacPassHTTP",
|
||||
"compatibilty" : [
|
||||
{
|
||||
"pluginVersion": "0.2.*",
|
||||
"minimumHostVersion" : "0.6.1",
|
||||
"maximumHostVersion" : "0.6.2"
|
||||
},
|
||||
{
|
||||
"pluginVersion": "0.3",
|
||||
"minimumHostVersion" : "0.7",
|
||||
"maximumHostVersion" : "0.7.3"
|
||||
},
|
||||
{
|
||||
"pluginVersion": "0.3.1",
|
||||
"minimumHostVersion" : "0.7.4"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -37,6 +37,30 @@
|
||||
/* Action to add an entry via template */
|
||||
"ADD_TREMPLATE_ENTRY" = "Vorgabeeintrag erstellen";
|
||||
|
||||
/* Allow the download of the plugin repository file */
|
||||
"ALERT_ASK_FOR_PLUGIN_REPOSITORY_ALLOW_DOWNLOAD" = "Keine Daten herunterladen.";
|
||||
|
||||
/* Informative text displayed on the alert that shows up when MacPass asks for permssion to download the plugin repository JSON file */
|
||||
"ALERT_ASK_FOR_PLUGIN_REPOSITORY_CONNECTION_PERMISSION_INFORMATIVE_TEXT" = "Das Verzeichnis ist auf https://macpassapp.org hinterlegt. MacPass verbindet lädt die Defintionen herunter um sicher zu stellen, dass alle Daten auf dem neusten Stand sind.";
|
||||
|
||||
/* Message displayed on the alert that askf for permission to download the plugin repository JSON file */
|
||||
"ALERT_ASK_FOR_PLUGIN_REPOSITORY_CONNECTION_PERMISSION_MESSAGE" = "MacPass möchte das Pluginverzeichnis aktualisieren.";
|
||||
|
||||
/* Disallow the download of the plugin repository file */
|
||||
"ALERT_ASK_FOR_PLUGIN_REPOSITORY_DISALLOW_DOWNLOAD" = "Aktualisiere Daten online.";
|
||||
|
||||
/* Button in dialog to leave autotype disabled and continiue! */
|
||||
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_BUTTON_OK" = "Autotype deaktiviert lassen.";
|
||||
|
||||
/* Button in dialog to open accessibilty preferences pane! */
|
||||
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_BUTTON_OPEN_PREFERENCES" = "Systemeinstellung Bedienungshilfen öffnen …";
|
||||
|
||||
/* Alert informative text displayed when Autotype performs self check and lacks accessibilty permissions */
|
||||
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_INFORMATIVE_TEXT" = "Das System erlaubt MacPass nicht, Autotype-Tastenbefehle an andere Anwendungen zu schicken. Um Autotype zu ermöglichen fügen Sie MacPass zu den Bedienungshilfen in den Datenschutzeinstellung hinzu. ";
|
||||
|
||||
/* Alert message displayed when Autotype performs self check and lacks accessibilty permissions */
|
||||
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_MESSAGE_TEXT" = "MacPass kann Autotype nicht ausführen.";
|
||||
|
||||
/* Button in dialog to leave plugin ds disabled and continiue! */
|
||||
"ALERT_INCOMPATIBLE_PLUGINS_ENCOUNTERED_BUTTON_OK" = "OK";
|
||||
|
||||
|
||||
@@ -37,6 +37,30 @@
|
||||
/* Action to add an entry via template */
|
||||
"ADD_TREMPLATE_ENTRY" = "Create Template Entry";
|
||||
|
||||
/* Allow the download of the plugin repository file */
|
||||
"ALERT_ASK_FOR_PLUGIN_REPOSITORY_ALLOW_DOWNLOAD" = "Do not update defintions";
|
||||
|
||||
/* Informative text displayed on the alert that shows up when MacPass asks for permssion to download the plugin repository JSON file */
|
||||
"ALERT_ASK_FOR_PLUGIN_REPOSITORY_CONNECTION_PERMISSION_INFORMATIVE_TEXT" = "The plugin defintions are hosted online at https://macpassapp.org. MacPass would like to download those files to ensure the data is up to date.";
|
||||
|
||||
/* Message displayed on the alert that askf for permission to download the plugin repository JSON file */
|
||||
"ALERT_ASK_FOR_PLUGIN_REPOSITORY_CONNECTION_PERMISSION_MESSAGE" = "MacPass would like to check for updates of plugin defintions online";
|
||||
|
||||
/* Disallow the download of the plugin repository file */
|
||||
"ALERT_ASK_FOR_PLUGIN_REPOSITORY_DISALLOW_DOWNLOAD" = "Update definitions online";
|
||||
|
||||
/* Button in dialog to leave autotype disabled and continiue! */
|
||||
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_BUTTON_OK" = "Keep Autotype disabled.";
|
||||
|
||||
/* Button in dialog to open accessibilty preferences pane! */
|
||||
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_BUTTON_OPEN_PREFERENCES" = "Open Accessibilty Preferences…";
|
||||
|
||||
/* Alert informative text displayed when Autotype performs self check and lacks accessibilty permissions */
|
||||
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_INFORMATIVE_TEXT" = "The system prevents MacPass from sending key strokes to other Applications. To enable Autotype please grant MacPass Accessibilty rights in the privacy preferences.";
|
||||
|
||||
/* Alert message displayed when Autotype performs self check and lacks accessibilty permissions */
|
||||
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_MESSAGE_TEXT" = "MacPass cannot perform Autotype";
|
||||
|
||||
/* Button in dialog to leave plugin ds disabled and continiue! */
|
||||
"ALERT_INCOMPATIBLE_PLUGINS_ENCOUNTERED_BUTTON_OK" = "OK";
|
||||
|
||||
|
||||
6
scripts/update_plugin_repository.sh
Executable file
6
scripts/update_plugin_repository.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
URL="https://macpassapp.org/data/plugins.json"
|
||||
MY_FOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
DOWNLOAD_FOLDER="${MY_FOLDER}/../MacPass/Resources/"
|
||||
cd "${DOWNLOAD_FOLDER}"
|
||||
wget "${URL}"
|
||||
Reference in New Issue
Block a user