Merge branch 'release/0.2.10'
This commit is contained in:
commit
c45a08b929
40 changed files with 505 additions and 229 deletions
2
Podfile
2
Podfile
|
|
@ -2,7 +2,7 @@ platform :ios, '10.2'
|
|||
use_frameworks!
|
||||
|
||||
target 'passKit' do
|
||||
pod 'ObjectivePGP', :git => 'https://github.com/krzyzanowskim/ObjectivePGP.git'
|
||||
pod 'ObjectivePGP', :git => 'https://github.com/krzyzanowskim/ObjectivePGP.git', :tag => '0.9.0'
|
||||
target 'pass' do
|
||||
inherit! :search_paths
|
||||
end
|
||||
|
|
|
|||
13
README.md
13
README.md
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# Pass
|
||||
[](https://github.com/mssun/pass-ios/releases)
|
||||

|
||||

|
||||
[](https://gitter.im/passforios/passforios)
|
||||
[](https://travis-ci.org/mssun/passforios)
|
||||
[](https://www.paypal.me/mssun)
|
||||
|
|
@ -11,9 +11,14 @@ Pass is an iOS client compatible with [ZX2C4's Pass command line
|
|||
application](http://www.passwordstore.org/). It is a password manager using
|
||||
GPG for encryption and Git for version control.
|
||||
|
||||
Pass for iOS is available in the [App Store](https://appsto.re/us/DY13hb.i)
|
||||
with the name "Pass - Password Store". If you want to join the iOS beta via
|
||||
Testflight, drop an email to `developer@passforios.mssun.me`. Thank you.
|
||||
Pass for iOS is available in the App Store with the name "Pass - Password Store".
|
||||
|
||||
<p>
|
||||
<a href="https://itunes.apple.com/us/app/pass-password-store/id1205820573?mt=8"><img alt="Download on the App Store" src="badge/app_store_badge.svg" width="150"/></a>
|
||||
</p>
|
||||
|
||||
If you want to join the iOS beta via
|
||||
TestFlight, drop an email to `developer@passforios.mssun.me`. Thank you.
|
||||
|
||||
## Features
|
||||
|
||||
|
|
|
|||
129
badge/app_store_badge.svg
Normal file
129
badge/app_store_badge.svg
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="US_UK_Download_on_the" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
x="0px" y="0px" width="135px" height="40px" viewBox="0 0 135 40" enable-background="new 0 0 135 40" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#A6A6A6" d="M130.197,40H4.729C2.122,40,0,37.872,0,35.267V4.726C0,2.12,2.122,0,4.729,0h125.468
|
||||
C132.803,0,135,2.12,135,4.726v30.541C135,37.872,132.803,40,130.197,40L130.197,40z"/>
|
||||
<path d="M134.032,35.268c0,2.116-1.714,3.83-3.834,3.83H4.729c-2.119,0-3.839-1.714-3.839-3.83V4.725
|
||||
c0-2.115,1.72-3.835,3.839-3.835h125.468c2.121,0,3.834,1.72,3.834,3.835L134.032,35.268L134.032,35.268z"/>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M30.128,19.784c-0.029-3.223,2.639-4.791,2.761-4.864c-1.511-2.203-3.853-2.504-4.676-2.528
|
||||
c-1.967-0.207-3.875,1.177-4.877,1.177c-1.022,0-2.565-1.157-4.228-1.123c-2.14,0.033-4.142,1.272-5.24,3.196
|
||||
c-2.266,3.923-0.576,9.688,1.595,12.859c1.086,1.553,2.355,3.287,4.016,3.226c1.625-0.067,2.232-1.036,4.193-1.036
|
||||
c1.943,0,2.513,1.036,4.207,0.997c1.744-0.028,2.842-1.56,3.89-3.127c1.255-1.78,1.759-3.533,1.779-3.623
|
||||
C33.507,24.924,30.161,23.647,30.128,19.784z"/>
|
||||
<path fill="#FFFFFF" d="M26.928,10.306c0.874-1.093,1.472-2.58,1.306-4.089c-1.265,0.056-2.847,0.875-3.758,1.944
|
||||
c-0.806,0.942-1.526,2.486-1.34,3.938C24.557,12.205,26.016,11.382,26.928,10.306z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M53.645,31.504h-2.271l-1.244-3.909h-4.324l-1.185,3.909h-2.211l4.284-13.308h2.646L53.645,31.504z
|
||||
M49.755,25.955L48.63,22.48c-0.119-0.355-0.342-1.191-0.671-2.507h-0.04c-0.131,0.566-0.342,1.402-0.632,2.507l-1.105,3.475
|
||||
H49.755z"/>
|
||||
<path fill="#FFFFFF" d="M64.662,26.588c0,1.632-0.441,2.922-1.323,3.869c-0.79,0.843-1.771,1.264-2.942,1.264
|
||||
c-1.264,0-2.172-0.454-2.725-1.362h-0.04v5.055h-2.132V25.067c0-1.026-0.027-2.079-0.079-3.159h1.875l0.119,1.521h0.04
|
||||
c0.711-1.146,1.79-1.718,3.238-1.718c1.132,0,2.077,0.447,2.833,1.342C64.284,23.949,64.662,25.127,64.662,26.588z M62.49,26.666
|
||||
c0-0.934-0.21-1.704-0.632-2.31c-0.461-0.632-1.08-0.948-1.856-0.948c-0.526,0-1.004,0.176-1.431,0.523
|
||||
c-0.428,0.35-0.708,0.807-0.839,1.373c-0.066,0.264-0.099,0.48-0.099,0.65v1.6c0,0.698,0.214,1.287,0.642,1.768
|
||||
s0.984,0.721,1.668,0.721c0.803,0,1.428-0.31,1.875-0.928C62.266,28.496,62.49,27.68,62.49,26.666z"/>
|
||||
<path fill="#FFFFFF" d="M75.699,26.588c0,1.632-0.441,2.922-1.324,3.869c-0.789,0.843-1.77,1.264-2.941,1.264
|
||||
c-1.264,0-2.172-0.454-2.724-1.362H68.67v5.055h-2.132V25.067c0-1.026-0.027-2.079-0.079-3.159h1.875l0.119,1.521h0.04
|
||||
c0.71-1.146,1.789-1.718,3.238-1.718c1.131,0,2.076,0.447,2.834,1.342C75.32,23.949,75.699,25.127,75.699,26.588z M73.527,26.666
|
||||
c0-0.934-0.211-1.704-0.633-2.31c-0.461-0.632-1.078-0.948-1.855-0.948c-0.527,0-1.004,0.176-1.432,0.523
|
||||
c-0.428,0.35-0.707,0.807-0.838,1.373c-0.065,0.264-0.099,0.48-0.099,0.65v1.6c0,0.698,0.214,1.287,0.64,1.768
|
||||
c0.428,0.48,0.984,0.721,1.67,0.721c0.803,0,1.428-0.31,1.875-0.928C73.303,28.496,73.527,27.68,73.527,26.666z"/>
|
||||
<path fill="#FFFFFF" d="M88.039,27.772c0,1.132-0.393,2.053-1.182,2.764c-0.867,0.777-2.074,1.165-3.625,1.165
|
||||
c-1.432,0-2.58-0.276-3.449-0.829l0.494-1.777c0.936,0.566,1.963,0.85,3.082,0.85c0.803,0,1.428-0.182,1.877-0.544
|
||||
c0.447-0.362,0.67-0.848,0.67-1.454c0-0.54-0.184-0.995-0.553-1.364c-0.367-0.369-0.98-0.712-1.836-1.029
|
||||
c-2.33-0.869-3.494-2.142-3.494-3.816c0-1.094,0.408-1.991,1.225-2.689c0.814-0.699,1.9-1.048,3.258-1.048
|
||||
c1.211,0,2.217,0.211,3.02,0.632l-0.533,1.738c-0.75-0.408-1.598-0.612-2.547-0.612c-0.75,0-1.336,0.185-1.756,0.553
|
||||
c-0.355,0.329-0.533,0.73-0.533,1.205c0,0.526,0.203,0.961,0.611,1.303c0.355,0.316,1,0.658,1.936,1.027
|
||||
c1.145,0.461,1.986,1,2.527,1.618C87.77,26.081,88.039,26.852,88.039,27.772z"/>
|
||||
<path fill="#FFFFFF" d="M95.088,23.508h-2.35v4.659c0,1.185,0.414,1.777,1.244,1.777c0.381,0,0.697-0.033,0.947-0.099l0.059,1.619
|
||||
c-0.42,0.157-0.973,0.236-1.658,0.236c-0.842,0-1.5-0.257-1.975-0.77c-0.473-0.514-0.711-1.376-0.711-2.587v-4.837h-1.4v-1.6h1.4
|
||||
v-1.757l2.094-0.632v2.389h2.35V23.508z"/>
|
||||
<path fill="#FFFFFF" d="M105.691,26.627c0,1.475-0.422,2.686-1.264,3.633c-0.883,0.975-2.055,1.461-3.516,1.461
|
||||
c-1.408,0-2.529-0.467-3.365-1.401s-1.254-2.113-1.254-3.534c0-1.487,0.43-2.705,1.293-3.652c0.861-0.948,2.023-1.422,3.484-1.422
|
||||
c1.408,0,2.541,0.467,3.396,1.402C105.283,24.021,105.691,25.192,105.691,26.627z M103.479,26.696
|
||||
c0-0.885-0.189-1.644-0.572-2.277c-0.447-0.766-1.086-1.148-1.914-1.148c-0.857,0-1.508,0.383-1.955,1.148
|
||||
c-0.383,0.634-0.572,1.405-0.572,2.317c0,0.885,0.189,1.644,0.572,2.276c0.461,0.766,1.105,1.148,1.936,1.148
|
||||
c0.814,0,1.453-0.39,1.914-1.168C103.281,28.347,103.479,27.58,103.479,26.696z"/>
|
||||
<path fill="#FFFFFF" d="M112.621,23.783c-0.211-0.039-0.436-0.059-0.672-0.059c-0.75,0-1.33,0.283-1.738,0.85
|
||||
c-0.355,0.5-0.533,1.132-0.533,1.895v5.035h-2.131l0.02-6.574c0-1.106-0.027-2.113-0.08-3.021h1.857l0.078,1.836h0.059
|
||||
c0.225-0.631,0.58-1.139,1.066-1.52c0.475-0.343,0.988-0.514,1.541-0.514c0.197,0,0.375,0.014,0.533,0.039V23.783z"/>
|
||||
<path fill="#FFFFFF" d="M122.156,26.252c0,0.382-0.025,0.704-0.078,0.967h-6.396c0.025,0.948,0.334,1.673,0.928,2.173
|
||||
c0.539,0.447,1.236,0.671,2.092,0.671c0.947,0,1.811-0.151,2.588-0.454l0.334,1.48c-0.908,0.396-1.98,0.593-3.217,0.593
|
||||
c-1.488,0-2.656-0.438-3.506-1.313c-0.848-0.875-1.273-2.05-1.273-3.524c0-1.447,0.395-2.652,1.186-3.613
|
||||
c0.828-1.026,1.947-1.539,3.355-1.539c1.383,0,2.43,0.513,3.141,1.539C121.873,24.047,122.156,25.055,122.156,26.252z
|
||||
M120.123,25.699c0.014-0.632-0.125-1.178-0.414-1.639c-0.369-0.593-0.936-0.889-1.699-0.889c-0.697,0-1.264,0.289-1.697,0.869
|
||||
c-0.355,0.461-0.566,1.014-0.631,1.658H120.123z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M49.05,10.009c0,1.177-0.353,2.063-1.058,2.658c-0.653,0.549-1.581,0.824-2.783,0.824
|
||||
c-0.596,0-1.106-0.026-1.533-0.078V6.982c0.557-0.09,1.157-0.136,1.805-0.136c1.145,0,2.008,0.249,2.59,0.747
|
||||
C48.723,8.156,49.05,8.961,49.05,10.009z M47.945,10.038c0-0.763-0.202-1.348-0.606-1.756c-0.404-0.407-0.994-0.611-1.771-0.611
|
||||
c-0.33,0-0.611,0.022-0.844,0.068v4.889c0.129,0.02,0.365,0.029,0.708,0.029c0.802,0,1.421-0.223,1.857-0.669
|
||||
S47.945,10.892,47.945,10.038z"/>
|
||||
<path fill="#FFFFFF" d="M54.909,11.037c0,0.725-0.207,1.319-0.621,1.785c-0.434,0.479-1.009,0.718-1.727,0.718
|
||||
c-0.692,0-1.243-0.229-1.654-0.689c-0.41-0.459-0.615-1.038-0.615-1.736c0-0.73,0.211-1.329,0.635-1.794s0.994-0.698,1.712-0.698
|
||||
c0.692,0,1.248,0.229,1.669,0.688C54.708,9.757,54.909,10.333,54.909,11.037z M53.822,11.071c0-0.435-0.094-0.808-0.281-1.119
|
||||
c-0.22-0.376-0.533-0.564-0.94-0.564c-0.421,0-0.741,0.188-0.961,0.564c-0.188,0.311-0.281,0.69-0.281,1.138
|
||||
c0,0.435,0.094,0.808,0.281,1.119c0.227,0.376,0.543,0.564,0.951,0.564c0.4,0,0.714-0.191,0.94-0.574
|
||||
C53.725,11.882,53.822,11.506,53.822,11.071z"/>
|
||||
<path fill="#FFFFFF" d="M62.765,8.719l-1.475,4.714h-0.96l-0.611-2.047c-0.155-0.511-0.281-1.019-0.379-1.523h-0.019
|
||||
c-0.091,0.518-0.217,1.025-0.379,1.523l-0.649,2.047h-0.971l-1.387-4.714h1.077l0.533,2.241c0.129,0.53,0.235,1.035,0.32,1.513
|
||||
h0.019c0.078-0.394,0.207-0.896,0.389-1.503l0.669-2.25h0.854l0.641,2.202c0.155,0.537,0.281,1.054,0.378,1.552h0.029
|
||||
c0.071-0.485,0.178-1.002,0.32-1.552l0.572-2.202H62.765z"/>
|
||||
<path fill="#FFFFFF" d="M68.198,13.433H67.15v-2.7c0-0.832-0.316-1.248-0.95-1.248c-0.311,0-0.562,0.114-0.757,0.343
|
||||
c-0.193,0.229-0.291,0.499-0.291,0.808v2.796h-1.048v-3.366c0-0.414-0.013-0.863-0.038-1.349h0.921l0.049,0.737h0.029
|
||||
c0.122-0.229,0.304-0.418,0.543-0.569c0.284-0.176,0.602-0.265,0.95-0.265c0.44,0,0.806,0.142,1.097,0.427
|
||||
c0.362,0.349,0.543,0.87,0.543,1.562V13.433z"/>
|
||||
<path fill="#FFFFFF" d="M71.088,13.433h-1.047V6.556h1.047V13.433z"/>
|
||||
<path fill="#FFFFFF" d="M77.258,11.037c0,0.725-0.207,1.319-0.621,1.785c-0.434,0.479-1.01,0.718-1.727,0.718
|
||||
c-0.693,0-1.244-0.229-1.654-0.689c-0.41-0.459-0.615-1.038-0.615-1.736c0-0.73,0.211-1.329,0.635-1.794s0.994-0.698,1.711-0.698
|
||||
c0.693,0,1.248,0.229,1.67,0.688C77.057,9.757,77.258,10.333,77.258,11.037z M76.17,11.071c0-0.435-0.094-0.808-0.281-1.119
|
||||
c-0.219-0.376-0.533-0.564-0.939-0.564c-0.422,0-0.742,0.188-0.961,0.564c-0.188,0.311-0.281,0.69-0.281,1.138
|
||||
c0,0.435,0.094,0.808,0.281,1.119c0.227,0.376,0.543,0.564,0.951,0.564c0.4,0,0.713-0.191,0.939-0.574
|
||||
C76.074,11.882,76.17,11.506,76.17,11.071z"/>
|
||||
<path fill="#FFFFFF" d="M82.33,13.433h-0.941l-0.078-0.543h-0.029c-0.322,0.433-0.781,0.65-1.377,0.65
|
||||
c-0.445,0-0.805-0.143-1.076-0.427c-0.246-0.258-0.369-0.579-0.369-0.96c0-0.576,0.24-1.015,0.723-1.319
|
||||
c0.482-0.304,1.16-0.453,2.033-0.446V10.3c0-0.621-0.326-0.931-0.979-0.931c-0.465,0-0.875,0.117-1.229,0.349l-0.213-0.688
|
||||
c0.438-0.271,0.979-0.407,1.617-0.407c1.232,0,1.85,0.65,1.85,1.95v1.736C82.262,12.78,82.285,13.155,82.33,13.433z
|
||||
M81.242,11.813v-0.727c-1.156-0.02-1.734,0.297-1.734,0.95c0,0.246,0.066,0.43,0.201,0.553c0.135,0.123,0.307,0.184,0.512,0.184
|
||||
c0.23,0,0.445-0.073,0.641-0.218c0.197-0.146,0.318-0.331,0.363-0.558C81.236,11.946,81.242,11.884,81.242,11.813z"/>
|
||||
<path fill="#FFFFFF" d="M88.285,13.433h-0.93l-0.049-0.757h-0.029c-0.297,0.576-0.803,0.864-1.514,0.864
|
||||
c-0.568,0-1.041-0.223-1.416-0.669s-0.562-1.025-0.562-1.736c0-0.763,0.203-1.381,0.611-1.853c0.395-0.44,0.879-0.66,1.455-0.66
|
||||
c0.633,0,1.076,0.213,1.328,0.64h0.02V6.556h1.049v5.607C88.248,12.622,88.26,13.045,88.285,13.433z M87.199,11.445v-0.786
|
||||
c0-0.136-0.01-0.246-0.029-0.33c-0.059-0.252-0.186-0.464-0.379-0.635c-0.195-0.171-0.43-0.257-0.701-0.257
|
||||
c-0.391,0-0.697,0.155-0.922,0.466c-0.223,0.311-0.336,0.708-0.336,1.193c0,0.466,0.107,0.844,0.322,1.135
|
||||
c0.227,0.31,0.533,0.465,0.916,0.465c0.344,0,0.619-0.129,0.828-0.388C87.1,12.069,87.199,11.781,87.199,11.445z"/>
|
||||
<path fill="#FFFFFF" d="M97.248,11.037c0,0.725-0.207,1.319-0.621,1.785c-0.434,0.479-1.008,0.718-1.727,0.718
|
||||
c-0.691,0-1.242-0.229-1.654-0.689c-0.41-0.459-0.615-1.038-0.615-1.736c0-0.73,0.211-1.329,0.635-1.794s0.994-0.698,1.713-0.698
|
||||
c0.691,0,1.248,0.229,1.668,0.688C97.047,9.757,97.248,10.333,97.248,11.037z M96.162,11.071c0-0.435-0.094-0.808-0.281-1.119
|
||||
c-0.221-0.376-0.533-0.564-0.941-0.564c-0.42,0-0.74,0.188-0.961,0.564c-0.188,0.311-0.281,0.69-0.281,1.138
|
||||
c0,0.435,0.094,0.808,0.281,1.119c0.227,0.376,0.543,0.564,0.951,0.564c0.4,0,0.715-0.191,0.941-0.574
|
||||
C96.064,11.882,96.162,11.506,96.162,11.071z"/>
|
||||
<path fill="#FFFFFF" d="M102.883,13.433h-1.047v-2.7c0-0.832-0.316-1.248-0.951-1.248c-0.311,0-0.562,0.114-0.756,0.343
|
||||
s-0.291,0.499-0.291,0.808v2.796h-1.049v-3.366c0-0.414-0.012-0.863-0.037-1.349h0.92l0.049,0.737h0.029
|
||||
c0.123-0.229,0.305-0.418,0.543-0.569c0.285-0.176,0.602-0.265,0.951-0.265c0.439,0,0.805,0.142,1.096,0.427
|
||||
c0.363,0.349,0.543,0.87,0.543,1.562V13.433z"/>
|
||||
<path fill="#FFFFFF" d="M109.936,9.504h-1.154v2.29c0,0.582,0.205,0.873,0.611,0.873c0.188,0,0.344-0.016,0.467-0.049
|
||||
l0.027,0.795c-0.207,0.078-0.479,0.117-0.814,0.117c-0.414,0-0.736-0.126-0.969-0.378c-0.234-0.252-0.35-0.676-0.35-1.271V9.504
|
||||
h-0.689V8.719h0.689V7.855l1.027-0.31v1.173h1.154V9.504z"/>
|
||||
<path fill="#FFFFFF" d="M115.484,13.433h-1.049v-2.68c0-0.845-0.316-1.268-0.949-1.268c-0.486,0-0.818,0.245-1,0.735
|
||||
c-0.031,0.103-0.049,0.229-0.049,0.377v2.835h-1.047V6.556h1.047v2.841h0.02c0.33-0.517,0.803-0.775,1.416-0.775
|
||||
c0.434,0,0.793,0.142,1.078,0.427c0.355,0.355,0.533,0.883,0.533,1.581V13.433z"/>
|
||||
<path fill="#FFFFFF" d="M121.207,10.853c0,0.188-0.014,0.346-0.039,0.475h-3.143c0.014,0.466,0.164,0.821,0.455,1.067
|
||||
c0.266,0.22,0.609,0.33,1.029,0.33c0.465,0,0.889-0.074,1.271-0.223l0.164,0.728c-0.447,0.194-0.973,0.291-1.582,0.291
|
||||
c-0.73,0-1.305-0.215-1.721-0.645c-0.418-0.43-0.625-1.007-0.625-1.731c0-0.711,0.193-1.303,0.582-1.775
|
||||
c0.406-0.504,0.955-0.756,1.648-0.756c0.678,0,1.193,0.252,1.541,0.756C121.068,9.77,121.207,10.265,121.207,10.853z
|
||||
M120.207,10.582c0.008-0.311-0.061-0.579-0.203-0.805c-0.182-0.291-0.459-0.437-0.834-0.437c-0.342,0-0.621,0.142-0.834,0.427
|
||||
c-0.174,0.227-0.277,0.498-0.311,0.815H120.207z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -874,10 +874,12 @@
|
|||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-passKitTests/Pods-passKitTests-frameworks.sh",
|
||||
"${PODS_ROOT}/ObjectivePGP/Frameworks/ios/ObjectivePGP.framework",
|
||||
"${PODS_ROOT}/ObjectivePGP/Frameworks/ios/ObjectivePGP.framework.dSYM",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ObjectivePGP.framework",
|
||||
"${DWARF_DSYM_FOLDER_PATH}/ObjectivePGP.framework.dSYM",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
|
|
@ -910,10 +912,12 @@
|
|||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-pass/Pods-pass-frameworks.sh",
|
||||
"${PODS_ROOT}/ObjectivePGP/Frameworks/ios/ObjectivePGP.framework",
|
||||
"${PODS_ROOT}/ObjectivePGP/Frameworks/ios/ObjectivePGP.framework.dSYM",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ObjectivePGP.framework",
|
||||
"${DWARF_DSYM_FOLDER_PATH}/ObjectivePGP.framework.dSYM",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
|
|
@ -1196,7 +1200,7 @@
|
|||
SWIFT_INCLUDE_PATHS = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
|
@ -1241,7 +1245,7 @@
|
|||
SKIP_INSTALL = YES;
|
||||
SWIFT_INCLUDE_PATHS = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
|
@ -1264,7 +1268,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER).passKitTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/pass.app/pass";
|
||||
};
|
||||
|
|
@ -1285,7 +1289,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER).passKitTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/pass.app/pass";
|
||||
};
|
||||
|
|
@ -1319,7 +1323,7 @@
|
|||
PROVISIONING_PROFILE = "d25c9029-bca6-4b2d-b04e-4abc9d232740";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "match Development me.mssun.passforios.find-login-action-extension";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
|
|
@ -1352,7 +1356,7 @@
|
|||
PROVISIONING_PROFILE = "cbd86628-6f3e-40f3-b518-20d2330db545";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.mssun.passforios.find-login-action-extension";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
|
|
@ -1368,7 +1372,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER).passTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/pass.app/pass";
|
||||
};
|
||||
|
|
@ -1385,7 +1389,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER).passTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/pass.app/pass";
|
||||
};
|
||||
|
|
@ -1444,7 +1448,7 @@
|
|||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
|
@ -1493,7 +1497,7 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = me.mssun.passforios;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
|
|
@ -1529,7 +1533,7 @@
|
|||
PROVISIONING_PROFILE = "2e72f4af-b935-4970-9cd3-44d4cc24b646";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "match Development me.mssun.passforios";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "pass/Helpers/Objective-CBridgingHeader.h";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
|
@ -1567,7 +1571,7 @@
|
|||
PROVISIONING_PROFILE = "ee6e841d-ef77-4f00-b534-d7f1fd25dc1d";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.mssun.passforios";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "pass/Helpers/Objective-CBridgingHeader.h";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0900"
|
||||
LastUpgradeVersion = "0910"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -425,13 +425,13 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Password" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="LfQ-Af-j2O">
|
||||
<rect key="frame" x="62" y="0.0" width="343" height="44"/>
|
||||
<rect key="frame" x="62" y="0.0" width="344" height="44"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" tag="1001" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="✓" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Scc-5J-bu1">
|
||||
<rect key="frame" x="23" y="11" width="16" height="22"/>
|
||||
<rect key="frame" x="23" y="11" width="15.666666666666664" height="22"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="18"/>
|
||||
<color key="textColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
|
@ -439,9 +439,10 @@
|
|||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="Scc-5J-bu1" firstAttribute="leading" secondItem="1uB-oE-kfI" secondAttribute="leadingMargin" constant="15" id="8Z8-4c-oDD"/>
|
||||
<constraint firstItem="LfQ-Af-j2O" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Scc-5J-bu1" secondAttribute="trailing" constant="20" id="I9d-Au-QVj"/>
|
||||
<constraint firstItem="LfQ-Af-j2O" firstAttribute="top" secondItem="1uB-oE-kfI" secondAttribute="topMargin" constant="-8" id="OPg-oc-KZy"/>
|
||||
<constraint firstItem="LfQ-Af-j2O" firstAttribute="leading" secondItem="1uB-oE-kfI" secondAttribute="leadingMargin" constant="54" id="TCp-fd-Sim"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="LfQ-Af-j2O" secondAttribute="trailing" constant="1" id="dDF-2l-XhB"/>
|
||||
<constraint firstItem="LfQ-Af-j2O" firstAttribute="leading" relation="lessThanOrEqual" secondItem="1uB-oE-kfI" secondAttribute="leadingMargin" constant="54" id="TCp-fd-Sim"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="LfQ-Af-j2O" secondAttribute="trailing" id="dDF-2l-XhB"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="LfQ-Af-j2O" secondAttribute="bottom" constant="-8.3333333333333357" id="e3U-qA-37g"/>
|
||||
<constraint firstItem="Scc-5J-bu1" firstAttribute="centerY" secondItem="1uB-oE-kfI" secondAttribute="centerY" id="eyS-Gb-VOi"/>
|
||||
</constraints>
|
||||
|
|
@ -471,10 +472,11 @@
|
|||
<constraints>
|
||||
<constraint firstItem="wbx-rk-i8H" firstAttribute="leading" secondItem="p3u-8b-h3U" secondAttribute="leadingMargin" constant="15" id="1gS-CT-W2C"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="Ezz-76-a53" secondAttribute="bottom" constant="-8.3333333333333357" id="NW7-VO-yjh"/>
|
||||
<constraint firstItem="Ezz-76-a53" firstAttribute="leading" secondItem="p3u-8b-h3U" secondAttribute="leadingMargin" constant="54" id="Ols-7H-4Lb"/>
|
||||
<constraint firstItem="Ezz-76-a53" firstAttribute="leading" relation="lessThanOrEqual" secondItem="p3u-8b-h3U" secondAttribute="leadingMargin" constant="54" id="Ols-7H-4Lb"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="Ezz-76-a53" secondAttribute="trailing" constant="1" id="hLu-eh-HXR"/>
|
||||
<constraint firstItem="Ezz-76-a53" firstAttribute="top" secondItem="p3u-8b-h3U" secondAttribute="topMargin" constant="-8" id="jVn-3g-0ax"/>
|
||||
<constraint firstItem="wbx-rk-i8H" firstAttribute="centerY" secondItem="p3u-8b-h3U" secondAttribute="centerY" id="jwk-j5-WsJ"/>
|
||||
<constraint firstItem="Ezz-76-a53" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="wbx-rk-i8H" secondAttribute="trailing" constant="23" id="xcB-Dt-05o"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
|
|
@ -487,7 +489,7 @@
|
|||
</connections>
|
||||
</tableView>
|
||||
<toolbarItems/>
|
||||
<navigationItem key="navigationItem" title="Git Server" id="gXX-yl-9oj">
|
||||
<navigationItem key="navigationItem" title="Git Server" largeTitleDisplayMode="never" id="gXX-yl-9oj">
|
||||
<barButtonItem key="rightBarButtonItem" title="Clone" style="done" id="sgQ-zB-rxv">
|
||||
<connections>
|
||||
<action selector="save:" destination="ynQ-64-MfA" id="HNL-Da-fXT"/>
|
||||
|
|
@ -596,8 +598,8 @@
|
|||
<outlet property="delegate" destination="3WR-HY-zYj" id="kqI-mx-f0D"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="PGP Key" id="eK3-bb-419">
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="save" id="TNt-ne-l7W">
|
||||
<navigationItem key="navigationItem" title="PGP Key" largeTitleDisplayMode="never" id="eK3-bb-419">
|
||||
<barButtonItem key="rightBarButtonItem" style="done" systemItem="save" id="TNt-ne-l7W">
|
||||
<connections>
|
||||
<action selector="save:" destination="3WR-HY-zYj" id="uLA-oz-lPI"/>
|
||||
</connections>
|
||||
|
|
@ -634,7 +636,7 @@
|
|||
<segue destination="rRf-7l-IGe" kind="unwind" unwindAction="cancelAddPasswordWithSegue:" id="G4F-ci-BmD"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="save" id="FtF-nT-zRJ">
|
||||
<barButtonItem key="rightBarButtonItem" style="done" systemItem="save" id="FtF-nT-zRJ">
|
||||
<connections>
|
||||
<segue destination="rRf-7l-IGe" kind="unwind" identifier="saveAddPasswordSegue" unwindAction="saveAddPasswordWithSegue:" id="eVU-Kz-JU0"/>
|
||||
</connections>
|
||||
|
|
@ -662,10 +664,11 @@
|
|||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="scanner output" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lOI-p4-BGb">
|
||||
<rect key="frame" x="50" y="562" width="314" height="45"/>
|
||||
<rect key="frame" x="57" y="562" width="300" height="45"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.5" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="45" id="bdi-FH-dMP"/>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="300" id="zBX-AY-wU0"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
|
|
@ -675,14 +678,13 @@
|
|||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="eYa-Io-fXF" firstAttribute="top" secondItem="lOI-p4-BGb" secondAttribute="bottom" constant="80" id="9iK-9H-fuB"/>
|
||||
<constraint firstItem="lOI-p4-BGb" firstAttribute="leading" secondItem="a0T-JY-UcS" secondAttribute="leadingMargin" constant="30" id="RCL-aq-Ywc"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="lOI-p4-BGb" secondAttribute="trailing" constant="30" id="qNb-4K-GGl"/>
|
||||
<constraint firstItem="lOI-p4-BGb" firstAttribute="centerX" secondItem="a0T-JY-UcS" secondAttribute="centerX" id="IVH-ax-fJ3"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" title="Scan OTP QR Codes" id="Hlb-5I-bfE">
|
||||
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="KBZ-N2-OGE">
|
||||
<connections>
|
||||
<segue destination="0gD-ix-2NF" kind="unwind" unwindAction="cancelOTPScannerWithSegue:" id="nZe-B6-MNt"/>
|
||||
<action selector="pressCancel:" destination="A9p-Qb-WmU" id="SYK-Qh-Cs7"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
|
|
@ -691,7 +693,6 @@
|
|||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="rqh-SR-bIq" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
<exit id="0gD-ix-2NF" userLabel="Exit" sceneMemberID="exit"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="7059" y="-1012"/>
|
||||
</scene>
|
||||
|
|
@ -776,8 +777,8 @@
|
|||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="ZmJ-0Z-N04" sceneMemberID="viewController">
|
||||
<tabBarItem key="tabBarItem" title="Settings" image="Settings" selectedImage="Settings" id="6Xa-be-Z8g"/>
|
||||
<toolbarItems/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="wWs-15-HDi">
|
||||
<rect key="frame" x="0.0" y="20" width="414" height="44"/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" largeTitles="YES" id="wWs-15-HDi">
|
||||
<rect key="frame" x="0.0" y="20" width="414" height="96"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<nil name="viewControllers"/>
|
||||
|
|
@ -809,7 +810,7 @@
|
|||
<segue destination="HB6-Yu-Y3J" kind="unwind" unwindAction="cancelEditPasswordWithSegue:" id="B5h-gu-WUv"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="save" id="4l7-58-u8N">
|
||||
<barButtonItem key="rightBarButtonItem" style="done" systemItem="save" id="4l7-58-u8N">
|
||||
<connections>
|
||||
<segue destination="HB6-Yu-Y3J" kind="unwind" identifier="saveEditPasswordSegue" unwindAction="saveEditPasswordWithSegue:" id="1sb-Aa-Qdy"/>
|
||||
</connections>
|
||||
|
|
@ -838,7 +839,7 @@
|
|||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" editable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3dt-Ph-4As">
|
||||
<rect key="frame" x="20" y="10" width="374" height="726"/>
|
||||
<rect key="frame" x="20" y="72" width="374" height="664"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<string key="text">K7PBbkoaJf6mLyVX3EBU
|
||||
username: passforios-demo@email.com
|
||||
|
|
@ -853,8 +854,8 @@ Phone Support PIN #: 84719</string>
|
|||
<constraints>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="3dt-Ph-4As" secondAttribute="trailing" id="2IV-7r-9eG"/>
|
||||
<constraint firstItem="7JD-uM-IyS" firstAttribute="top" secondItem="3dt-Ph-4As" secondAttribute="bottom" id="3yp-aL-exH"/>
|
||||
<constraint firstItem="3dt-Ph-4As" firstAttribute="top" secondItem="XeK-cv-AXf" secondAttribute="bottom" constant="-54" id="5y9-J3-Luj"/>
|
||||
<constraint firstAttribute="leadingMargin" secondItem="3dt-Ph-4As" secondAttribute="leading" id="jgf-j1-lNa"/>
|
||||
<constraint firstItem="3dt-Ph-4As" firstAttribute="top" secondItem="XeK-cv-AXf" secondAttribute="bottom" constant="8" symbolic="YES" id="yN7-0c-t4Y"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" title="Raw Password" id="c13-zM-tLf">
|
||||
|
|
@ -969,7 +970,7 @@ Phone Support PIN #: 84719</string>
|
|||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="SSH Key" id="DrT-Wk-L5K">
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="done" id="DEb-eH-FHf">
|
||||
<barButtonItem key="rightBarButtonItem" style="done" systemItem="done" id="DEb-eH-FHf">
|
||||
<connections>
|
||||
<action selector="doneButtonTapped:" destination="hqC-Ic-NMi" id="gIV-JX-4hk"/>
|
||||
</connections>
|
||||
|
|
@ -997,7 +998,7 @@ Phone Support PIN #: 84719</string>
|
|||
<outlet property="delegate" destination="ljx-el-KZL" id="suq-rR-a60"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="General" id="aAM-Iw-iBA"/>
|
||||
<navigationItem key="navigationItem" title="General" largeTitleDisplayMode="never" id="aAM-Iw-iBA"/>
|
||||
<connections>
|
||||
<segue destination="RcF-UZ-Tde" kind="show" identifier="showAboutRepositorySegue" id="X49-Em-78M"/>
|
||||
</connections>
|
||||
|
|
@ -1129,7 +1130,7 @@ Phone Support PIN #: 84719</string>
|
|||
<outlet property="delegate" destination="Rqu-AW-ZNQ" id="FIc-7F-8PL"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Advanced" id="tc7-wf-hG7"/>
|
||||
<navigationItem key="navigationItem" title="Advanced" largeTitleDisplayMode="never" id="tc7-wf-hG7"/>
|
||||
<connections>
|
||||
<outlet property="discardChangesTableViewCell" destination="Jm8-B5-wKx" id="rfA-G3-2OE"/>
|
||||
<outlet property="encryptInASCIIArmoredTableViewCell" destination="tHt-Ro-0HF" id="tOi-Sj-mLJ"/>
|
||||
|
|
@ -1155,7 +1156,7 @@ Phone Support PIN #: 84719</string>
|
|||
<outlet property="delegate" destination="ZcQ-fs-QEW" id="GET-cd-P5Q"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="About" id="Pel-JD-Z5x"/>
|
||||
<navigationItem key="navigationItem" title="About" largeTitleDisplayMode="never" id="Pel-JD-Z5x"/>
|
||||
<connections>
|
||||
<segue destination="yb5-mG-DI8" kind="show" identifier="showOpenSourceComponentsSegue" id="1lz-OC-pgC"/>
|
||||
<segue destination="NEk-KW-Ogp" kind="show" identifier="showSpecialThanksSegue" id="nzG-Je-gqo"/>
|
||||
|
|
@ -1271,7 +1272,7 @@ Phone Support PIN #: 84719</string>
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
<attributedString key="attributedText">
|
||||
<fragment>
|
||||
<string key="content">GnuPG supports a command-line option --armor that that causes output to be generated in an ASCII-armored format similar to unencoded documents rather than the binary format.
|
||||
<string key="content">GnuPG supports the command-line option "-a" that causes output to be generated in an ASCII-armored format similar to unencoded documents rather than the binary format.
|
||||
|
||||
</string>
|
||||
<attributes>
|
||||
|
|
@ -1324,7 +1325,7 @@ Cgo
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oyB-oI-1fS">
|
||||
<rect key="frame" x="15" y="8" width="391" height="144"/>
|
||||
<rect key="frame" x="15" y="8" width="391" height="143.66666666666666"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<fontDescription key="fontDescription" name="Menlo-Regular" family="Menlo" pointSize="8.5"/>
|
||||
|
|
@ -1362,7 +1363,7 @@ Cgo
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lrQ-Ln-ZOv">
|
||||
<rect key="frame" x="15" y="8" width="391" height="143"/>
|
||||
<rect key="frame" x="15" y="8" width="391" height="143.66666666666666"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<fontDescription key="fontDescription" name="Menlo-Regular" family="Menlo" pointSize="8.5"/>
|
||||
|
|
@ -1396,8 +1397,8 @@ Cgo
|
|||
<outlet property="delegate" destination="1gA-jh-frD" id="jKb-Ie-lOh"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="PGP Key" id="V4w-cf-d9g">
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="save" id="lVZ-mz-KGt">
|
||||
<navigationItem key="navigationItem" title="PGP Key" largeTitleDisplayMode="never" id="V4w-cf-d9g">
|
||||
<barButtonItem key="rightBarButtonItem" style="done" systemItem="save" id="lVZ-mz-KGt">
|
||||
<connections>
|
||||
<action selector="save:" destination="1gA-jh-frD" id="dfU-DP-Eth"/>
|
||||
</connections>
|
||||
|
|
@ -1517,7 +1518,7 @@ Cgo
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="23o-MP-wQY">
|
||||
<rect key="frame" x="15" y="8" width="391" height="143"/>
|
||||
<rect key="frame" x="15" y="8" width="391" height="143.66666666666666"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<fontDescription key="fontDescription" name="Menlo-Regular" family="Menlo" pointSize="8.5"/>
|
||||
|
|
@ -1549,7 +1550,7 @@ Cgo
|
|||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="SSH Key" id="gNq-BH-pj8">
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="done" id="X6m-eX-dl8">
|
||||
<barButtonItem key="rightBarButtonItem" style="done" systemItem="done" id="X6m-eX-dl8">
|
||||
<connections>
|
||||
<action selector="doneButtonTapped:" destination="WgM-cY-mig" id="7Yj-rw-y05"/>
|
||||
</connections>
|
||||
|
|
@ -1651,7 +1652,7 @@ Cgo
|
|||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Git Signature" id="pPi-jd-x5U">
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="save" id="kMD-4J-wBb">
|
||||
<barButtonItem key="rightBarButtonItem" style="done" systemItem="save" id="kMD-4J-wBb">
|
||||
<connections>
|
||||
<segue destination="M5P-Ab-cIc" kind="unwind" identifier="saveGitConfigSettingSegue" unwindAction="saveGitConfigSettingWithSegue:" id="RGN-ff-tuP"/>
|
||||
</connections>
|
||||
|
|
@ -1680,9 +1681,10 @@ Cgo
|
|||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="scanner output" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="U8O-Md-w8e">
|
||||
<rect key="frame" x="50" y="611" width="314" height="45"/>
|
||||
<rect key="frame" x="57" y="611" width="300" height="45"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.5" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="300" id="JcM-Sy-Hw8"/>
|
||||
<constraint firstAttribute="height" constant="45" id="q3X-BT-aK8"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
|
|
@ -1692,8 +1694,7 @@ Cgo
|
|||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="U8O-Md-w8e" secondAttribute="trailing" constant="30" id="Sok-Wi-SXQ"/>
|
||||
<constraint firstItem="U8O-Md-w8e" firstAttribute="leading" secondItem="CA8-A9-019" secondAttribute="leadingMargin" constant="30" id="opY-C9-XIS"/>
|
||||
<constraint firstItem="U8O-Md-w8e" firstAttribute="centerX" secondItem="CA8-A9-019" secondAttribute="centerX" id="OWy-pk-0Ip"/>
|
||||
<constraint firstItem="53A-gx-tky" firstAttribute="top" secondItem="U8O-Md-w8e" secondAttribute="bottom" constant="80" id="tzL-K0-lE7"/>
|
||||
</constraints>
|
||||
</view>
|
||||
|
|
@ -1719,9 +1720,10 @@ Cgo
|
|||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="scanner output" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fsL-pq-A5q">
|
||||
<rect key="frame" x="50" y="567" width="314" height="45"/>
|
||||
<rect key="frame" x="57" y="567" width="300" height="45"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.5" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="300" id="7Qj-pb-GoY"/>
|
||||
<constraint firstAttribute="height" constant="45" id="IPT-kM-arz"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
|
|
@ -1732,8 +1734,7 @@ Cgo
|
|||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="QZv-Im-xZk" firstAttribute="top" secondItem="fsL-pq-A5q" secondAttribute="bottom" constant="80" id="76J-7g-eVO"/>
|
||||
<constraint firstItem="fsL-pq-A5q" firstAttribute="leading" secondItem="GYE-sh-yvu" secondAttribute="leadingMargin" constant="30" id="IOo-JD-FMG"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="fsL-pq-A5q" secondAttribute="trailing" constant="30" id="ymC-G4-bdA"/>
|
||||
<constraint firstItem="fsL-pq-A5q" firstAttribute="centerX" secondItem="GYE-sh-yvu" secondAttribute="centerX" id="pev-xD-1vH"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" title="Scan SSH Keys" id="bov-FI-Hkg"/>
|
||||
|
|
@ -1805,7 +1806,7 @@ Cgo
|
|||
<image name="Settings" width="25" height="25"/>
|
||||
</resources>
|
||||
<inferredMetricsTieBreakers>
|
||||
<segue reference="iCM-Fy-hkk"/>
|
||||
<segue reference="yyD-4H-pLE"/>
|
||||
<segue reference="WfV-6d-ZUj"/>
|
||||
<segue reference="UfP-k3-XeR"/>
|
||||
</inferredMetricsTieBreakers>
|
||||
</document>
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import UIKit
|
|||
import passKit
|
||||
|
||||
class AddPasswordTableViewController: PasswordEditorTableViewController {
|
||||
var tempContent: String = ""
|
||||
let passwordStore = PasswordStore.shared
|
||||
var defaultDirPrefix = ""
|
||||
|
||||
override func viewDidLoad() {
|
||||
tableData = [
|
||||
|
|
@ -24,6 +24,7 @@ class AddPasswordTableViewController: PasswordEditorTableViewController {
|
|||
lengthSetting.max > lengthSetting.min {
|
||||
tableData[1].append([.type: PasswordEditorCellType.passwordLengthCell, .title: "passwordlength"])
|
||||
}
|
||||
tableData[0][0][PasswordEditorCellKey.content] = defaultDirPrefix
|
||||
super.viewDidLoad()
|
||||
}
|
||||
|
||||
|
|
@ -38,10 +39,7 @@ class AddPasswordTableViewController: PasswordEditorTableViewController {
|
|||
}
|
||||
|
||||
// check name
|
||||
guard nameCell?.getContent()?.isEmpty == false else {
|
||||
let alertTitle = "Cannot Add Password"
|
||||
let alertMessage = "Please fill in the name."
|
||||
Utils.alert(title: alertTitle, message: alertMessage, controller: self, completion: nil)
|
||||
guard checkName() == true else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
@ -56,9 +54,7 @@ class AddPasswordTableViewController: PasswordEditorTableViewController {
|
|||
plainText.append("\n")
|
||||
plainText.append(additionsString)
|
||||
}
|
||||
let encodedName = (nameCell?.getContent()?.stringByAddingPercentEncodingForRFC3986())!
|
||||
let name = URL(string: encodedName)!.lastPathComponent
|
||||
let url = URL(string: encodedName)!.appendingPathExtension("gpg")
|
||||
let (name, url) = getNameURL()
|
||||
password = Password(name: name, url: url, plainText: plainText)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,12 +27,8 @@ class EditPasswordTableViewController: PasswordEditorTableViewController {
|
|||
|
||||
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
|
||||
if identifier == "saveEditPasswordSegue" {
|
||||
if let name = nameCell?.getContent(),
|
||||
let path = name.stringByAddingPercentEncodingForRFC3986(),
|
||||
let _ = URL(string: path) {
|
||||
return true
|
||||
} else {
|
||||
Utils.alert(title: "Cannot Save", message: "Password name is invalid.", controller: self, completion: nil)
|
||||
// check name
|
||||
guard checkName() == true else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
@ -47,9 +43,7 @@ class EditPasswordTableViewController: PasswordEditorTableViewController {
|
|||
plainText.append("\n")
|
||||
plainText.append(additionsString)
|
||||
}
|
||||
let encodedName = (nameCell?.getContent()?.stringByAddingPercentEncodingForRFC3986())!
|
||||
let name = URL(string: encodedName)!.lastPathComponent
|
||||
let url = URL(string: encodedName)!.appendingPathExtension("gpg")
|
||||
let (name, url) = getNameURL()
|
||||
if password!.plainText != plainText || password!.url!.path != url.path {
|
||||
password!.updatePassword(name: name, url: url, plainText: plainText)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,12 +28,21 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
return uiSwitch
|
||||
}()
|
||||
|
||||
let rememberPassphraseSwitch: UISwitch = {
|
||||
let rememberPGPPassphraseSwitch: UISwitch = {
|
||||
let uiSwitch = UISwitch()
|
||||
uiSwitch.onTintColor = Globals.blue
|
||||
uiSwitch.sizeToFit()
|
||||
uiSwitch.addTarget(self, action: #selector(rememberPassphraseSwitchAction(_:)), for: UIControlEvents.valueChanged)
|
||||
uiSwitch.isOn = SharedDefaults[.isRememberPassphraseOn]
|
||||
uiSwitch.addTarget(self, action: #selector(rememberPGPPassphraseSwitchAction(_:)), for: UIControlEvents.valueChanged)
|
||||
uiSwitch.isOn = SharedDefaults[.isRememberPGPPassphraseOn]
|
||||
return uiSwitch
|
||||
}()
|
||||
|
||||
let rememberGitCredentialPassphraseSwitch: UISwitch = {
|
||||
let uiSwitch = UISwitch()
|
||||
uiSwitch.onTintColor = Globals.blue
|
||||
uiSwitch.sizeToFit()
|
||||
uiSwitch.addTarget(self, action: #selector(rememberGitCredentialPassphraseSwitchAction(_:)), for: UIControlEvents.valueChanged)
|
||||
uiSwitch.isOn = SharedDefaults[.isRememberGitCredentialPassphraseOn]
|
||||
return uiSwitch
|
||||
}()
|
||||
|
||||
|
|
@ -58,10 +67,11 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
|
||||
// section 2
|
||||
[
|
||||
[.title: "Remember Passphrase", .action: "none",],
|
||||
[.title: "Remember PGP Key Passphrase", .action: "none",],
|
||||
[.title: "Remember Git Credential Passphrase", .action: "none",],
|
||||
],
|
||||
[
|
||||
[.title: "Show Folder", .action: "none",],
|
||||
[.title: "Show Folders", .action: "none",],
|
||||
[.title: "Hide Unknown Fields", .action: "none",],
|
||||
[.title: "Hide OTP Fields", .action: "none",],
|
||||
],
|
||||
|
|
@ -98,11 +108,15 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
cell.accessoryView = accessoryView
|
||||
cell.selectionStyle = .none
|
||||
hideOTPSwitch.isOn = SharedDefaults[.isHideOTPOn]
|
||||
case "Remember Passphrase":
|
||||
case "Remember PGP Key Passphrase":
|
||||
cell.accessoryType = .none
|
||||
cell.selectionStyle = .none
|
||||
cell.accessoryView = rememberPassphraseSwitch
|
||||
case "Show Folder":
|
||||
cell.accessoryView = rememberPGPPassphraseSwitch
|
||||
case "Remember Git Credential Passphrase":
|
||||
cell.accessoryType = .none
|
||||
cell.selectionStyle = .none
|
||||
cell.accessoryView = rememberGitCredentialPassphraseSwitch
|
||||
case "Show Folders":
|
||||
cell.accessoryType = .none
|
||||
cell.selectionStyle = .none
|
||||
cell.accessoryView = showFolderSwitch
|
||||
|
|
@ -176,13 +190,21 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
NotificationCenter.default.post(name: .passwordDetailDisplaySettingChanged, object: nil)
|
||||
}
|
||||
|
||||
@objc func rememberPassphraseSwitchAction(_ sender: Any?) {
|
||||
SharedDefaults[.isRememberPassphraseOn] = rememberPassphraseSwitch.isOn
|
||||
if rememberPassphraseSwitch.isOn == false {
|
||||
@objc func rememberPGPPassphraseSwitchAction(_ sender: Any?) {
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = rememberPGPPassphraseSwitch.isOn
|
||||
if rememberPGPPassphraseSwitch.isOn == false {
|
||||
passwordStore.pgpKeyPassphrase = nil
|
||||
}
|
||||
}
|
||||
|
||||
@objc func rememberGitCredentialPassphraseSwitchAction(_ sender: Any?) {
|
||||
SharedDefaults[.isRememberGitCredentialPassphraseOn] = rememberGitCredentialPassphraseSwitch.isOn
|
||||
if rememberGitCredentialPassphraseSwitch.isOn == false {
|
||||
passwordStore.gitSSHPrivateKeyPassphrase = nil
|
||||
passwordStore.gitPassword = nil
|
||||
}
|
||||
}
|
||||
|
||||
@objc func showFolderSwitchAction(_ sender: Any?) {
|
||||
SharedDefaults[.isShowFolderOn] = showFolderSwitch.isOn
|
||||
NotificationCenter.default.post(name: .passwordDisplaySettingChanged, object: nil)
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
)
|
||||
)
|
||||
}
|
||||
// Remember git credential password/passphrase temporarily, ask whether users want this after a successful clone.
|
||||
SharedDefaults[.isRememberGitCredentialPassphraseOn] = true
|
||||
let dispatchQueue = DispatchQueue.global(qos: .userInitiated)
|
||||
dispatchQueue.async {
|
||||
do {
|
||||
|
|
@ -113,9 +115,21 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
SharedDefaults[.gitURL] = URL(string: gitRepostiroyURL)
|
||||
SharedDefaults[.gitUsername] = username
|
||||
SharedDefaults[.gitAuthenticationMethod] = auth
|
||||
SVProgressHUD.showSuccess(withStatus: "Done")
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self)
|
||||
SVProgressHUD.dismiss()
|
||||
let savePassphraseAlert = UIAlertController(title: "Done", message: "Do you want to save the Git credential password/passphrase?", preferredStyle: UIAlertControllerStyle.alert)
|
||||
// no
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
||||
SharedDefaults[.isRememberGitCredentialPassphraseOn] = false
|
||||
self.passwordStore.gitPassword = nil
|
||||
self.passwordStore.gitSSHPrivateKeyPassphrase = nil
|
||||
self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self)
|
||||
})
|
||||
// yes
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in
|
||||
SharedDefaults[.isRememberGitCredentialPassphraseOn] = true
|
||||
self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self)
|
||||
})
|
||||
self.present(savePassphraseAlert, animated: true, completion: nil)
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
|
|
@ -257,7 +271,7 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
case .http:
|
||||
message = "Please fill in the password of your Git account."
|
||||
case .ssh:
|
||||
message = "Please fill in the password of your SSH key."
|
||||
message = "Please fill in the passphrase of your SSH key."
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ class OTPScannerController: QRScannerController {
|
|||
|
||||
var scannedOTP: String?
|
||||
|
||||
@IBAction func pressCancel(_ sender: UIBarButtonItem) {
|
||||
navigationController?.popViewController(animated: true)
|
||||
}
|
||||
// MARK: - AVCaptureMetadataOutputObjectsDelegate Methods
|
||||
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
|
||||
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
|
|||
// no
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
||||
self.pgpPassphrase = nil
|
||||
SharedDefaults[.isRememberPassphraseOn] = false
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = false
|
||||
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||
})
|
||||
// yes
|
||||
|
|
@ -129,7 +129,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
|
|||
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||
self.pgpPassphrase = alert.textFields?.first?.text
|
||||
SharedDefaults[.isRememberPassphraseOn] = true
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = true
|
||||
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||
}))
|
||||
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class PGPKeySettingTableViewController: UITableViewController {
|
|||
// no
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
||||
self.pgpPassphrase = nil
|
||||
SharedDefaults[.isRememberPassphraseOn] = false
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = false
|
||||
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||
})
|
||||
// yes
|
||||
|
|
@ -54,7 +54,7 @@ class PGPKeySettingTableViewController: UITableViewController {
|
|||
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||
self.pgpPassphrase = alert.textFields?.first?.text
|
||||
SharedDefaults[.isRememberPassphraseOn] = true
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = true
|
||||
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||
}))
|
||||
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
||||
|
|
|
|||
|
|
@ -19,12 +19,6 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
private var shouldPopCurrentView = false
|
||||
private let passwordStore = PasswordStore.shared
|
||||
|
||||
private let indicator: UIActivityIndicatorView = {
|
||||
let indicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
|
||||
indicator.center = CGPoint(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height * 0.382)
|
||||
return indicator
|
||||
}()
|
||||
|
||||
private lazy var editUIBarButtonItem: UIBarButtonItem = {
|
||||
let uiBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(pressEdit(_:)))
|
||||
return uiBarButtonItem
|
||||
|
|
@ -85,10 +79,11 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
tableView.rowHeight = UITableViewAutomaticDimension
|
||||
tableView.estimatedRowHeight = 52
|
||||
|
||||
indicator.startAnimating()
|
||||
tableView.addSubview(indicator)
|
||||
editUIBarButtonItem.isEnabled = false
|
||||
navigationItem.rightBarButtonItem = editUIBarButtonItem
|
||||
if #available(iOS 11.0, *) {
|
||||
navigationItem.largeTitleDisplayMode = .never
|
||||
}
|
||||
|
||||
if let imageData = passwordEntity?.image {
|
||||
let image = UIImage(data: imageData as Data)
|
||||
|
|
@ -134,7 +129,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
self.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
let _ = sem.wait(timeout: DispatchTime.distantFuture)
|
||||
if SharedDefaults[.isRememberPassphraseOn] {
|
||||
if SharedDefaults[.isRememberPGPPassphraseOn] {
|
||||
self.passwordStore.pgpKeyPassphrase = passphrase
|
||||
}
|
||||
return passphrase
|
||||
|
|
@ -174,7 +169,6 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
|
||||
private func showPassword() {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
self?.indicator.stopAnimating()
|
||||
self?.setTableData()
|
||||
self?.tableView.reloadData()
|
||||
self?.editUIBarButtonItem.isEnabled = true
|
||||
|
|
@ -407,7 +401,11 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
}
|
||||
|
||||
func openLink() {
|
||||
guard let urlString = self.password?.getURLString(), let url = URL(string: urlString) else {
|
||||
var urlString = self.password?.getURLString() ?? ""
|
||||
if !urlString.lowercased().starts(with: "https://") && !urlString.lowercased().starts(with: "http://") {
|
||||
urlString = "http://\(urlString)"
|
||||
}
|
||||
guard let url = URL(string: urlString) else {
|
||||
DispatchQueue.main.async {
|
||||
Utils.alert(title: "Error", message: "Cannot find a valid URL", controller: self, completion: nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
self.tableView.sectionFooterHeight = UITableViewAutomaticDimension;
|
||||
self.tableView.estimatedSectionFooterHeight = 0;
|
||||
}
|
||||
override func viewDidLayoutSubviews() {
|
||||
additionsCell?.contentTextView.setContentOffset(.zero, animated: false)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cellData = tableData[indexPath.section][indexPath.row]
|
||||
|
|
@ -101,7 +104,7 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
let minimumLength = lengthSetting?.min ?? 0
|
||||
let maximumLength = lengthSetting?.max ?? 0
|
||||
var defaultLength = lengthSetting?.def ?? 0
|
||||
if let currentPasswordLength = (tableData[passwordSection][0][PasswordEditorCellKey.content] as? String)?.characters.count,
|
||||
if let currentPasswordLength = (tableData[passwordSection][0][PasswordEditorCellKey.content] as? String)?.count,
|
||||
currentPasswordLength >= minimumLength,
|
||||
currentPasswordLength <= maximumLength {
|
||||
defaultLength = currentPasswordLength
|
||||
|
|
@ -258,4 +261,45 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
tableData[additionsSection][0][PasswordEditorCellKey.content] = additionsCell?.getContent()
|
||||
}
|
||||
}
|
||||
|
||||
func getNameURL() -> (String, URL) {
|
||||
let encodedName = (nameCell?.getContent()?.stringByAddingPercentEncodingForRFC3986())!
|
||||
let name = URL(string: encodedName)!.lastPathComponent
|
||||
let url = URL(string: encodedName)!.appendingPathExtension("gpg")
|
||||
return (name, url)
|
||||
}
|
||||
|
||||
func checkName() -> Bool {
|
||||
// the name field should not be empty
|
||||
guard let name = nameCell?.getContent(), name.isEmpty == false else {
|
||||
Utils.alert(title: "Cannot Save", message: "Please fill in the name.", controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
|
||||
// the name should not start with /
|
||||
guard name.hasPrefix("/") == false else {
|
||||
Utils.alert(title: "Cannot Save", message: "Please remove the prefix \"/\" from your password name.", controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
|
||||
// the name field should be a valid url
|
||||
guard let path = name.stringByAddingPercentEncodingForRFC3986(),
|
||||
var passwordURL = URL(string: path) else {
|
||||
Utils.alert(title: "Cannot Save", message: "Password name is invalid.", controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
|
||||
// check whether we can parse the filename (be consistent with PasswordStore::addPasswordEntities)
|
||||
var previousPathLength = Int.max
|
||||
while passwordURL.path != "." {
|
||||
passwordURL = passwordURL.deletingLastPathComponent()
|
||||
if passwordURL.path != "." && passwordURL.path.count >= previousPathLength {
|
||||
Utils.alert(title: "Cannot Save", message: "Cannot parse the filename. Please check and simplify the password name.", controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
previousPathLength = passwordURL.path.count
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
uiSearchController.searchResultsUpdater = self
|
||||
uiSearchController.dimsBackgroundDuringPresentation = false
|
||||
uiSearchController.searchBar.isTranslucent = false
|
||||
uiSearchController.searchBar.backgroundColor = UIColor.gray
|
||||
uiSearchController.searchBar.sizeToFit()
|
||||
return uiSearchController
|
||||
}()
|
||||
|
|
@ -48,10 +47,13 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
syncControl.addTarget(self, action: #selector(handleRefresh(_:)), for: UIControlEvents.valueChanged)
|
||||
return syncControl
|
||||
}()
|
||||
private lazy var searchBarView: UIView = {
|
||||
let uiView = UIView(frame: CGRect(x: 0, y: 64, width: self.view.bounds.width, height: 56))
|
||||
uiView.addSubview(self.searchController.searchBar)
|
||||
return uiView
|
||||
private lazy var searchBarView: UIView? = {
|
||||
guard #available(iOS 11, *) else {
|
||||
let uiView = UIView(frame: CGRect(x: 0, y: 64, width: self.view.bounds.width, height: 56))
|
||||
uiView.addSubview(self.searchController.searchBar)
|
||||
return uiView
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
private lazy var backUIBarButtonItem: UIBarButtonItem = {
|
||||
let backUIBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(self.backAction(_:)))
|
||||
|
|
@ -172,8 +174,17 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
DispatchQueue.main.async {
|
||||
SVProgressHUD.dismiss()
|
||||
self.syncControl.endRefreshing()
|
||||
let error = error as NSError
|
||||
var message = error.localizedDescription
|
||||
if let underlyingError = error.userInfo[NSUnderlyingErrorKey] as? NSError {
|
||||
message = "\(message)\nUnderlying error: \(underlyingError.localizedDescription)"
|
||||
if underlyingError.localizedDescription.contains("Wrong passphrase") {
|
||||
message = "\(message)\nRecovery suggestion: Wrong credential password/passphrase has been removed, please try again."
|
||||
gitCredential.delete()
|
||||
}
|
||||
}
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(800)) {
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
Utils.alert(title: "Error", message: message, controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -192,14 +203,21 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
tabBarController!.delegate = self
|
||||
searchController.searchBar.delegate = self
|
||||
tableView.delegate = self
|
||||
tableView.dataSource = self
|
||||
tableView.contentInset = UIEdgeInsetsMake(56, 0, 0, 0)
|
||||
definesPresentationContext = true
|
||||
view.addSubview(searchBarView)
|
||||
if #available(iOS 11.0, *) {
|
||||
navigationItem.searchController = searchController
|
||||
navigationController?.navigationBar.prefersLargeTitles = true
|
||||
navigationItem.largeTitleDisplayMode = .automatic
|
||||
navigationItem.hidesSearchBarWhenScrolling = false
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
tableView.contentInset = UIEdgeInsetsMake(56, 0, 0, 0)
|
||||
view.addSubview(searchBarView!)
|
||||
}
|
||||
tableView.refreshControl = syncControl
|
||||
SVProgressHUD.setDefaultMaskType(.black)
|
||||
tableView.register(UINib(nibName: "PasswordWithFolderTableViewCell", bundle: nil), forCellReuseIdentifier: "passwordWithFolderTableViewCell")
|
||||
|
|
@ -223,8 +241,11 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
|
||||
override func viewWillLayoutSubviews() {
|
||||
super.viewWillLayoutSubviews()
|
||||
searchBarView.frame = CGRect(x: 0, y: navigationController!.navigationBar.bounds.size.height + UIApplication.shared.statusBarFrame.height, width: UIScreen.main.bounds.width, height: 56)
|
||||
searchController.searchBar.sizeToFit()
|
||||
guard #available(iOS 11, *) else {
|
||||
searchBarView?.frame = CGRect(x: 0, y: navigationController!.navigationBar.bounds.size.height + UIApplication.shared.statusBarFrame.height, width: UIScreen.main.bounds.width, height: 56)
|
||||
searchController.searchBar.sizeToFit()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func numberOfSections(in tableView: UITableView) -> Int {
|
||||
|
|
@ -242,18 +263,16 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
let cell = tableView.dequeueReusableCell(withIdentifier: "passwordTableViewCell", for: indexPath)
|
||||
|
||||
let entry = getPasswordEntry(by: indexPath)
|
||||
if entry.passwordEntity!.synced {
|
||||
cell.textLabel?.text = entry.title
|
||||
} else {
|
||||
cell.textLabel?.text = "↻ \(entry.title)"
|
||||
}
|
||||
if !entry.isDir {
|
||||
if entry.passwordEntity!.synced {
|
||||
cell.textLabel?.text = entry.title
|
||||
} else {
|
||||
cell.textLabel?.text = "↻ \(entry.title)"
|
||||
}
|
||||
|
||||
cell.addGestureRecognizer(longPressGestureRecognizer)
|
||||
cell.accessoryType = .none
|
||||
cell.detailTextLabel?.text = ""
|
||||
} else {
|
||||
cell.textLabel?.text = "\(entry.title)"
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
cell.detailTextLabel?.font = UIFont.preferredFont(forTextStyle: .body)
|
||||
cell.detailTextLabel?.text = "\(entry.passwordEntity?.children?.count ?? 0)"
|
||||
|
|
@ -351,7 +370,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
// bring back
|
||||
SVProgressHUD.show(withStatus: "Decrypting")
|
||||
}
|
||||
if SharedDefaults[.isRememberPassphraseOn] {
|
||||
if SharedDefaults[.isRememberPGPPassphraseOn] {
|
||||
self.passwordStore.pgpKeyPassphrase = passphrase
|
||||
}
|
||||
return passphrase
|
||||
|
|
@ -445,6 +464,14 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
let passwordEntity = getPasswordEntry(by: selectedIndexPath).passwordEntity!
|
||||
viewController.passwordEntity = passwordEntity
|
||||
}
|
||||
} else if segue.identifier == "addPasswordSegue" {
|
||||
if let navController = segue.destination as? UINavigationController {
|
||||
if let viewController = navController.topViewController as? AddPasswordTableViewController {
|
||||
if let path = parentPasswordEntity?.path {
|
||||
viewController.defaultDirPrefix = "\(path)/"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -478,16 +505,15 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
|
||||
private func reloadTableView(data: [PasswordsTableEntry], anim: CAAnimation? = nil) {
|
||||
// set navigation item
|
||||
var numberOfLocalCommitsString = ""
|
||||
let numberOfLocalCommits = self.passwordStore.numberOfLocalCommits()
|
||||
if numberOfLocalCommits > 0 {
|
||||
numberOfLocalCommitsString = " (\(numberOfLocalCommits))"
|
||||
if numberOfLocalCommits == 0 {
|
||||
navigationController?.tabBarItem.badgeValue = nil
|
||||
} else {
|
||||
navigationController?.tabBarItem.badgeValue = "\(numberOfLocalCommits)"
|
||||
}
|
||||
if parentPasswordEntity != nil {
|
||||
navigationItem.title = "\(parentPasswordEntity!.name!)\(numberOfLocalCommitsString)"
|
||||
navigationItem.leftBarButtonItem = backUIBarButtonItem
|
||||
} else {
|
||||
navigationItem.title = "Password Store\(numberOfLocalCommitsString)"
|
||||
navigationItem.leftBarButtonItem = nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
|
|||
|
||||
// Initialize the captureSession object.
|
||||
captureSession = AVCaptureSession()
|
||||
|
||||
|
||||
// Set the input device on the capture session.
|
||||
captureSession?.addInput(input)
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
|
|||
|
||||
// MARK: - AVCaptureMetadataOutputObjectsDelegate Methods
|
||||
|
||||
func metadataOutput(captureOutput: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
|
||||
func metadataOutput(_ captureOutput: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
|
||||
|
||||
if let metadataObj = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
|
||||
supportedCodeTypes.contains(metadataObj.type),
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class SettingsTableViewController: UITableViewController {
|
|||
if let controller = segue.source as? PGPKeySettingTableViewController {
|
||||
SharedDefaults[.pgpPrivateKeyURL] = URL(string: controller.pgpPrivateKeyURLTextField.text!)
|
||||
SharedDefaults[.pgpPublicKeyURL] = URL(string: controller.pgpPublicKeyURLTextField.text!)
|
||||
if SharedDefaults[.isRememberPassphraseOn] {
|
||||
if SharedDefaults[.isRememberPGPPassphraseOn] {
|
||||
self.passwordStore.pgpKeyPassphrase = controller.pgpPassphrase
|
||||
}
|
||||
SharedDefaults[.pgpKeySource] = "url"
|
||||
|
|
@ -61,7 +61,7 @@ class SettingsTableViewController: UITableViewController {
|
|||
|
||||
} else if let controller = segue.source as? PGPKeyArmorSettingTableViewController {
|
||||
SharedDefaults[.pgpKeySource] = "armor"
|
||||
if SharedDefaults[.isRememberPassphraseOn] {
|
||||
if SharedDefaults[.isRememberPGPPassphraseOn] {
|
||||
self.passwordStore.pgpKeyPassphrase = controller.pgpPassphrase
|
||||
}
|
||||
|
||||
|
|
@ -259,7 +259,7 @@ class SettingsTableViewController: UITableViewController {
|
|||
// no
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
||||
self.passwordStore.pgpKeyPassphrase = nil
|
||||
SharedDefaults[.isRememberPassphraseOn] = false
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = false
|
||||
self.saveImportedPGPKey()
|
||||
})
|
||||
// yes
|
||||
|
|
@ -268,7 +268,7 @@ class SettingsTableViewController: UITableViewController {
|
|||
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||
self.passwordStore.pgpKeyPassphrase = alert.textFields?.first?.text
|
||||
SharedDefaults[.isRememberPassphraseOn] = true
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = true
|
||||
self.saveImportedPGPKey()
|
||||
}))
|
||||
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef Objective_CBridgingHeader_h
|
||||
#define Objective_CBridgingHeader_h
|
||||
|
||||
// #import <ObjectivePGP/ObjectivePGP.h>
|
||||
#import <ObjectiveGit/ObjectiveGit.h>
|
||||
#import "ObjectivePGP/ObjectivePGP.h"
|
||||
#import "ObjectiveGit/ObjectiveGit.h"
|
||||
|
||||
#endif /* Objective_CBridgingHeader_h */
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.2.9</string>
|
||||
<string>0.3.0</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class FillPasswordTableViewCell: ContentTableViewCell {
|
|||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
// Initialization code
|
||||
contentTextField.font = UIFont(name: Globals.passwordFonts, size: (contentTextField.font?.pointSize)!)
|
||||
contentTextField.font = Globals.passwordFont
|
||||
|
||||
// Force aspect ratio of button images
|
||||
settingButton.imageView?.contentMode = .scaleAspectFit
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13173"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
|
|
@ -16,17 +16,14 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="320" height="90"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="90"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="89.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="19l-R0-gP1">
|
||||
<rect key="frame" x="15" y="11" width="290" height="68"/>
|
||||
<rect key="frame" x="8" y="11" width="304" height="68"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="password" textAlignment="natural" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="k0U-2N-YaX" userLabel="Password">
|
||||
<rect key="frame" x="0.0" y="0.0" width="230" height="68"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="9gX-VT-F9P"/>
|
||||
</constraints>
|
||||
<rect key="frame" x="0.0" y="0.0" width="244" height="68"/>
|
||||
<nil key="textColor"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="alphabet"/>
|
||||
|
|
@ -35,7 +32,7 @@
|
|||
</connections>
|
||||
</textField>
|
||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hTh-ek-Xam" userLabel="Generate">
|
||||
<rect key="frame" x="230" y="0.0" width="30" height="68"/>
|
||||
<rect key="frame" x="244" y="0.0" width="30" height="68"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="30" id="l0l-7B-Tws"/>
|
||||
</constraints>
|
||||
|
|
@ -46,7 +43,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SZJ-aY-45Y" userLabel="Setting">
|
||||
<rect key="frame" x="260" y="0.0" width="30" height="68"/>
|
||||
<rect key="frame" x="274" y="0.0" width="30" height="68"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="30" id="D9D-FC-ANz"/>
|
||||
</constraints>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class LabelTableViewCell: UITableViewCell {
|
|||
contentLabel.text = Globals.passwordDots
|
||||
}
|
||||
}
|
||||
contentLabel.font = UIFont(name: Globals.passwordFonts, size: contentLabel.font.pointSize)
|
||||
contentLabel.font = Globals.passwordFont
|
||||
case "hmac-based":
|
||||
type = .HOTP
|
||||
if isReveal {
|
||||
|
|
@ -59,7 +59,7 @@ class LabelTableViewCell: UITableViewCell {
|
|||
} else {
|
||||
contentLabel.text = Globals.oneTimePasswordDots
|
||||
}
|
||||
contentLabel.font = UIFont(name: Globals.passwordFonts, size: contentLabel.font.pointSize)
|
||||
contentLabel.font = Globals.passwordFont
|
||||
case "url":
|
||||
type = .URL
|
||||
contentLabel.text = content
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13173"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="333" height="59"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
||||
<rect key="frame" x="0.0" y="0.0" width="333" height="59"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="333" height="58.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="content" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yyr-cF-QN0">
|
||||
<rect key="frame" x="15" y="27" width="303" height="21"/>
|
||||
<rect key="frame" x="8" y="27" width="305" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="21" id="pgw-DF-LQa"/>
|
||||
</constraints>
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dqz-7n-uEZ">
|
||||
<rect key="frame" x="15" y="11" width="303" height="13"/>
|
||||
<rect key="frame" x="8" y="11" width="317" height="13"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
|
||||
<color key="textColor" red="0.0" green="0.47843137254901957" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
<constraint firstItem="Dqz-7n-uEZ" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" id="CVm-uc-iVo"/>
|
||||
<constraint firstAttribute="topMargin" secondItem="Dqz-7n-uEZ" secondAttribute="top" id="N4y-iT-CiY"/>
|
||||
<constraint firstItem="yyr-cF-QN0" firstAttribute="leading" secondItem="Dqz-7n-uEZ" secondAttribute="leading" id="TpW-bu-QIx"/>
|
||||
<constraint firstItem="yyr-cF-QN0" firstAttribute="width" secondItem="Dqz-7n-uEZ" secondAttribute="width" id="ZXa-fK-0Bg"/>
|
||||
<constraint firstAttribute="trailing" secondItem="yyr-cF-QN0" secondAttribute="trailing" constant="20" symbolic="YES" id="evr-4N-30Z"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="yyr-cF-QN0" secondAttribute="bottom" id="mIj-9c-ElE"/>
|
||||
<constraint firstItem="yyr-cF-QN0" firstAttribute="top" secondItem="Dqz-7n-uEZ" secondAttribute="bottom" constant="3" id="sgc-hN-i8t"/>
|
||||
</constraints>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12118" systemVersion="16F43c" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13173"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="8Ky-UZ-sLu">
|
||||
<rect key="frame" x="15" y="11" width="290" height="47"/>
|
||||
<rect key="frame" x="8" y="11" width="304" height="47"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="R1z-fU-Xr2"/>
|
||||
</constraints>
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
<constraint firstItem="8Ky-UZ-sLu" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" id="3h4-9E-oDJ"/>
|
||||
<constraint firstItem="8Ky-UZ-sLu" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="FH4-4T-aaK"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="8Ky-UZ-sLu" secondAttribute="trailing" id="Nii-Cg-gC1"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="8Ky-UZ-sLu" secondAttribute="bottom" id="h72-l3-Sb3"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="8Ky-UZ-sLu" secondAttribute="bottom" priority="750" id="h72-l3-Sb3"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12118" systemVersion="16F43c" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13173"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<customFonts key="customFonts">
|
||||
<array key="Menlo.ttc">
|
||||
<string>Menlo-Regular</string>
|
||||
</array>
|
||||
</customFonts>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
|
|
@ -20,7 +25,7 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xHX-Sh-1pR">
|
||||
<rect key="frame" x="15" y="11" width="290" height="195"/>
|
||||
<rect key="frame" x="8" y="11" width="304" height="195"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="120" id="Tvq-j8-Nvh"/>
|
||||
|
|
@ -32,7 +37,7 @@
|
|||
<constraints>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="xHX-Sh-1pR" secondAttribute="trailing" id="LWS-JW-9dS"/>
|
||||
<constraint firstItem="xHX-Sh-1pR" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" id="SRq-7t-Gyr"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="xHX-Sh-1pR" secondAttribute="bottom" id="UPQ-jk-QJR"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="xHX-Sh-1pR" secondAttribute="bottom" priority="750" id="UPQ-jk-QJR"/>
|
||||
<constraint firstItem="xHX-Sh-1pR" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="gwb-2C-4wp"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
|
|
|
|||
|
|
@ -143,6 +143,12 @@
|
|||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-App-1024@1x.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="QHc-XA-1MZ">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="QHc-XA-1MZ">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13174"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
<!--Password Store-->
|
||||
<scene sceneID="NlT-0d-7x9">
|
||||
<objects>
|
||||
<viewController id="DnC-Ka-AYb" customClass="ExtensionViewController" customModule="passextension" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<viewController id="DnC-Ka-AYb" customClass="ExtensionViewController" customModule="passExtension" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="TbF-II-itz"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="9b9-wt-KCV"/>
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="P9f-HJ-cS5">
|
||||
<rect key="frame" x="0.0" y="64" width="375" height="626"/>
|
||||
<subviews>
|
||||
<searchBar contentMode="redraw" showsCancelButton="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xuO-jY-YRU">
|
||||
<searchBar contentMode="redraw" translatesAutoresizingMaskIntoConstraints="NO" id="xuO-jY-YRU">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
</searchBar>
|
||||
|
|
@ -37,18 +37,18 @@
|
|||
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="T2b-vj-fza" id="aVb-V4-hqg">
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="44"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="LUo-8T-I4j">
|
||||
<rect key="frame" x="15" y="12" width="33" height="21"/>
|
||||
<rect key="frame" x="15" y="12" width="33.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="9ik-sy-sTS">
|
||||
<rect key="frame" x="296" y="12" width="44" height="21"/>
|
||||
<rect key="frame" x="296" y="12" width="44" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
|
|
@ -101,7 +101,7 @@
|
|||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="QHc-XA-1MZ" sceneMemberID="viewController">
|
||||
<toolbarItems/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="WRo-Vb-Kcg">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<nil name="viewControllers"/>
|
||||
|
|
|
|||
|
|
@ -12,10 +12,14 @@ import passKit
|
|||
|
||||
fileprivate class PasswordsTableEntry : NSObject {
|
||||
var title: String
|
||||
var categoryText: String
|
||||
var categoryArray: [String]
|
||||
var passwordEntity: PasswordEntity?
|
||||
init(title: String, passwordEntity: PasswordEntity?) {
|
||||
self.title = title
|
||||
self.passwordEntity = passwordEntity
|
||||
init(_ entity: PasswordEntity) {
|
||||
self.title = entity.name!
|
||||
self.categoryText = entity.getCategoryText()
|
||||
self.categoryArray = entity.getCategoryArray()
|
||||
self.passwordEntity = entity
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +50,7 @@ class ExtensionViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
var passwordEntities = [PasswordEntity]()
|
||||
passwordEntities = self.passwordStore.fetchPasswordEntityCoreData(withDir: false)
|
||||
passwordsTableEntries = passwordEntities.map {
|
||||
PasswordsTableEntry(title: $0.name!, passwordEntity: $0)
|
||||
PasswordsTableEntry($0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +145,7 @@ class ExtensionViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
}
|
||||
cell.accessoryType = .none
|
||||
cell.detailTextLabel?.font = UIFont.preferredFont(forTextStyle: .footnote)
|
||||
cell.detailTextLabel?.text = entry.passwordEntity?.getCategoryText()
|
||||
cell.detailTextLabel?.text = entry.categoryText
|
||||
return cell
|
||||
}
|
||||
|
||||
|
|
@ -223,7 +227,7 @@ class ExtensionViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
self.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
let _ = sem.wait(timeout: DispatchTime.distantFuture)
|
||||
if SharedDefaults[.isRememberPassphraseOn] {
|
||||
if SharedDefaults[.isRememberPGPPassphraseOn] {
|
||||
self.passwordStore.pgpKeyPassphrase = passphrase
|
||||
}
|
||||
return passphrase
|
||||
|
|
@ -241,10 +245,15 @@ class ExtensionViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
|
||||
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
|
||||
if let searchText = searchBar.text, searchText.isEmpty == false {
|
||||
let searchTextLowerCased = searchText.lowercased()
|
||||
filteredPasswordsTableEntries = passwordsTableEntries.filter { entry in
|
||||
let entryTitle = entry.title.lowercased()
|
||||
return entryTitle.contains(searchTextLowerCased) || searchTextLowerCased.contains(entryTitle)
|
||||
var matched = false
|
||||
matched = matched || entry.title.range(of: searchText, options: .caseInsensitive) != nil
|
||||
matched = matched || searchText.range(of: entry.title, options: .caseInsensitive) != nil
|
||||
entry.categoryArray.forEach({ (category) in
|
||||
matched = matched || category.range(of: searchText, options: .caseInsensitive) != nil
|
||||
matched = matched || searchText.range(of: category, options: .caseInsensitive) != nil
|
||||
})
|
||||
return matched
|
||||
}
|
||||
searchActive = true
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.2.9</string>
|
||||
<string>0.3.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ public enum AppError: Error {
|
|||
case PasswordDuplicatedError
|
||||
case GitResetError
|
||||
case PGPPublicKeyNotExistError
|
||||
case WrongPasswordFilename
|
||||
case UnknownError
|
||||
}
|
||||
|
||||
|
|
@ -33,6 +34,8 @@ extension AppError: LocalizedError {
|
|||
return "Cannot identify the latest synced commit."
|
||||
case .PGPPublicKeyNotExistError:
|
||||
return "PGP public key doesn't exist."
|
||||
case .WrongPasswordFilename:
|
||||
return "Cannot write to the password file."
|
||||
case .UnknownError:
|
||||
return "Unknown error."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ public extension DefaultsKeys {
|
|||
|
||||
static let isHideUnknownOn = DefaultsKey<Bool>("isHideUnknownOn")
|
||||
static let isHideOTPOn = DefaultsKey<Bool>("isHideOTPOn")
|
||||
static let isRememberPassphraseOn = DefaultsKey<Bool>("isRememberPassphraseOn")
|
||||
static let isRememberPGPPassphraseOn = DefaultsKey<Bool>("isRememberPGPPassphraseOn")
|
||||
static let isRememberGitCredentialPassphraseOn = DefaultsKey<Bool>("isRememberGitCredentialPassphraseOn")
|
||||
static let isShowFolderOn = DefaultsKey<Bool>("isShowFolderOn")
|
||||
static let passwordGeneratorFlavor = DefaultsKey<String>("passwordGeneratorFlavor")
|
||||
|
||||
|
|
|
|||
|
|
@ -47,11 +47,14 @@ public class Globals {
|
|||
|
||||
public static let passwordDots = "••••••••••••"
|
||||
public static let oneTimePasswordDots = "••••••"
|
||||
public static let passwordFonts = "Menlo"
|
||||
public static let passwordFont = UIFont(name: "Courier-Bold", size: UIFont.labelFontSize - 1)
|
||||
|
||||
// UI related
|
||||
public static let red = UIColor(red:1.00, green:0.23, blue:0.19, alpha:1.0)
|
||||
public static let blue = UIColor(red:0.00, green:0.48, blue:1.00, alpha:1.0)
|
||||
public static let letterColor = UIColor(red:40/255.0, green:42/255.0, blue:54/255.0, alpha:1.0)
|
||||
public static let symbolColor = UIColor(red:200/255.0, green:40/255.0, blue:41/255.0, alpha:1.0)
|
||||
public static let digitColor = UIColor(red:66/255.0, green:113/255.0, blue:174/255.0, alpha:1.0)
|
||||
public static let tableCellButtonSize = CGFloat(20.0)
|
||||
|
||||
private init() { }
|
||||
|
|
|
|||
|
|
@ -107,9 +107,11 @@ public class Utils {
|
|||
for (index, element) in plainPassword.unicodeScalars.enumerated() {
|
||||
var charColor = UIColor.darkText
|
||||
if NSCharacterSet.decimalDigits.contains(element) {
|
||||
charColor = Globals.red
|
||||
charColor = Globals.digitColor
|
||||
} else if !NSCharacterSet.letters.contains(element) {
|
||||
charColor = Globals.blue
|
||||
charColor = Globals.symbolColor
|
||||
} else {
|
||||
charColor = Globals.letterColor
|
||||
}
|
||||
attributedPassword.addAttribute(NSAttributedStringKey.foregroundColor, value: charColor, range: NSRange(location: index, length: 1))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<string>0.3.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
|
|
|||
|
|
@ -26,38 +26,39 @@ public struct GitCredential {
|
|||
|
||||
public func credentialProvider(requestGitPassword: @escaping (Credential, String?) -> String?) throws -> GTCredentialProvider {
|
||||
var attempts = 0
|
||||
var lastPassword: String? = nil
|
||||
return GTCredentialProvider { (_, _, _) -> (GTCredential?) in
|
||||
var credential: GTCredential? = nil
|
||||
|
||||
switch self.credential {
|
||||
case let .http(userName):
|
||||
var newPassword = self.passwordStore.gitPassword
|
||||
if newPassword == nil || attempts != 0 {
|
||||
var lastPassword = self.passwordStore.gitPassword
|
||||
if lastPassword == nil || attempts != 0 {
|
||||
if let requestedPassword = requestGitPassword(self.credential, lastPassword) {
|
||||
newPassword = requestedPassword
|
||||
self.passwordStore.gitPassword = newPassword
|
||||
if SharedDefaults[.isRememberGitCredentialPassphraseOn] {
|
||||
self.passwordStore.gitPassword = requestedPassword
|
||||
}
|
||||
lastPassword = requestedPassword
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
attempts += 1
|
||||
lastPassword = newPassword
|
||||
credential = try? GTCredential(userName: userName, password: newPassword!)
|
||||
credential = try? GTCredential(userName: userName, password: lastPassword!)
|
||||
case let .ssh(userName, privateKeyFile):
|
||||
// remarks: in fact, attempts > 1 never happens even with the wrong passphrase
|
||||
var newPassword = self.passwordStore.gitSSHPrivateKeyPassphrase
|
||||
if newPassword == nil || attempts != 0 {
|
||||
var lastPassword = self.passwordStore.gitSSHPrivateKeyPassphrase
|
||||
if lastPassword == nil || attempts != 0 {
|
||||
if let requestedPassword = requestGitPassword(self.credential, lastPassword) {
|
||||
newPassword = requestedPassword
|
||||
self.passwordStore.gitSSHPrivateKeyPassphrase = newPassword
|
||||
if SharedDefaults[.isRememberGitCredentialPassphraseOn] {
|
||||
self.passwordStore.gitSSHPrivateKeyPassphrase = requestedPassword
|
||||
}
|
||||
lastPassword = requestedPassword
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
attempts += 1
|
||||
lastPassword = newPassword
|
||||
credential = try? GTCredential(userName: userName, publicKeyURL: nil, privateKeyURL: privateKeyFile, passphrase: newPassword!)
|
||||
credential = try? GTCredential(userName: userName, publicKeyURL: nil, privateKeyURL: privateKeyFile, passphrase: lastPassword!)
|
||||
}
|
||||
return credential
|
||||
}
|
||||
|
|
@ -66,9 +67,9 @@ public struct GitCredential {
|
|||
public func delete() {
|
||||
switch credential {
|
||||
case .http:
|
||||
Utils.removeKeychain(name: "gitPassword")
|
||||
self.passwordStore.gitPassword = nil
|
||||
case .ssh:
|
||||
Utils.removeKeychain(name: "gitSSHKeyPassphrase")
|
||||
self.passwordStore.gitSSHPrivateKeyPassphrase = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public class Password {
|
|||
additions.removeAll()
|
||||
|
||||
// split the plain text
|
||||
let plainTextSplit = plainText.characters.split(maxSplits: 1, omittingEmptySubsequences: false) {
|
||||
let plainTextSplit = plainText.split(maxSplits: 1, omittingEmptySubsequences: false) {
|
||||
$0 == "\n" || $0 == "\r\n"
|
||||
}.map(String.init)
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ public class Password {
|
|||
|
||||
public func getAdditionsPlainText() -> String {
|
||||
// lines starting from the second
|
||||
let plainTextSplit = plainText.characters.split(maxSplits: 1, omittingEmptySubsequences: false) {
|
||||
let plainTextSplit = plainText.split(maxSplits: 1, omittingEmptySubsequences: false) {
|
||||
$0 == "\n" || $0 == "\r\n"
|
||||
}.map(String.init)
|
||||
if plainTextSplit.count == 1 {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,10 @@ extension PasswordEntity {
|
|||
}
|
||||
|
||||
public func getCategoryText() -> String {
|
||||
return getCategoryArray().joined(separator: " > ")
|
||||
}
|
||||
|
||||
public func getCategoryArray() -> [String] {
|
||||
var parentEntity = parent
|
||||
var passwordCategoryArray: [String] = []
|
||||
while parentEntity != nil {
|
||||
|
|
@ -29,7 +33,7 @@ extension PasswordEntity {
|
|||
parentEntity = parentEntity!.parent
|
||||
}
|
||||
passwordCategoryArray.reverse()
|
||||
return passwordCategoryArray.joined(separator: " > ")
|
||||
return passwordCategoryArray
|
||||
}
|
||||
|
||||
public func getURL() -> URL? {
|
||||
|
|
|
|||
|
|
@ -21,16 +21,16 @@ public class PasswordStore {
|
|||
|
||||
public var storeRepository: GTRepository?
|
||||
public var pgpKeyID: String?
|
||||
public var publicKey: PGPKey? {
|
||||
public var publicKey: Key? {
|
||||
didSet {
|
||||
if publicKey != nil {
|
||||
pgpKeyID = publicKey!.keyID.shortKeyString
|
||||
pgpKeyID = publicKey!.keyID.shortIdentifier
|
||||
} else {
|
||||
pgpKeyID = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
public var privateKey: PGPKey?
|
||||
public var privateKey: Key?
|
||||
|
||||
public var gitSignatureForNow: GTSignature {
|
||||
get {
|
||||
|
|
@ -120,6 +120,7 @@ public class PasswordStore {
|
|||
print(Globals.documentPathLegacy)
|
||||
print(Globals.libraryPathLegacy)
|
||||
migrateIfNeeded()
|
||||
backwardCompatibility()
|
||||
|
||||
do {
|
||||
if fm.fileExists(atPath: storeURL.path) {
|
||||
|
|
@ -166,6 +167,17 @@ public class PasswordStore {
|
|||
updatePasswordEntityCoreData()
|
||||
}
|
||||
|
||||
private func backwardCompatibility() {
|
||||
// For the newly-introduced isRememberGitCredentialPassphraseOn (20171008)
|
||||
if (self.gitPassword != nil || self.gitSSHPrivateKeyPassphrase != nil) && SharedDefaults[.isRememberGitCredentialPassphraseOn] == false {
|
||||
SharedDefaults[.isRememberGitCredentialPassphraseOn] = true
|
||||
}
|
||||
// For the renamed isRememberPGPPassphraseOn (20171008)
|
||||
if self.pgpKeyPassphrase != nil && SharedDefaults[.isRememberPGPPassphraseOn] == false {
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = true
|
||||
}
|
||||
}
|
||||
|
||||
enum SSHKeyType {
|
||||
case `public`, secret
|
||||
}
|
||||
|
|
@ -223,9 +235,10 @@ public class PasswordStore {
|
|||
}
|
||||
|
||||
|
||||
private func importKey(from keyPath: String) -> PGPKey? {
|
||||
private func importKey(from keyPath: String) -> Key? {
|
||||
if fm.fileExists(atPath: keyPath) {
|
||||
let keys = pgp.importKeys(fromFile: keyPath)
|
||||
let keys = ObjectivePGP.readKeys(from: keyPath)
|
||||
pgp.import(keys: keys)
|
||||
if !keys.isEmpty {
|
||||
return keys.first
|
||||
}
|
||||
|
|
@ -233,7 +246,7 @@ public class PasswordStore {
|
|||
return nil
|
||||
}
|
||||
|
||||
public func getPgpPrivateKey() -> PGPKey {
|
||||
public func getPgpPrivateKey() -> Key {
|
||||
return pgp.keys.filter({$0.secretKey != nil})[0]
|
||||
}
|
||||
|
||||
|
|
@ -328,7 +341,6 @@ public class PasswordStore {
|
|||
let remote = try GTRemote(name: "origin", in: storeRepository)
|
||||
try storeRepository.pull(storeRepository.currentBranch(), from: remote, withOptions: options, progress: transferProgressBlock)
|
||||
} catch {
|
||||
credential.delete()
|
||||
throw(error)
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
|
|
@ -459,17 +471,6 @@ public class PasswordStore {
|
|||
}
|
||||
}
|
||||
|
||||
public func getNumberOfUnsyncedPasswords() -> Int {
|
||||
let passwordEntityFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "PasswordEntity")
|
||||
do {
|
||||
passwordEntityFetchRequest.predicate = NSPredicate(format: "synced = %i", 0)
|
||||
return try context.count(for: passwordEntityFetchRequest)
|
||||
} catch {
|
||||
fatalError("Failed to fetch unsynced passwords: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public func getLatestUpdateInfo(filename: String) -> String {
|
||||
guard let storeRepository = storeRepository else {
|
||||
return "Unknown"
|
||||
|
|
@ -581,7 +582,6 @@ public class PasswordStore {
|
|||
try storeRepository.push(masterBranch, to: remote, withOptions: options, progress: transferProgressBlock)
|
||||
}
|
||||
} catch {
|
||||
credential.delete()
|
||||
throw(error)
|
||||
}
|
||||
}
|
||||
|
|
@ -592,18 +592,26 @@ public class PasswordStore {
|
|||
}
|
||||
|
||||
var passwordURL = password.url!
|
||||
var previousPathLength = Int.max
|
||||
var paths: [String] = []
|
||||
while passwordURL.path != "." {
|
||||
paths.append(passwordURL.path)
|
||||
passwordURL = passwordURL.deletingLastPathComponent()
|
||||
// better identify errors before saving a new password
|
||||
if passwordURL.path != "." && passwordURL.path.count >= previousPathLength {
|
||||
throw AppError.WrongPasswordFilename
|
||||
}
|
||||
previousPathLength = passwordURL.path.count
|
||||
}
|
||||
paths.reverse()
|
||||
print(paths)
|
||||
var parentPasswordEntity: PasswordEntity? = nil
|
||||
for path in paths {
|
||||
let isDir = !path.hasSuffix(".gpg")
|
||||
if let passwordEntity = getPasswordEntity(by: path, isDir: isDir) {
|
||||
print(passwordEntity.path!)
|
||||
parentPasswordEntity = passwordEntity
|
||||
passwordEntity.synced = false
|
||||
} else {
|
||||
if !isDir {
|
||||
return insertPasswordEntity(name: URL(string: path.stringByAddingPercentEncodingForRFC3986()!)!.deletingPathExtension().lastPathComponent, path: path, parent: parentPasswordEntity, synced: false, isDir: false)
|
||||
|
|
@ -661,8 +669,9 @@ public class PasswordStore {
|
|||
let saveURL = storeURL.appendingPathComponent(passwordEntity.getURL()!.path)
|
||||
try self.encrypt(password: password).write(to: saveURL)
|
||||
try gitAdd(path: passwordEntity.getURL()!.path)
|
||||
let _ = try gitCommit(message: "Edit password for \(passwordEntity.getURL()!.deletingPathExtension().path.removingPercentEncoding!) to store using Pass for iOS.")
|
||||
let _ = try gitCommit(message: "Edit password for \(passwordEntity.getURL()!.deletingPathExtension().path.removingPercentEncoding!) using Pass for iOS.")
|
||||
newPasswordEntity = passwordEntity
|
||||
newPasswordEntity?.synced = false
|
||||
}
|
||||
|
||||
if password.changed&PasswordChange.path.rawValue != 0 {
|
||||
|
|
@ -831,7 +840,7 @@ public class PasswordStore {
|
|||
if passphrase == nil {
|
||||
passphrase = requestPGPKeyPassphrase()
|
||||
}
|
||||
let decryptedData = try PasswordStore.shared.pgp.decryptData(encryptedData, passphrase: passphrase)
|
||||
let decryptedData = try PasswordStore.shared.pgp.decrypt(encryptedData, passphrase: passphrase)
|
||||
let plainText = String(data: decryptedData, encoding: .utf8) ?? ""
|
||||
let escapedPath = passwordEntity.path!.stringByAddingPercentEncodingForRFC3986() ?? ""
|
||||
return Password(name: passwordEntity.name!, url: URL(string: escapedPath), plainText: plainText)
|
||||
|
|
@ -843,7 +852,7 @@ public class PasswordStore {
|
|||
throw AppError.PGPPublicKeyNotExistError
|
||||
}
|
||||
let plainData = password.getPlainData()
|
||||
let encryptedData = try pgp.encryptData(plainData, using: Array(publicKey), armored: SharedDefaults[.encryptInArmored])
|
||||
let encryptedData = try pgp.encrypt(plainData, using: Array(publicKey), armored: SharedDefaults[.encryptInArmored])
|
||||
return encryptedData
|
||||
}
|
||||
|
||||
|
|
@ -865,7 +874,7 @@ public class PasswordStore {
|
|||
Utils.removeFileIfExists(atPath: Globals.gitSSHPrivateKeyPath)
|
||||
Defaults.remove(.gitSSHPrivateKeyArmor)
|
||||
Defaults.remove(.gitSSHPrivateKeyURL)
|
||||
Utils.removeKeychain(name: ".gitSSHPrivateKeyPassphrase")
|
||||
self.gitSSHPrivateKeyPassphrase = nil
|
||||
}
|
||||
|
||||
public func gitSSHKeyExists(inFileSharing: Bool = false) -> Bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue