Skip to content

Commit 8592988

Browse files
committed
Merge branch 'feature-macOS-pkg'; v11.1.1
2 parents 676e342 + 074eecd commit 8592988

File tree

5 files changed

+82
-27
lines changed

5 files changed

+82
-27
lines changed

GNUmakefile

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,24 @@ APPLEID ?= [email protected]
1010
TEAMID ?= ZD8TVTCXDS
1111
# The unique App ID assigned by App Store Connect, under App Information (NOT your Apple ID!!)
1212
APPID ?= 1608360813
13-
#DEVID ?= 3rd Party Mac Developer Application: Perry Kundert ($(TEAMID))
1413
#DEVID ?= Developer ID Application: Perry Kundert ($(TEAMID))
15-
DEVID ?= DDB5489E29389E9081E0A2FD83B6555D1B101829
14+
#DEVID ?= DDB5489E29389E9081E0A2FD83B6555D1B101829
15+
#DEVID ?= 3rd Party Mac Developer Application: Perry Kundert ($(TEAMID))
16+
#DEVID ?= A5DE932A0649AE3B6F06A8134F3E19D2E19A8196
17+
# Developer ID Application (not for Mac App Store)
18+
DEVID ?= EAA134BE299C43D27E33E2B8645FF4CF55DE8A92
19+
1620
#PKGID ?= 3rd Party Mac Developer Installer: Perry Kundert ($(TEAMID))
21+
#PKGID ?= 1B482CEB543825C33C366A5665B935D3CEC9FD05
22+
1723
PKGID ?= Developer ID Installer: Perry Kundert ($(TEAMID))
18-
DSTID ?= Apple Distribution: Perry Kundert ($(TEAMID))
24+
25+
1926
BUNDLEID ?= ca.kundert.perry.SLIP39
2027
APIISSUER ?= 5f3b4519-83ae-4e01-8d31-f7db26f68290
2128
APIKEY ?= 5H98J7LKPC
29+
#PROVISION ?= ~/Documents/Apple/Certificates/SLIP39_Mac_App_Store_Provisioning.provisionprofile
30+
PROVISION ?= ~/Documents/Apple/Certificates/SLIP39_Mac_General_Provisioning.provisionprofile
2231

2332
# Various cx_Freeze targets are at paths with computed extensions, eg: build/exe.win-amd64-3.10/
2433
CXFREEZE_VER ?= 3.10
@@ -385,12 +394,15 @@ dist/SLIP-39-$(VERSION).dmg.upload-app: dist/SLIP-39-$(VERSION).dmg dist/SLIP-39
385394
# Must copy the app w/ ditto, into a target dir structure including the destination location, eg. /Applications/SLIP-39.app/...
386395
#
387396
dist/SLIP-39-$(VERSION).pkg: dist/SLIP-39.app
388-
rm -rf /tmp/SLIP-39
389-
ditto $< /tmp/SLIP-39/Applications/SLIP-39.app
390-
productbuild --sign "$(PKGID)" --timestamp \
397+
#rm -rf /tmp/SLIP-39-pkg
398+
#ditto $< /tmp/SLIP-39-pkg/SLIP-39.app
399+
productbuild \
400+
--sign "$(PKGID)" \
401+
--timestamp \
391402
--identifier "$(BUNDLEID).pkg" \
392403
--version $(VERSION) \
393-
--root /tmp/SLIP-39/Applications/ / $@
404+
--root "$<" "/Applications/SLIP-39.app/" \
405+
$@
394406

395407

396408
# Confirm that the .pkg is signed w/ the correct certificates.
@@ -599,32 +611,46 @@ dist/SLIP-39.app-checkids: SLIP-39.spec
599611
# - Find each dependent key, and look at its SHA fingerprint, and then see if you have
600612
# that one in your System keychain, downloading all the named keys from apple 'til
601613
# you find the one with the matching fingerprint. Grr... Repeat 'til check-signature works.
614+
# * To be accepted by the Mac App Store, your App must be signed, and have an entitlements.plist
615+
# containing:
616+
# <key>com.apple.security.app-sandbox</key> <true/>
617+
# - This causes PyInstaller created apps to crash, because they can't execute the Python interpreter
618+
# recursively (?) https://github.com/pyinstaller/pyinstaller/issues/2198
619+
# - Here is an up-to-date diary of the woes encountered: https://github.com/pyinstaller/pyinstaller/issues/7123
620+
# - A summary of the solutions is here: https://github.com/nyavramov/python_app_mac_app_store
621+
#
602622
dist/SLIP-39.app: SLIP-39-macOS.spec \
603623
SLIP-39.metadata/entitlements.plist \
604-
images/SLIP-39.icns
624+
images/SLIP-39.icns \
625+
$(PROVISION)
605626
@echo -e "\n\n*** Rebuilding $@, version $(VERSION)..."
606627
rm -rf build $@*
607628
sed -I "" -E "s/version=.*/version='$(VERSION)',/" $<
608629
sed -I "" -E "s/'CFBundleVersion':.*/'CFBundleVersion':'$(VERSION)',/" $<
609630
sed -I "" -E "s/codesign_identity=.*/codesign_identity='$(DEVID)',/" $<
610631
pyinstaller --noconfirm $<
632+
#echo "Copying Provisioning Profile..."; rsync -va $(PROVISION) $@/Contents/embedded.provisionprofile
611633
echo "Checking signature (pyinstaller signed)..."; ./SLIP-39.metadata/check-signature $@ || true
612-
codesign --verify $@
634+
codesign --verify --verbose $@
613635
# codesign --deep --force \
614636
# --all-architectures --options=runtime --timestamp \
615637
# --sign "$(DEVID)" \
616638
# $@
617639
# echo "Checking signature (app code signed)..."; ./SLIP-39.metadata/check-signature $@ || true
618640
# codesign --verify $@
619-
codesign --deep --force \
620-
--all-architectures --options=runtime --timestamp \
641+
codesign --deep --force --timestamp --verbose --options runtime \
642+
--all-architectures \
621643
--entitlements ./SLIP-39.metadata/entitlements.plist \
622644
--sign "$(DEVID)" \
623645
$@
624646
echo "Checking signature (app code + entitlements signed w/ $(DEVID))..."; ./SLIP-39.metadata/check-signature $@ || true
625-
codesign --verify $@
647+
codesign --verify --verbose $@
626648
touch $@ # try to avoid unnecessary rebuilding
627649

650+
app-assess: dist/SLIP-39.app
651+
spctl --assess --type execute --context context:primary-signature -vvv $<
652+
653+
628654
#
629655
# Only used for initial creation of SLIP-39.spec; it must be customized, so this target cannot be
630656
# used to achieve a complete, operational SLIP-39.spec file!
@@ -650,7 +676,6 @@ SLIP-39-macOS.spec: SLIP-39.py
650676
pyinstaller --noconfirm --windowed --onefile \
651677
--codesign-identity "$(DEVID)" \
652678
--osx-bundle-identifier "$(BUNDLEID)" \
653-
--osx-entitlements-file ./SLIP-39.metadata/entitlements.plist \
654679
--collect-data shamir_mnemonic \
655680
--hidden-import slip39 \
656681
--collect-data slip39 \

SLIP-39-macOS.spec

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ datas = []
55
datas += collect_data_files('shamir_mnemonic')
66
datas += collect_data_files('slip39')
77

8+
block_cipher = None
89

910
a = Analysis(
1011
['SLIP-39.py'],
@@ -16,9 +17,17 @@ a = Analysis(
1617
hooksconfig={},
1718
runtime_hooks=[],
1819
excludes=[],
20+
win_no_prefer_redirects=False,
21+
win_private_assemblies=False,
22+
cipher=block_cipher,
1923
noarchive=False,
2024
)
21-
pyz = PYZ(a.pure)
25+
26+
pyz = PYZ(
27+
a.pure,
28+
a.zipped_data,
29+
cipher=block_cipher,
30+
)
2231

2332
exe = EXE(
2433
pyz,
@@ -37,20 +46,29 @@ exe = EXE(
3746
disable_windowed_traceback=False,
3847
argv_emulation=False,
3948
target_arch=None,
40-
codesign_identity='DDB5489E29389E9081E0A2FD83B6555D1B101829',
41-
entitlements_file='./SLIP-39.metadata/entitlements.plist',
49+
codesign_identity='EAA134BE299C43D27E33E2B8645FF4CF55DE8A92',
50+
entitlements_file=None,
51+
icon='images/SLIP-39.icns',
4252
)
53+
4354
app = BUNDLE(
4455
exe,
4556
name='SLIP-39.app',
4657
icon='images/SLIP-39.icns',
4758
version='11.1.1',
4859
info_plist={
60+
'NSPrincipalClass': 'NSApplication',
61+
'NSAppleScriptEnabled': False,
62+
'LSBackgroundOnly': False,
63+
'NSRequiresAquaSystemAppearance': 'No',
64+
'CFBundleSupportedPlatforms': ['MacOSX'],
65+
'CFBundleIdentifier': 'ca.kundert.perry.SLIP39',
4966
'CFBundleVersion':'11.1.1',
5067
'CFBundlePackageType':'APPL',
5168
'LSApplicationCategoryType':'public.app-category.utilities',
52-
'LSMinimumSystemVersion':'10.15.0',
69+
'LSMinimumSystemVersion':'10.15',
5370
'NSHumanReadableCopyright':"Copyright © 2023 Perry Kundert.",
71+
'ITSAppUsesNonExemptEncryption': False,
5472
},
5573
bundle_identifier='ca.kundert.perry.SLIP39',
5674
)

SLIP-39.metadata/entitlements.plist

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
<plist version="1.0">
44
<dict>
5-
<!--
6-
<key>com.apple.security.app-sandbox</key> <true/>
7-
-->
85
<key>com.apple.security.files.user-selected.read-write</key> <true/>
96
<!-- These are required for binaries built by PyInstaller -->
7+
<!--
8+
<key>com.apple.security.app-sandbox</key> <true/>
9+
-->
1010
<key>com.apple.security.cs.allow-jit</key> <true/>
1111
<key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/>
1212
<key>com.apple.security.cs.disable-library-validation</key> <true/>

slip39/gui/main.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ def groups_layout(
239239
[
240240
sg.Text( f"Seed Name{LO_PRO and 's, ...' or ''}:", size=prefix, **T_kwds ),
241241
sg.Input( f"{', '.join(names)}",key='-NAMES-', size=inputs, **I_kwds ),
242+
sg.Checkbox( '2-Sided',key='-PF-DOUBLE-', default=True, **I_kwds ),
242243
],
243244
[
244245
sg.Text( "Card size:", **T_hue( T_kwds, 1/20 )),
@@ -1524,9 +1525,10 @@ def deficiency( *deficiencies ):
15241525
# We have a complete SLIP-39 Mnemonic set. If we get here, no failure status has been
15251526
# detected, and SLIP39 mnemonic and account details { "name": <details> } have been created;
15261527
# we can now save the PDFs; converted details is now { "<filename>": <details> })
1527-
if wallet_pwd is not False:
1528-
# And, if Paper Wallets haven't been disabled completely, remember our password/hint
1529-
wallet_pwd = values['-WALLET-PASS-'] # Produces Paper Wallet(s) iff set
1528+
if wallet_pwd is not False and values['-WALLET-PASS-'] or values['-WALLET-HINT-']:
1529+
# And, if Paper Wallets haven't been disabled completely, remember our password/hint.
1530+
# If we're supplied a wallet password "hint", we allow even the empty wallet password.
1531+
wallet_pwd = values['-WALLET-PASS-']
15301532
wallet_pwd_hint = values['-WALLET-HINT-']
15311533

15321534
if event in ('-SAVE-', '-PRINT-'):
@@ -1549,6 +1551,8 @@ def deficiency( *deficiencies ):
15491551
try:
15501552
card_format = next( c for c in CARD_SIZES if values[f"-CS-{c}-"] )
15511553
paper_format = next( pf for pn,pf in PAPER_FORMATS.items() if values[f"-PF-{pn}-"] )
1554+
wallet_format = next( (f for f in WALLET_SIZES if values.get( f"-WALLET-SIZE-{f}-" )), None )
1555+
double_sided = values['-PF-DOUBLE-']
15521556
details = write_pdfs(
15531557
names = details,
15541558
using_bip39 = using_bip39,
@@ -1558,10 +1562,11 @@ def deficiency( *deficiencies ):
15581562
edit = edit,
15591563
wallet_pwd = wallet_pwd,
15601564
wallet_pwd_hint = wallet_pwd_hint,
1561-
wallet_format = next( (f for f in WALLET_SIZES if values.get( f"-WALLET-SIZE-{f}-" )), None ),
1565+
wallet_format = wallet_format,
15621566
filepath = filepath,
15631567
printer = printer,
15641568
watermark = watermark,
1569+
double_sided = double_sided,
15651570
)
15661571
except Exception as exc:
15671572
status = f"Error saving PDF(s): {exc}"

slip39/recovery/__init__.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,22 @@ def detect_language(cls, code: str) -> str:
4747
"""Scan the Mnemonic until the language becomes unambiguous, including as abbreviation prefixes."""
4848
code = cls.normalize_string(code)
4949
possible = set(cls(lang) for lang in cls.list_languages())
50-
for word in code.split():
50+
words = set(code.split())
51+
for word in words:
5152
# possible languages have candidate(s) starting with the word/prefix
5253
possible = set(p for p in possible if any(c.startswith( word ) for c in p.wordlist))
5354
if not possible:
5455
raise ConfigurationError(f"Language unrecognized for {word!r}")
55-
if len( possible ) < 2:
56-
break
5756
if len(possible) == 1:
5857
return possible.pop().language
58+
# Multiple languages match: A prefix in many, but an exact match in one determines language.
59+
complete = set()
60+
for word in words:
61+
exact = set(p for p in possible if word in p.wordlist)
62+
if len(exact) == 1:
63+
complete.update(exact)
64+
if len(complete) == 1:
65+
return complete.pop().language
5966
raise ConfigurationError(
6067
f"Language ambiguous between {', '.join( p.language for p in possible)}"
6168
)

0 commit comments

Comments
 (0)