on b5b21d6 help sign in
.github/FUNDING.ymldeleted−1
since splitsnapshots
unifiedsplit
@@ -1 +0,0 @@
1−custom: ["https://iko.soy/donate"]
.github/workflows/build.yamldeleted−97
@@ -1,97 +0,0 @@
1−name: CI
2−
3−on:
4− push:
5− branches: ["master"]
6− pull_request:
7− branches: ["master"]
8− release:
9− types: [prereleased]
10−
11−jobs:
12− build:
13− runs-on: ubuntu-latest
14−
15− steps:
16− - uses: cachix/install-nix-action@v19
17−
18− - name: Cachix
19− uses: cachix/cachix-action@v12
20− with:
21− name: iko
22− authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
23−
24− - uses: actions/checkout@v3
25− with:
26− submodules: recursive
27−
28− - name: Install clickable
29− run: |
30− docker --version
31− sudo apt install adb git python3 python3-pip python3-setuptools
32− pip3 install --user clickable-ut==7.10.0 --upgrade
33− echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.bashrc
34−
35− - name: Build artifacts
36− run: ./dev/build.sh
37−
38− - name: Build Warden
39− run: clickable build --output click
40−
41− - uses: actions/upload-artifact@v3
42− with:
43− name: click
44− path: click/*
45−
46− - uses: actions/upload-artifact@v3
47− with:
48− name: dist
49− path: dist
50−
51− # Tests
52−
53− - uses: actions/setup-node@v3
54− with:
55− node-version: 16
56−
57− - name: Install test dependencies
58− working-directory: tests
59− run: |
60− npm ci
61− npx playwright install --with-deps
62−
63− - name: Run tests
64− working-directory: tests
65− run: npx playwright test
66−
67− - uses: actions/upload-artifact@v3
68− if: always()
69− with:
70− name: playwright-report
71− path: tests/playwright-report/
72−
73− # Upload release
74−
75− - name: Zip Release Assets
76− if: github.event_name == 'release'
77− shell: bash
78− run: |
79− cd dist/
80− zip -r ../../../../dist.zip .
81−
82− - name: Upload dist to release
83− if: github.event_name == 'release'
84− uses: svenstaro/upload-release-action@2.4.1
85− with:
86− repo_token: ${{ secrets.GITHUB_TOKEN }}
87− file: dist.zip
88− tag: ${{ github.ref }}
89−
90− - name: Upload click to release
91− if: github.event_name == 'release'
92− uses: svenstaro/upload-release-action@2.4.1
93− with:
94− repo_token: ${{ secrets.GITHUB_TOKEN }}
95− file: build/all/app/*.click
96− tag: ${{ github.ref }}
97− file_glob: true
.gitignore+1−12
@@ -7,16 +7,5 @@ static/backend.js
7.spago
7.spago
8output
8output
9.psc-ide-port
9.psc-ide-port
10−elm.js
11−output-es
12−elm-stuff
13−node_modules/
14−/tests/test-results/
15−/tests/playwright-report/
16−/tests/playwright/.cache/
17−generated-docs
18−backend.js.map
19−.spago2nix
20backend.js
10backend.js
21−vanilla
11+elm.js
22−dist
.gitmodulesnew file+6
@@ -0,0 +1,6 @@
1+[submodule "deps/bw"]
2+ path = deps/bw
3+ url = https://github.com/bitwarden/clients.git
4+[submodule "vanilla"]
5+ path = vanilla
6+ url = https://github.com/ilyakooo0/vanilla-compiled.git
.helix/languages.tomldeleted−3
@@ -1,3 +0,0 @@
1−[[language]]
2−name = "nix"
3−auto-format = true
.vscode/tasks.jsondeleted−31
@@ -1,31 +0,0 @@
1−{
2− // See https://go.microsoft.com/fwlink/?LinkId=733558
3− // for the documentation about the tasks.json format
4− "version": "2.0.0",
5− "tasks": [
6− {
7− "label": "Generate bridge",
8− "type": "process",
9− "command": "${workspaceFolder}/dev/generate-bridge.sh",
10− "problemMatcher": []
11− },
12− {
13− "label": "Build backend",
14− "type": "process",
15− "command": "${workspaceFolder}/dev/build-backend.sh",
16− "problemMatcher": []
17− },
18− {
19− "label": "Start Chrome",
20− "type": "process",
21− "command": "${workspaceFolder}/dev/start-chrome.sh",
22− "problemMatcher": []
23− },
24− {
25− "label": "Start Elm-live",
26− "type": "process",
27− "command": "${workspaceFolder}/dev/elm-live.sh",
28− "problemMatcher": []
29− }
30− ]
31−}
README.md+8−32
@@ -1,38 +1,14 @@
1−<p align="center">
1+# App Title
2− <img src="logo.png" style="width: 100px;" />
3−</p>
4
2
5−<h1 align="center">Warden</h1>
3+A short description of your app
6
4
7−<p align="center">
5+## License
8− <a href="https://open-store.io/app/soy.iko.warden"><img src="https://open-store.io/badges/en_US.svg" alt="OpenStore" style="width: 150px;" /></a>
9−</p>
10
6
7+Copyright (C) 2022 Your FullName
11
8
12−<p align="center">
9+This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published
13− <img src="screenshots/1.png" style="width: 150px;" />
10+by the Free Software Foundation.
14− <img src="screenshots/2.png" style="width: 150px;" />
15− <img src="screenshots/3.png" style="width: 150px;" />
16− <img src="screenshots/4.png" style="width: 150px;" />
17− <img src="screenshots/5.png" style="width: 150px;" />
18−</p>
19
11
20−Warden is a [Bitwarden](https://bitwarden.com)/[Vaultwarden](https://github.com/dani-garcia/vaultwarden) client for [Ubuntu Touch](https://ubuntu-touch.io).
12+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
21
13
22−## Features
14+You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
23−
24−1. View and edit: passwords, contact, secure notes and credit cards
25−2. Generate passwords
26−
27−## Support the project
28−
29−I fund the development of Warden out of my own pocket. If you find the project useful and don't want it to die, please consider donating what you think the app is worth to you.
30−
31−<p align="center">
32− <a href="https://iko.soy/donate"><img src="img/donate.png" alt="Donate" style="width: 150px;" /></a>
33−</p>
34−
35−
36−## Porting
37−
38−Although Warden is intended for ubuntu touch it is written completely in web technologies. This means that, if there is demand, the app can be ported to virtually any platform. The biggest problem will be [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).
warden.apparmor → appname.apparmorrenamed+1−1
@@ -5,5 +5,5 @@
5 "audio",
5 "audio",
6 "networking"
6 "networking"
7 ],
7 ],
8− "policy_version": 20.04
8+ "policy_version": 16.04
9}
9}
warden.desktop → appname.desktoprenamed

The content is the same.

backend-main.jsdeleted−3
@@ -1,3 +0,0 @@
1−import * as Main from "./backend/Main/index.js"
2−
3−Main.main()
backend/BW.js+50−64
@@ -1,29 +1,21 @@
1−import { StateFactory } from "../../bw/factories/stateFactory";
1+import { StateFactory } from "../../deps/bw/libs/shared/dist/src/factories/stateFactory";
2−import { GlobalState } from "../../bw/models/domain/global-state";
2+import { GlobalState } from "../../deps/bw/libs/shared/dist/src/models/domain/globalState";
3−import { ApiService } from "../../bw/services/api.service";
3+import { ApiService } from "../../deps/bw/libs/shared/dist/src/services/api.service";
4−import { AppIdService } from "../../bw/services/appId.service";
4+import { AppIdService } from "../../deps/bw/libs/shared/dist/src/services/appId.service";
5−import { ConsoleLogService } from "../../bw/services/consoleLog.service";
5+import { ConsoleLogService } from "../../deps/bw/libs/shared/dist/src/services/consoleLog.service";
6−import { EnvironmentService } from "../../bw/services/environment.service";
6+import { EnvironmentService } from "../../deps/bw/libs/shared/dist/src/services/environment.service";
7−import { StateMigrationService } from "../../bw/services/stateMigration.service";
7+import { StateMigrationService } from "../../deps/bw/libs/shared/dist/src/services/stateMigration.service";
8−import { TokenService } from "../../bw/services/token.service";
8+import { TokenService } from "../../deps/bw/libs/shared/dist/src/services/token.service";
9−import { WebCryptoFunctionService } from "../../bw/services/webCryptoFunction.service";
9+import { WebCryptoFunctionService } from "../../deps/bw/libs/shared/dist/src/services/webCryptoFunction.service";
10−import { Account, AccountProfile, AccountTokens } from "../../bw/models/domain/account";
10+import { Account, AccountProfile, AccountTokens } from "../../deps/bw/libs/shared/dist/src/models/domain/account";
11−import {MemoryStorageService} from "../../bw/services/memoryStorage.service"
11+
12−
13−// import BrowserStorageService from "../../../../bw/services/browserStorage.service";
12+// import BrowserStorageService from "../../../../deps/bw/libs/shared/dist/src/services/browserStorage.service";
14−import { CryptoService } from "../../bw/services/crypto.service";
13+import { CryptoService } from "../../deps/bw/libs/shared/dist/src/services/crypto.service";
15−
14+
16−import { I18nService } from "../../bw/services/i18n.service";
15+import { I18nService } from "../../deps/bw/libs/shared/dist/src/services/i18n.service";
17−import { StateService as BaseStateService } from "../../bw/services/state.service";
16+import { StateService as BaseStateService } from "../../deps/bw/libs/shared/dist/src/services/state.service";
18−import { PasswordTokenRequest } from "../../bw/models/request/identity-token/password-token.request";
17+import { PasswordTokenRequest } from "../../deps/bw/libs/shared/dist/src/models/request/identityToken/passwordTokenRequest";
19−import { TokenTwoFactorRequest} from "../../bw/models/request/identity-token/token-two-factor.request";
18+import { TokenRequestTwoFactor } from "../../deps/bw/libs/common/src/models/request/identityToken/tokenRequestTwoFactor.ts";
20−import { CipherRequest } from "../../bw/vault/models/request/cipher.request";
21−import { CipherCreateRequest } from "../../bw/vault/models/request/cipher-create.request";
22−import { Cipher } from "../../bw/vault/models/domain/cipher";
23−import { CipherData } from "../../bw/vault/models/data/cipher.data";
24−import { PasswordGenerationService } from "../../bw/services/passwordGeneration.service";
25−import { TotpService } from "../../bw/services/totp.service"
26−import { EncryptServiceImplementation } from "../../bw/services/cryptography/encrypt.service.implementation"
27
19
28function sanitize(obj) {
20function sanitize(obj) {
29 return JSON.parse(JSON.stringify(obj));
21 return JSON.parse(JSON.stringify(obj));
@@ -38,7 +30,7 @@ export function getServices() {
38
30
39 await bg.bootstrap()
31 await bg.bootstrap()
40
32
41− await bg.environmentService.setUrls(urls)
33+ bg.environmentService.setUrls(urls)
42
34
43 if (tokenResponse != null) {
35 if (tokenResponse != null) {
44 const accountInformation = await bg.tokenService.decodeToken(tokenResponse.accessToken);
36 const accountInformation = await bg.tokenService.decodeToken(tokenResponse.accessToken);
@@ -75,36 +67,18 @@ export function getServices() {
75 req.email,
67 req.email,
76 req.masterPasswordHash,
68 req.masterPasswordHash,
77 req.captchaResponse,
69 req.captchaResponse,
78− new TokenTwoFactorRequest(
79− req.twoFactor.provider,
80− req.twoFactor.token,
81− req.twoFactor.remember
70+ new TokenRequestTwoFactor(req.twoFactor),
82− ),
83 req.device
71 req.device
84 )
72 )
85 ),
73 ),
86 getSync: () => api.getSync().then(sanitize),
74 getSync: () => api.getSync().then(sanitize),
87− postCipherCreate: (cipher) => api.postCipherCreate(makeCipherCreateRequest(cipher)),
88− putCipher: (cipher) => api.putCipher(cipher.id, makeCipherRequest(cipher)),
89− deleteCipher: (id) => api.deleteCipher(id),
90− postTwoFactorEmail: (req) => api.postTwoFactorEmail(req),
91 }
75 }
92 },
76 },
93 crypto: bg.cryptoService,
77 crypto: bg.cryptoService,
94− cryptoFunctions: bg.cryptoFunctionService,
78+ cryptoFunctions: bg.cryptoFunctionService
95− passwordGeneration: bg.passwordGenerationService,
96− totpService: bg.totpService,
97 }
79 }
98}
80}
99
81
100−function makeCipherRequest(cipher) {
101− return new CipherRequest(new Cipher(new CipherData(cipher)))
102−}
103−
104−function makeCipherCreateRequest(cipher) {
105− return new CipherCreateRequest(new Cipher(new CipherData(cipher)))
106−}
107−
108class MainBackground {
82class MainBackground {
109 // messagingService; //: MessagingServiceAbstraction;
83 // messagingService; //: MessagingServiceAbstraction;
110 // storageService; //: StorageServiceAbstraction;
84 // storageService; //: StorageServiceAbstraction;
@@ -133,7 +107,6 @@ class MainBackground {
133 new StateFactory(GlobalState, Account)
107 new StateFactory(GlobalState, Account)
134 );
108 );
135 this.stateService = new StateService(
109 this.stateService = new StateService(
136− this.storageService,
137 this.storageService,
110 this.storageService,
138 this.storageService,
111 this.storageService,
139 this.logService,
112 this.logService,
@@ -164,13 +137,8 @@ class MainBackground {
164 );
137 );
165 this.i18nService = new I18nService("en");
138 this.i18nService = new I18nService("en");
166 this.cryptoFunctionService = new WebCryptoFunctionService(window);
139 this.cryptoFunctionService = new WebCryptoFunctionService(window);
167− this.encryptService = new EncryptServiceImplementation(
168− this.cryptoFunctionService,
169− this.logService
170− );
171 this.cryptoService = new BrowserCryptoService(
140 this.cryptoService = new BrowserCryptoService(
172 this.cryptoFunctionService,
141 this.cryptoFunctionService,
173− this.encryptService,
174 this.platformUtilsService,
142 this.platformUtilsService,
175 this.logService,
143 this.logService,
176 this.stateService
144 this.stateService
@@ -185,16 +153,6 @@ class MainBackground {
185 this.appIdService,
153 this.appIdService,
186 (expired) => this.logout(expired)
154 (expired) => this.logout(expired)
187 );
155 );
188− this.passwordGenerationService = new PasswordGenerationService(
189− this.cryptoService,
190− this.policyService,
191− this.stateService
192− );
193− this.totpService = new TotpService(
194− this.cryptoFunctionService,
195− this.logService,
196− this.stateService
197− );
198 }
156 }
199
157
200 async bootstrap() {
158 async bootstrap() {
@@ -214,6 +172,34 @@ class MainBackground {
214 }
172 }
215}
173}
216
174
175+class MemoryStorageService {
176+
177+ constructor() {
178+ this.storage = {};
179+ }
180+
181+ async get(key) {
182+ return this.storage[key]
183+ }
184+
185+ async has(key) {
186+ return key in this.storage;
187+ }
188+
189+ async save(key, obj) {
190+ if (obj == null) {
191+ this.remove(key)
192+ return
193+ }
194+
195+ this.storage[key] = obj
196+ }
197+
198+ async remove(key) {
199+ delete this.storage[key]
200+ }
201+}
202+
217class BrowserCryptoService extends CryptoService {
203class BrowserCryptoService extends CryptoService {
218 async retrieveKeyFromStorage(keySuffix) {
204 async retrieveKeyFromStorage(keySuffix) {
219 if (keySuffix === "biometric") {
205 if (keySuffix === "biometric") {
@@ -294,7 +280,7 @@ class BrowserPlatformUtilsService {
294 saveFile(win, blobData, blobOptions, fileName) {
280 saveFile(win, blobData, blobOptions, fileName) {
295 // BrowserApi.downloadFile(win, blobData, blobOptions, fileName);
281 // BrowserApi.downloadFile(win, blobData, blobOptions, fileName);
296 }
282 }
297− getApplicationVersionNumber() {
283+ getApplicationVersion() {
298 // return Promise.resolve(BrowserApi.getApplicationVersion());
284 // return Promise.resolve(BrowserApi.getApplicationVersion());
299 }
285 }
300 supportsWebAuthn(win) {
286 supportsWebAuthn(win) {
backend/BW.purs+28−45
@@ -1,10 +1,8 @@
1module BW where
1module BW where
2
2
3import BW.Types
3import BW.Types
4−import Bridge
5import Prelude
4import Prelude
6
5
7−import Bridge as Bridge
8import Control.Promise (Promise)
6import Control.Promise (Promise)
9import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson)
7import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson)
10import Data.ArrayBuffer.Typed as AB
8import Data.ArrayBuffer.Typed as AB
@@ -15,37 +13,22 @@ import Data.JNullable (JNullable)
15import Data.SymmetricCryptoKey (SymmetricCryptoKey)
13import Data.SymmetricCryptoKey (SymmetricCryptoKey)
16import Effect (Effect)
14import Effect (Effect)
17import Effect.Unsafe (unsafePerformEffect)
15import Effect.Unsafe (unsafePerformEffect)
18−import Untagged.Union (type (|+|))
16+
19−
20−type TotpService =
21− { getCode :: String -> Promise String
22− , getTimeInterval :: String -> Int
23− }
24−
25−type CryptoService =
17+type CryptoService
26− { makeKey :: Fn4 Password String KDF KdfConfig (Promise SymmetricCryptoKey)
18+ = { makeKey :: Fn4 Password String KDF Int (Promise SymmetricCryptoKey)
27− , hashPassword :: Fn3 Password SymmetricCryptoKey (JNullable HashPurpose) (Promise StringHash)
19+ , hashPassword :: Fn3 Password SymmetricCryptoKey (JNullable HashPurpose) (Promise StringHash)
28− , decryptToUtf8 :: Fn2 EncString SymmetricCryptoKey (Promise String)
20+ , decryptToUtf8 :: Fn2 EncString SymmetricCryptoKey (Promise String)
29− , decryptToBytes :: Fn2 EncString SymmetricCryptoKey (Promise ArrayBuffer)
21+ , decryptToBytes :: Fn2 EncString SymmetricCryptoKey (Promise ArrayBuffer)
30− , encrypt :: Fn2 String SymmetricCryptoKey (Promise EncString)
31− , stretchKey :: SymmetricCryptoKey -> Promise SymmetricCryptoKey
22+ , stretchKey :: SymmetricCryptoKey -> Promise SymmetricCryptoKey
32− }
23+ }
33−
24+
34−type ApiService =
25+type ApiService
35− { postPrelogin :: PreloginRequest -> Promise PreloginResponse
26+ = { postPrelogin :: PreloginRequest -> Promise PreloginResponse
36− , getProfile :: Unit -> Promise ProfileResponse
27+ , getProfile :: Unit -> Promise ProfileResponse
37− -- TODO: There can really be more request and response types. Maybe handle this later.
28+ -- TODO: There can really be more request and response types. Maybe handle this later.
38− , postIdentityToken :: PasswordTokenRequest -> Promise (IdentityCaptchaResponse |+| IdentityTwoFactorResponse |+| IdentityTokenResponse)
29+ , postIdentityToken :: PasswordTokenRequest -> Promise IdentityTokenResponse
39− , getSync :: Unit -> Promise SyncResponse
30+ , getSync :: Unit -> Promise SyncResponse
40− , postCipherCreate :: CipherResponse -> Promise CipherResponse
41− , putCipher :: CipherResponse -> Promise CipherResponse
42− , deleteCipher :: String -> Promise Unit
43− , postTwoFactorEmail :: TwoFactorEmailRequest -> Promise Unit
44− }
45−
46−type PasswordGeneration =
47− { generatePassword :: Bridge.PasswordGeneratorConfig -> Promise String
48− }
31+ }
49
32
50cryptoFunctionsTypeSha1 = "sha1" :: CryptoFunctionsType
33cryptoFunctionsTypeSha1 = "sha1" :: CryptoFunctionsType
51
34
@@ -55,13 +38,15 @@ cryptoFunctionsTypeSha512 = "sha512" :: CryptoFunctionsType
55
38
56cryptoFunctionsTypeMd5 = "md5" :: CryptoFunctionsType
39cryptoFunctionsTypeMd5 = "md5" :: CryptoFunctionsType
57
40
58−type CryptoFunctionsType = String
41+type CryptoFunctionsType
42+ = String
59
43
60−type CryptoFunctions =
44+type CryptoFunctions
61− { hash :: Fn2 String CryptoFunctionsType (Promise Hash)
45+ = { hash :: Fn2 String CryptoFunctionsType (Promise Hash)
62− }
46+ }
63
47
48+newtype Hash
64−newtype Hash = Hash (ArrayBuffer)
49+ = Hash (ArrayBuffer)
65
50
66hashToArray :: Hash -> Array Int
51hashToArray :: Hash -> Array Int
67hashToArray (Hash buf) =
52hashToArray (Hash buf) =
@@ -84,12 +69,10 @@ instance EncodeJson Hash where
84instance DecodeJson Hash where
69instance DecodeJson Hash where
85 decodeJson = decodeJson >>> map arrayToHash
70 decodeJson = decodeJson >>> map arrayToHash
86
71
87−type Services =
72+type Services
88− { crypto :: CryptoService
73+ = { crypto :: CryptoService
89− , getApi :: Urls -> JNullable IdentityTokenResponse -> Promise ApiService
74+ , getApi :: Urls -> JNullable IdentityTokenResponse -> Promise ApiService
90− , cryptoFunctions :: CryptoFunctions
75+ , cryptoFunctions :: CryptoFunctions
91− , passwordGeneration :: PasswordGeneration
92− , totpService :: TotpService
93− }
76+ }
94
77
95foreign import getServices :: Effect Services
78foreign import getServices :: Effect Services
backend/BW/Logic.purs+41−454
@@ -2,78 +2,38 @@ module BW.Logic where
2
2
3import BW
3import BW
4import BW.Types
4import BW.Types
5+import Control.El
5import Prelude
6import Prelude
6−
7−import Bridge as Bridge
8−import Control.Monad.Error.Class (throwError)
9import Control.Promise (Promise)
7import Control.Promise (Promise)
10import Control.Promise as Promise
8import Control.Promise as Promise
11import Data.EncString as EncString
9import Data.EncString as EncString
12import Data.Function.Uncurried (runFn2, runFn3, runFn4)
10import Data.Function.Uncurried (runFn2, runFn3, runFn4)
13−import Data.JNullable (JNullable, fromJNullable, jnull, nullify)
11+import Data.JNullable (jnull, nullify)
14−import Data.JNullable as JNullable
15−import Data.JOpt (JOpt(..), fromJOpt)
16−import Data.Maybe (Maybe(..), fromMaybe, maybe)
17−import Data.Newtype (class Newtype, unwrap, wrap)
18−import Data.Number.Format as Number
19import Data.String as String
12import Data.String as String
20import Data.SymmetricCryptoKey (SymmetricCryptoKey)
13import Data.SymmetricCryptoKey (SymmetricCryptoKey)
21import Data.SymmetricCryptoKey as SymmetricCryptoKey
14import Data.SymmetricCryptoKey as SymmetricCryptoKey
22−import Data.Traversable (traverse)
23−import Data.Undefined.NoProblem (opt, undefined)
24−import Effect (Effect)
25−import Effect.Aff (Aff)
26import Effect.Aff.Class (class MonadAff, liftAff)
15import Effect.Aff.Class (class MonadAff, liftAff)
27import Effect.Class (liftEffect)
16import Effect.Class (liftEffect)
28−import Effect.Exception (error)
29import Effect.Exception as Exc
17import Effect.Exception as Exc
30−import Effect.Random (random)
31−import Localstorage as Storage
32−import Run (Run)
33−import Run.Reader (Reader, askAt)
34−import Storage (DeviceIDKey(..))
35−import Type.Prelude (Proxy(..))
36−import Untagged.Union (type (|+|))
37−import Web.Storage.Storage (Storage)
38
18
39-- | Creates the master key
19-- | Creates the master key
40−makePreloginKey
20+makePreloginKey ::
41− :: forall r
21+ forall r.
42− . PreloginResponse
22+ HasL "crypto" CryptoService r =>
43− -> Email
44− -> Password
45− -> Run
46− ( crypto :: Reader CryptoService
47− , effect :: Effect
48− , aff :: Aff
49− | r
50− )
51− SymmetricCryptoKey
23+ PreloginResponse -> Email -> Password -> Al r SymmetricCryptoKey
52−makePreloginKey { kdf, kdfIterations, kdfMemory, kdfParallelism } (Email email') password = do
24+makePreloginKey { kdf, kdfIterations } (Email email') password = do
53− crypto <- askAt (Proxy :: _ "crypto")
25+ crypto <- l (L :: L "crypto")
54 let
26 let
55 email = (String.trim >>> String.toLower) email'
27 email = (String.trim >>> String.toLower) email'
56− liftPromise $ runFn4 crypto.makeKey password email kdf
28+ liftPromise $ runFn4 crypto.makeKey password email kdf kdfIterations
57− { iterations: kdfIterations
58− , memory: kdfMemory
59− , parallelism: kdfParallelism
60− }
61
29
62−makeDecryptionKey
30+makeDecryptionKey ::
63− :: forall r
31+ forall r.
64− .
32+ HasL "crypto" CryptoService r =>
65 -- | Matser key (prelogin key)
33 -- | Matser key (prelogin key)
66− SymmetricCryptoKey
34+ SymmetricCryptoKey -> EncryptedString -> Al r SymmetricCryptoKey
67− -> EncryptedString
68− -> Run
69− ( crypto :: Reader CryptoService
70− , effect :: Effect
71− , aff :: Aff
72− | r
73− )
74− SymmetricCryptoKey
75makeDecryptionKey masterKey str = do
35makeDecryptionKey masterKey str = do
76− crypto <- askAt (Proxy :: _ "crypto")
36+ crypto <- l (L :: L "crypto")
77 let
37 let
78 encryptedKeyString = EncString.fromString str
38 encryptedKeyString = EncString.fromString str
79
39
@@ -88,425 +48,52 @@ makeDecryptionKey masterKey str = do
88 liftEffect $ Exc.throw $ "Unsupported key encryption type: " <> show encType
48 liftEffect $ Exc.throw $ "Unsupported key encryption type: " <> show encType
89 pure $ SymmetricCryptoKey.fromArrayBuffer key
49 pure $ SymmetricCryptoKey.fromArrayBuffer key
90
50
91−getLogInRequestToken
51+getLogInRequestToken ::
92− :: forall r
52+ forall r.
93− . { prelogin :: PreloginResponse
94− , email :: Email
95− , password :: Password
96− , captchaResponse :: Maybe String
97− , secondFactor :: Bridge.Cmd_Login_secondFactor_Maybe
98− }
99− -> Run
100− ( api :: Reader ApiService
53+ HasL "api" ApiService r =>
101− , crypto :: Reader CryptoService
54+ HasL "crypto" CryptoService r =>
102− , effect :: Effect
55+ PreloginResponse -> Email -> Password -> Al r IdentityTokenResponse
103− , aff :: Aff
104− , storage :: Reader Storage
105− | r
106− )
107− (IdentityCaptchaResponse |+| IdentityTwoFactorResponse |+| IdentityTokenResponse)
108−getLogInRequestToken
56+getLogInRequestToken prelogin email password = do
109− { prelogin
110− , email
111− , password
112− , captchaResponse
113− , secondFactor: Bridge.Cmd_Login_secondFactor_Maybe secondFactor
114− } = do
115 key <- makePreloginKey prelogin email password
57 key <- makePreloginKey prelogin email password
116− crypto <- askAt (Proxy :: _ "crypto")
58+ crypto <- l (L :: L "crypto")
117− let
59+ api :: ApiService <- l (L :: L "api")
118− twoFactor =
119− maybe
120− { provider: twoFactorProviderTypeEmail
121− , token: ""
122− , remember: false
123− }
124− ( \(Bridge.Cmd_Login_secondFactor x@{ provider }) ->
125− x { provider = bridgeToSecondFactorType provider }
126− )
127− secondFactor
128 _localHashedPassword <-
60 _localHashedPassword <-
129 liftPromise
61 liftPromise
130 $ runFn3 crypto.hashPassword password key (nullify hashPurposeLocalAuthorization)
62 $ runFn3 crypto.hashPassword password key (nullify hashPurposeLocalAuthorization)
131 StringHash hashedPassword <- liftPromise $ runFn3 crypto.hashPassword password key jnull
63 StringHash hashedPassword <- liftPromise $ runFn3 crypto.hashPassword password key jnull
132− deviceId <- getDeviceID
133− api :: ApiService <- askAt (Proxy :: _ "api")
134 liftPromise
64 liftPromise
135 $ api.postIdentityToken
65 $ api.postIdentityToken
136 { email: email
66 { email: email
137 , masterPasswordHash: hashedPassword
67 , masterPasswordHash: hashedPassword
138− , captchaResponse: fromMaybe "" captchaResponse
68+ , captchaResponse: ""
139− , twoFactor
69+ , twoFactor:
70+ { provider: twoFactorProviderTypeEmail
71+ , token: ""
72+ , remember: false
73+ }
140 , device:
74 , device:
141 { type: deviceTypeUnknownBrowser
75 { type: deviceTypeUnknownBrowser
142− , name: "Ubuntu Touch"
76+ , name: "Temporary device name"
143− , identifier: deviceId
77+ , identifier: "42"
144 , pushToken: jnull
78 , pushToken: jnull
145 }
79 }
146 }
80 }
147
81
148−bwPasswordStringHash
149− :: forall r
150− . PreloginResponse
151− -> Email
152− -> Password
153− -> Run
154− ( crypto :: Reader CryptoService
155− , effect :: Effect
156− , aff :: Aff
157− | r
158− )
159− StringHash
160−bwPasswordStringHash prelogin email password = do
161− key <- makePreloginKey prelogin email password
162− crypto <- askAt (Proxy :: _ "crypto")
163− _localHashedPassword <-
164− liftPromise
165− $ runFn3 crypto.hashPassword password key (nullify hashPurposeLocalAuthorization)
166− liftPromise $ runFn3 crypto.hashPassword password key jnull
167−
168−hashPassword
169− :: forall r
170− . Password
171− -> Run
172− ( cryptoFunctions :: Reader CryptoFunctions
82+hashPassword :: forall r. HasL "cryptoFunctions" CryptoFunctions r => Password -> Al r Hash
173− , aff :: Aff
174− , effect :: Effect
175− | r
176− )
177− Hash
178hashPassword (Password password) = do
83hashPassword (Password password) = do
179− cryptoFunctions <- askAt (Proxy :: _ "cryptoFunctions")
84+ cryptoFunctions <- l (L :: L "cryptoFunctions")
180 liftPromise $ runFn2 cryptoFunctions.hash password cryptoFunctionsTypeSha512
85 liftPromise $ runFn2 cryptoFunctions.hash password cryptoFunctionsTypeSha512
181
86
182−decrypt
87+decrypt ::
183− :: forall r
88+ forall r.
184− . EncryptedString
185− -> Run
186− ( key :: Reader SymmetricCryptoKey
187− , crypto :: Reader CryptoService
89+ HasL "crypto" CryptoService r =>
188− , aff :: Aff
90+ HasL "key" SymmetricCryptoKey r =>
189− , effect :: Effect
91+ EncryptedString ->
190− | r
191− )
192− String
92+ Al r String
193decrypt input = do
93decrypt input = do
194− crypto <- askAt (Proxy :: _ "crypto")
94+ crypto <- l (L :: L "crypto")
195− key <- askAt (Proxy :: _ "key")
95+ key <- l (L :: L "key")
196 liftPromise $ runFn2 crypto.decryptToUtf8 (EncString.fromString input) key
96 liftPromise $ runFn2 crypto.decryptToUtf8 (EncString.fromString input) key
197
97
198−encrypt
199− :: forall r
200− . String
201− -> Run
202− ( key :: Reader SymmetricCryptoKey
203− , crypto :: Reader CryptoService
204− , aff :: Aff
205− , effect :: Effect
206− | r
207− )
208− EncryptedString
209−encrypt input = do
210− crypto <- askAt (Proxy :: _ "crypto")
211− key <- askAt (Proxy :: _ "key")
212− map EncString.toString $ liftPromise $ runFn2 crypto.encrypt input key
213−
214−liftPromise :: forall m a. MonadAff m => Promise a -> m a
98+liftPromise ∷ forall m a. MonadAff m ⇒ Promise a → m a
215liftPromise = liftAff <<< Promise.toAff
99liftPromise = liftAff <<< Promise.toAff
216−
217−encodeCipher
218− :: forall r
219− . Bridge.FullCipher
220− -> Run
221− ( key :: Reader SymmetricCryptoKey
222− , crypto :: Reader CryptoService
223− , aff :: Aff
224− , effect :: Effect
225− | r
226− )
227− CipherResponse
228−encodeCipher
229− (Bridge.FullCipher { name, cipher, id, favorite, reprompt, collectionIds }) = do
230− let
231− f :: CipherResponse -> Run _ CipherResponse
232− f x = case cipher of
233− Bridge.CardCipher (Bridge.Cipher_CardCipher c) -> do
234− cardholderName <- encryptNullable c.cardholderName
235− brand <- encryptNullable c.brand
236− number <- encryptNullable c.number
237− expMonth <- encryptNullable c.expMonth
238− expYear <- encryptNullable c.expYear
239− code <- encryptNullable c.code
240− pure
241− x
242− { card =
243− nullify
244− { cardholderName
245− , brand
246− , number
247− , expMonth
248− , expYear
249− , code
250− }
251− , type = cipherTypeCard
252− }
253− Bridge.IdentityCipher (Bridge.Cipher_IdentityCipher identity) -> do
254− address1 <- encryptNullable identity.address1
255− address2 <- encryptNullable identity.address2
256− address3 <- encryptNullable identity.address3
257− city <- encryptNullable identity.city
258− company <- encryptNullable identity.company
259− country <- encryptNullable identity.country
260− email <- encryptNullable identity.email
261− firstName <- encryptNullable identity.firstName
262− lastName <- encryptNullable identity.lastName
263− licenseNumber <- encryptNullable identity.licenseNumber
264− middleName <- encryptNullable identity.middleName
265− passportNumber <- encryptNullable identity.passportNumber
266− phone <- encryptNullable identity.phone
267− postalCode <- encryptNullable identity.postalCode
268− ssn <- encryptNullable identity.ssn
269− state <- encryptNullable identity.state
270− title <- encryptNullable identity.title
271− username <- encryptNullable identity.username
272− pure
273− x
274− { identity =
275− nullify
276− { address1
277− , address2
278− , address3
279− , city
280− , company
281− , country
282− , email
283− , firstName
284− , lastName
285− , licenseNumber
286− , middleName
287− , passportNumber
288− , phone
289− , postalCode
290− , ssn
291− , state
292− , title
293− , username
294− }
295− , type = cipherTypeIdentity
296− }
297− Bridge.LoginCipher (Bridge.Cipher_LoginCipher login) -> do
298− password <- encryptNullable login.password
299− uris <-
300− traverse
301− ( \uri -> do
302− uriEnc <- nullify <$> encrypt uri
303− pure { uri: uriEnc, match: jnull }
304− )
305− (unwrap login.uris)
306− username <- encryptNullable login.username
307− totp <- encryptNullable login.totp
308− pure
309− x
310− { login =
311− nullify
312− { password
313− , uris: JOpt $ opt uris
314− , username
315− , passwordRevisionDate: jnull
316− , totp: totp
317− , autofillOnPageLoad: JOpt undefined
318− }
319− , type = cipherTypeLogin
320− }
321− Bridge.NoteCipher note -> do
322− encNote <- encrypt note
323− pure
324− x
325− { notes = nullify encNote
326− , type = cipherTypeSecureNote
327− }
328− encName <- encrypt name
329− f
330− { id
331− , organizationId: jnull
332− , folderId: jnull
333− , type: 0
334− , name: encName
335− , notes: jnull
336− , fields: jnull
337− , login: jnull
338− , card: jnull
339− , identity: jnull
340− , secureNote: jnull
341− , favorite: favorite
342− , edit: jnull
343− , viewPassword: jnull
344− , organizationUseTotp: jnull
345− , revisionDate: jnull
346− , attachments: jnull
347− , passwordHistory: jnull
348− , collectionIds: nullify $ unwrap collectionIds
349− , deletedDate: jnull
350− , reprompt
351− }
352−
353−-- | Check if the cipher is supported by Warden.
354−supportedCipher :: CipherResponse -> Boolean
355−-- We do not support organizations since that requires managing a separate set of
356−-- encryption keys
357−supportedCipher { organizationId } | Just _ <- JNullable.toMaybe organizationId = false
358−supportedCipher _ = true
359−
360−decodeCipher
361− :: forall r
362− . CipherResponse
363− -> Run
364− ( key :: Reader SymmetricCryptoKey
365− , crypto :: Reader CryptoService
366− , aff :: Aff
367− , effect :: Effect
368− | r
369− )
370− (Maybe Bridge.FullCipher)
371−decodeCipher cipher | not (supportedCipher cipher) =
372− pure $ Nothing
373−decodeCipher cipher = do
374− name <- decrypt cipher.name
375− cipherType <- case cipher.type of
376− n
377− | cipherTypeSecureNote == n -> do
378− note <- fromJNullable "" <$> (traverse decrypt cipher.notes)
379− pure $ Bridge.NoteCipher note
380− n
381− | cipherTypeLogin == n -> do
382− case JNullable.toMaybe cipher.login of
383− Nothing -> liftEffect $ throwError $ error "Login data is missing"
384− Just login -> do
385− username <- decryptNullable login.username
386− password <- decryptNullable login.password
387− totp <- decryptNullable login.totp
388− uris <- fromJOpt [] <$>
389− ((traverse >>> traverse) (_.uri >>> JNullable.toMaybe >>> maybe (pure "") decrypt) login.uris)
390− pure $ Bridge.LoginCipher
391− $ Bridge.Cipher_LoginCipher
392− { username
393− , password
394− , uris: wrap uris
395− , totp
396− }
397− n
398− | cipherTypeCard == n -> do
399− case JNullable.toMaybe cipher.card of
400− Nothing -> liftEffect $ throwError $ error "Card data is missing"
401− Just card -> do
402− cardholderName <- decryptNullable card.cardholderName
403− number <- decryptNullable card.number
404− code <- decryptNullable card.code
405− brand <- decryptNullable card.brand
406− expMonth <- decryptNullable card.expMonth
407− expYear <- decryptNullable card.expYear
408− pure $ Bridge.CardCipher
409− $ Bridge.Cipher_CardCipher
410− { brand, cardholderName, code, expMonth, expYear, number }
411− n
412− | cipherTypeIdentity == n -> do
413− case JNullable.toMaybe cipher.identity of
414− Nothing -> liftEffect $ throwError $ error "Identity data is missing"
415− Just identity -> do
416− firstName <- decryptNullable identity.firstName
417− middleName <- decryptNullable identity.middleName
418− lastName <- decryptNullable identity.lastName
419− address1 <- decryptNullable identity.address1
420− address2 <- decryptNullable identity.address2
421− address3 <- decryptNullable identity.address3
422− city <- decryptNullable identity.city
423− company <- decryptNullable identity.company
424− country <- decryptNullable identity.country
425− email <- decryptNullable identity.email
426− licenseNumber <- decryptNullable identity.licenseNumber
427− passportNumber <- decryptNullable identity.passportNumber
428− phone <- decryptNullable identity.phone
429− postalCode <- decryptNullable identity.postalCode
430− ssn <- decryptNullable identity.ssn
431− state <- decryptNullable identity.state
432− title <- decryptNullable identity.title
433− username <- decryptNullable identity.username
434− pure $ Bridge.IdentityCipher
435− $ wrap
436− { firstName
437− , middleName
438− , lastName
439− , address1
440− , address2
441− , address3
442− , city
443− , company
444− , country
445− , email
446− , licenseNumber
447− , passportNumber
448− , phone
449− , postalCode
450− , ssn
451− , state
452− , title
453− , username
454− }
455− n -> liftEffect $ throwError $ error $ "Unsupported cipher type: " <> show n
456− pure $ Just
457− $ wrap
458− { cipher: cipherType
459− , name
460− , id: cipher.id
461− , favorite: cipher.favorite
462− , reprompt: cipher.reprompt
463− , collectionIds: wrap <<< fromJNullable [] $ cipher.collectionIds
464− }
465−
466−decryptNullable
467− :: forall x r
468− . Newtype x (Maybe String)
469− => JNullable EncryptedString
470− -> Run
471− ( key :: Reader SymmetricCryptoKey
472− , crypto :: Reader CryptoService
473− , aff :: Aff
474− , effect :: Effect
475− | r
476− )
477− x
478−decryptNullable x = wrap <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt x)
479−
480−encryptNullable
481− :: forall x r
482− . Newtype x (Maybe String)
483− => x
484− -> Run
485− ( key :: Reader SymmetricCryptoKey
486− , crypto :: Reader CryptoService
487− , aff :: Aff
488− , effect :: Effect
489− | r
490− )
491− (JNullable EncryptedString)
492−encryptNullable x = case unwrap x of
493− Nothing -> pure jnull
494− Just y -> nullify <$> encrypt y
495−
496−getDeviceID ::
497− forall r.
498− Run
499− ( effect :: Effect
500− , storage :: Reader Storage
501− | r
502− )
503− String
504−getDeviceID = do
505− storage <- askAt (Proxy :: _ "storage")
506− maybeId <- liftEffect $ Storage.get storage DeviceIDKey
507− case maybeId of
508− Just id -> pure id
509− Nothing -> do
510− id <- map Number.toString $ liftEffect $ random
511− liftEffect $ Storage.store storage DeviceIDKey id
512− pure id
backend/BW/Types.purs+393−454
@@ -2,27 +2,14 @@ module BW.Types where
2
2
3import Prelude
3import Prelude
4
4
5−import Bridge as Bridge
6import Data.Argonaut (class DecodeJson, class EncodeJson)
5import Data.Argonaut (class DecodeJson, class EncodeJson)
7−import Data.Either (Either)
8−import Data.Either as Either
9−import Data.Int as Int
10import Data.JNullable (JNullable)
6import Data.JNullable (JNullable)
11import Data.JOpt (JOpt)
7import Data.JOpt (JOpt)
12−import Data.Maybe (Maybe(..))
13−import Data.Nullable (Nullable)
14import Data.ShowableJson (ShowableJson)
8import Data.ShowableJson (ShowableJson)
15import Data.Timestamp (Timestamp)
9import Data.Timestamp (Timestamp)
16−import Data.Traversable (for)
17−import Data.Tuple.Nested ((/\))
18−import Foreign as Foreign
19−import Literals.Undefined (Undefined)
20−import Type.Prelude (Proxy(..))
21−import Untagged.TypeCheck (class HasRuntimeType)
22−import Untagged.Union (type (|+|))
23−import Untagged.Union as Union
24
10
25−newtype EncryptedString = EncryptedString String
11+newtype EncryptedString
12+ = EncryptedString String
26
13
27derive newtype instance Show EncryptedString
14derive newtype instance Show EncryptedString
28derive newtype instance Ord EncryptedString
15derive newtype instance Ord EncryptedString
@@ -31,86 +18,78 @@ derive newtype instance EncodeJson EncryptedString
31derive newtype instance DecodeJson EncryptedString
18derive newtype instance DecodeJson EncryptedString
32
19
33kdfPBKDF2_SHA256 = 0 :: KDF
20kdfPBKDF2_SHA256 = 0 :: KDF
34−kdfArgon2id = 1 :: KDF
21+
35−
36−type KDF = Int
22+type KDF
37−
23+ = Int
24+
38−type PreloginResponse =
25+type PreloginResponse
39− { kdf :: KDF
26+ = { kdf :: KDF
40− , kdfIterations :: Int
27+ , kdfIterations :: Int
41− , kdfMemory :: JNullable Int
42− , kdfParallelism :: JNullable Int
43− }
44−
45−type KdfConfig =
46− { iterations :: Int
47− , memory :: JNullable Int
48− , parallelism :: JNullable Int
49− }
28+ }
50−
29+
51−type PreloginRequest =
30+type PreloginRequest
52− { email :: Email
31+ = { email :: String
53− }
32+ }
54−
33+
55−type ProfileResponse =
34+type ProfileResponse
56− { id :: String
35+ = { id :: String
57− , name :: JNullable String
36+ , name :: String
58− , email :: String
37+ , email :: String
59− , emailVerified :: Boolean
38+ , emailVerified :: Boolean
60− , masterPasswordHint :: JNullable String
39+ , masterPasswordHint :: String
61− -- , premiumPersonally :: Boolean
40+ , premiumPersonally :: Boolean
62− -- , premiumFromOrganization :: Boolean
41+ -- , premiumFromOrganization :: Boolean
63− , culture :: JNullable String
42+ , culture :: String
64− , twoFactorEnabled :: Boolean
43+ , twoFactorEnabled :: Boolean
65− , key :: EncryptedString
44+ , key :: EncryptedString
66− , privateKey :: EncryptedString
45+ , privateKey :: EncryptedString
67− , securityStamp :: JNullable String
46+ , securityStamp :: String
68− , forcePasswordReset :: Boolean
47+ , forcePasswordReset :: Boolean
69− , usesKeyConnector :: Boolean
48+ , usesKeyConnector :: Boolean
70− -- , organizations :: Array ProfileOrganizationResponse
49+ , organizations :: Array ProfileOrganizationResponse
71− , providers :: Array ProfileProviderResponse
50+ , providers :: Array ProfileProviderResponse
72− , providerOrganizations :: Array ProfileProviderOrganizationResponse
51+ , providerOrganizations :: Array ProfileProviderOrganizationResponse
73− }
52+ }
74−
53+
75−type ProfileOrganizationResponse =
54+type ProfileOrganizationResponse
76− { id :: String
55+ = { id :: String
77− , name :: JNullable String
56+ , name :: String
78− , usePolicies :: JNullable Boolean
57+ , usePolicies :: Boolean
79− , useGroups :: JNullable Boolean
58+ , useGroups :: Boolean
80− , useDirectory :: JNullable Boolean
59+ , useDirectory :: Boolean
81− , useEvents :: JNullable Boolean
60+ , useEvents :: Boolean
82− , useTotp :: JNullable Boolean
61+ , useTotp :: Boolean
83− , use2fa :: JNullable Boolean
62+ , use2fa :: Boolean
84− , useApi :: JNullable Boolean
63+ , useApi :: Boolean
85− , useSso :: JNullable Boolean
64+ , useSso :: Boolean
86− , useKeyConnector :: JNullable Boolean
65+ , useKeyConnector :: Boolean
87− , useResetPassword :: JNullable Boolean
66+ , useResetPassword :: Boolean
88− , selfHost :: JNullable Boolean
67+ , selfHost :: Boolean
89− , usersGetPremium :: JNullable Boolean
68+ , usersGetPremium :: Boolean
90− , seats :: JNullable Int
69+ , seats :: Int
91− , maxCollections :: JNullable Int
70+ , maxCollections :: Int
92− , maxStorageGb :: JNullable Int
71+ , maxStorageGb :: JNullable Int
93− , key :: JNullable String
72+ , key :: String
94− , hasPublicAndPrivateKeys :: JNullable Boolean
73+ , hasPublicAndPrivateKeys :: Boolean
95− , status :: JNullable OrganizationUserStatusType
74+ , status :: OrganizationUserStatusType
96− , type :: JNullable OrganizationUserType
75+ , type :: OrganizationUserType
97− , enabled :: JNullable Boolean
76+ , enabled :: Boolean
98− , ssoBound :: JNullable Boolean
77+ , ssoBound :: Boolean
99− , identifier :: JNullable String
78+ , identifier :: String
100− , permissions :: JNullable PermissionsApi
79+ , permissions :: PermissionsApi
101− , resetPasswordEnrolled :: JNullable Boolean
80+ , resetPasswordEnrolled :: Boolean
102− , userId :: JNullable String
81+ , userId :: String
103− , providerId :: JNullable String
82+ , providerId :: String
104− , providerName :: JNullable String
83+ , providerName :: String
105− , familySponsorshipFriendlyName :: JNullable String
84+ , familySponsorshipFriendlyName :: String
106− , familySponsorshipAvailable :: JNullable Boolean
85+ , familySponsorshipAvailable :: Boolean
107− , planProductType :: JNullable ProductType
86+ , planProductType :: ProductType
108− , keyConnectorEnabled :: JNullable Boolean
87+ , keyConnectorEnabled :: Boolean
109− , keyConnectorUrl :: JNullable String
88+ , keyConnectorUrl :: String
110− , familySponsorshipLastSyncDate :: JNullable Timestamp
89+ , familySponsorshipLastSyncDate :: JNullable Timestamp
111− , familySponsorshipValidUntil :: JNullable Timestamp
90+ , familySponsorshipValidUntil :: JNullable Timestamp
112− , familySponsorshipToDelete :: JNullable Boolean
91+ , familySponsorshipToDelete :: JNullable Boolean
113− }
92+ }
114
93
115organizationUserStatusTypeInvited = 0 :: OrganizationUserStatusType
94organizationUserStatusTypeInvited = 0 :: OrganizationUserStatusType
116
95
@@ -118,7 +97,8 @@ organizationUserStatusTypeAccepted = 0 :: OrganizationUserStatusType
118
97
119organizationUserStatusTypeConfirmed = 0 :: OrganizationUserStatusType
98organizationUserStatusTypeConfirmed = 0 :: OrganizationUserStatusType
120
99
121−type OrganizationUserStatusType = Int
100+type OrganizationUserStatusType
101+ = Int
122
102
123organizationUserTypeOwner = 0 :: OrganizationUserType
103organizationUserTypeOwner = 0 :: OrganizationUserType
124
104
@@ -130,26 +110,27 @@ organizationUserTypeManager = 3 :: OrganizationUserType
130
110
131organizationUserTypeCustom = 4 :: OrganizationUserType
111organizationUserTypeCustom = 4 :: OrganizationUserType
132
112
133−type OrganizationUserType = Int
113+type OrganizationUserType
134−
114+ = Int
115+
135−type PermissionsApi =
116+type PermissionsApi
136− { accessEventLogs :: Boolean
117+ = { accessEventLogs :: Boolean
137− , accessImportExport :: Boolean
118+ , accessImportExport :: Boolean
138− , accessReports :: Boolean
119+ , accessReports :: Boolean
139− , manageAllCollections :: Boolean
120+ , manageAllCollections :: Boolean
140− , createNewCollections :: Boolean
121+ , createNewCollections :: Boolean
141− , editAnyCollection :: Boolean
122+ , editAnyCollection :: Boolean
142− , deleteAnyCollection :: Boolean
123+ , deleteAnyCollection :: Boolean
143− , manageAssignedCollections :: Boolean
124+ , manageAssignedCollections :: Boolean
144− , editAssignedCollections :: Boolean
125+ , editAssignedCollections :: Boolean
145− , deleteAssignedCollections :: Boolean
126+ , deleteAssignedCollections :: Boolean
146− , manageCiphers :: Boolean
127+ , manageCiphers :: Boolean
147− , manageGroups :: Boolean
128+ , manageGroups :: Boolean
148− , manageSso :: Boolean
129+ , manageSso :: Boolean
149− , managePolicies :: Boolean
130+ , managePolicies :: Boolean
150− , manageUsers :: Boolean
131+ , manageUsers :: Boolean
151− , manageResetPassword :: Boolean
132+ , manageResetPassword :: Boolean
152− }
133+ }
153
134
154productTypeFree = 0 :: ProductType
135productTypeFree = 0 :: ProductType
155
136
@@ -159,19 +140,20 @@ productTypeTeams = 2 :: ProductType
159
140
160productTypeEnterprise = 3 :: ProductType
141productTypeEnterprise = 3 :: ProductType
161
142
162−type ProductType = Int
143+type ProductType
163−
144+ = Int
145+
164−type ProfileProviderResponse =
146+type ProfileProviderResponse
165− { id :: String
147+ = { id :: String
166− , name :: JNullable String
148+ , name :: String
167− , key :: JNullable String
149+ , key :: String
168− , status :: JNullable ProviderUserStatusType
150+ , status :: ProviderUserStatusType
169− , type :: JNullable ProviderUserType
151+ , type :: ProviderUserType
170− , enabled :: Boolean
152+ , enabled :: Boolean
171− , permissions :: PermissionsApi
153+ , permissions :: PermissionsApi
172− , userId :: JNullable String
154+ , userId :: String
173− , useEvents :: Boolean
155+ , useEvents :: Boolean
174− }
156+ }
175
157
176providerUserStatusTypeInvited = 0 :: ProviderUserStatusType
158providerUserStatusTypeInvited = 0 :: ProviderUserStatusType
177
159
@@ -179,79 +161,81 @@ providerUserStatusTypeAccepted = 1 :: ProviderUserStatusType
179
161
180providerUserStatusTypeConfirmed = 2 :: ProviderUserStatusType
162providerUserStatusTypeConfirmed = 2 :: ProviderUserStatusType
181
163
182−type ProviderUserStatusType = Int
164+type ProviderUserStatusType
165+ = Int
183
166
184providerUserTypeProviderAdmin = 0 :: ProviderUserType
167providerUserTypeProviderAdmin = 0 :: ProviderUserType
185
168
186providerUserTypeServiceUser = 1 :: ProviderUserType
169providerUserTypeServiceUser = 1 :: ProviderUserType
187
170
188−type ProviderUserType = Int
171+type ProviderUserType
189−
172+ = Int
173+
190−type ProfileProviderOrganizationResponse =
174+type ProfileProviderOrganizationResponse
191− { id :: String
175+ = { id :: String
192− , name :: JNullable String
176+ , name :: String
193− , usePolicies :: Boolean
177+ , usePolicies :: Boolean
194− , useGroups :: Boolean
178+ , useGroups :: Boolean
195− , useDirectory :: Boolean
179+ , useDirectory :: Boolean
196− , useEvents :: Boolean
180+ , useEvents :: Boolean
197− , useTotp :: Boolean
181+ , useTotp :: Boolean
198− , use2fa :: Boolean
182+ , use2fa :: Boolean
199− , useApi :: Boolean
183+ , useApi :: Boolean
200− , useSso :: Boolean
184+ , useSso :: Boolean
201− , useKeyConnector :: Boolean
185+ , useKeyConnector :: Boolean
202− , useResetPassword :: Boolean
186+ , useResetPassword :: Boolean
203− , selfHost :: Boolean
187+ , selfHost :: Boolean
204− , usersGetPremium :: Boolean
188+ , usersGetPremium :: Boolean
205− , seats :: Int
189+ , seats :: Int
206− , maxCollections :: Int
190+ , maxCollections :: Int
207− , maxStorageGb :: JNullable Int
191+ , maxStorageGb :: JNullable Int
208− , key :: JNullable String
192+ , key :: String
209− , hasPublicAndPrivateKeys :: Boolean
193+ , hasPublicAndPrivateKeys :: Boolean
210− , status :: OrganizationUserStatusType
194+ , status :: OrganizationUserStatusType
211− , type :: OrganizationUserType
195+ , type :: OrganizationUserType
212− , enabled :: Boolean
196+ , enabled :: Boolean
213− , ssoBound :: Boolean
197+ , ssoBound :: Boolean
214− , identifier :: JNullable String
198+ , identifier :: String
215− , permissions :: PermissionsApi
199+ , permissions :: PermissionsApi
216− , resetPasswordEnrolled :: Boolean
200+ , resetPasswordEnrolled :: Boolean
217− , userId :: JNullable String
201+ , userId :: String
218− , providerId :: JNullable String
202+ , providerId :: String
219− , providerName :: JNullable String
203+ , providerName :: String
220− , familySponsorshipFriendlyName :: JNullable String
204+ , familySponsorshipFriendlyName :: String
221− , familySponsorshipAvailable :: Boolean
205+ , familySponsorshipAvailable :: Boolean
222− , planProductType :: ProductType
206+ , planProductType :: ProductType
223− , keyConnectorEnabled :: Boolean
207+ , keyConnectorEnabled :: Boolean
224− , keyConnectorUrl :: JNullable String
208+ , keyConnectorUrl :: String
225− , familySponsorshipLastSyncDate :: JNullable Timestamp
209+ , familySponsorshipLastSyncDate :: JNullable Timestamp
226− , familySponsorshipValidUntil :: JNullable Timestamp
210+ , familySponsorshipValidUntil :: JNullable Timestamp
227− , familySponsorshipToDelete :: JNullable Boolean
211+ , familySponsorshipToDelete :: JNullable Boolean
228− }
212+ }
229−
213+
230−type Urls =
214+type Urls
231− { base :: JNullable String
215+ = { base :: JNullable String
232− , webVault :: JNullable String
216+ , webVault :: JNullable String
233− , api :: JNullable String
217+ , api :: JNullable String
234− , identity :: JNullable String
218+ , identity :: JNullable String
235− , icons :: JNullable String
219+ , icons :: JNullable String
236− , notifications :: JNullable String
220+ , notifications :: JNullable String
237− , events :: JNullable String
221+ , events :: JNullable String
238− , keyConnector :: JNullable String
222+ , keyConnector :: JNullable String
239− }
223+ }
240−
224+
241−type PasswordTokenRequest =
225+type PasswordTokenRequest
242− { email :: Email
226+ = { email :: Email
243− , masterPasswordHash :: String
227+ , masterPasswordHash :: String
244− , captchaResponse :: String
228+ , captchaResponse :: String
245− , twoFactor :: TokenRequestTwoFactor
229+ , twoFactor :: TokenRequestTwoFactor
246− , device :: DeviceRequest
230+ , device :: DeviceRequest
247− }
231+ }
248−
232+
249−type DeviceRequest =
233+type DeviceRequest
250− { type :: DeviceType
234+ = { type :: DeviceType
251− , name :: String
235+ , name :: String
252− , identifier :: String
236+ , identifier :: String
253− , pushToken :: JNullable String
237+ , pushToken :: JNullable String
254− }
238+ }
255
239
256deviceTypeAndroid = 0 :: DeviceType
240deviceTypeAndroid = 0 :: DeviceType
257
241
@@ -295,13 +279,14 @@ deviceTypeVivaldiExtension = 19 :: DeviceType
295
279
296deviceTypeSafariExtension = 20 :: DeviceType
280deviceTypeSafariExtension = 20 :: DeviceType
297
281
298−type DeviceType = Int
282+type DeviceType
283+ = Int
299
284
300−type TokenRequestTwoFactor =
285+type TokenRequestTwoFactor
301− { provider :: TwoFactorProviderType
286+ = { provider :: TwoFactorProviderType
302− , token :: String
287+ , token :: String
303− , remember :: Boolean
288+ , remember :: Boolean
304− }
289+ }
305
290
306twoFactorProviderTypeAuthenticator = 0 :: TwoFactorProviderType
291twoFactorProviderTypeAuthenticator = 0 :: TwoFactorProviderType
307
292
@@ -319,51 +304,24 @@ twoFactorProviderTypeOrganizationDuo = 6 :: TwoFactorProviderType
319
304
320twoFactorProviderTypeWebAuthn = 7 :: TwoFactorProviderType
305twoFactorProviderTypeWebAuthn = 7 :: TwoFactorProviderType
321
306
322−type TwoFactorProviderType = Int
307+type TwoFactorProviderType
323−
308+ = Int
324−secondFactorTypeToBridge
309+
325− :: TwoFactorProviderType
326− -> Maybe Bridge.TwoFactorProviderType
327−secondFactorTypeToBridge x = case x of
328− n
329− | n == twoFactorProviderTypeAuthenticator -> Just Bridge.Authenticator
330− n
331− | n == twoFactorProviderTypeEmail -> Just Bridge.Email
332− n
333− | n == twoFactorProviderTypeDuo -> Just Bridge.Duo
334− n
335− | n == twoFactorProviderTypeYubikey -> Just Bridge.Yubikey
336− n
337− | n == twoFactorProviderTypeU2f -> Just Bridge.U2f
338− n
339− | n == twoFactorProviderTypeRemember -> Just Bridge.Remember
340− n
341− | n == twoFactorProviderTypeOrganizationDuo -> Just Bridge.OrganizationDuo
342− n
343− | n == twoFactorProviderTypeWebAuthn -> Just Bridge.WebAuthn
344− _ -> Nothing
345−
346−bridgeToSecondFactorType :: Bridge.TwoFactorProviderType -> TwoFactorProviderType
347−bridgeToSecondFactorType Bridge.Authenticator = twoFactorProviderTypeAuthenticator
348−bridgeToSecondFactorType Bridge.Email = twoFactorProviderTypeEmail
349−bridgeToSecondFactorType Bridge.Duo = twoFactorProviderTypeDuo
350−bridgeToSecondFactorType Bridge.Yubikey = twoFactorProviderTypeYubikey
351−bridgeToSecondFactorType Bridge.U2f = twoFactorProviderTypeU2f
352−bridgeToSecondFactorType Bridge.Remember = twoFactorProviderTypeRemember
353−bridgeToSecondFactorType Bridge.OrganizationDuo = twoFactorProviderTypeOrganizationDuo
354−bridgeToSecondFactorType Bridge.WebAuthn = twoFactorProviderTypeWebAuthn
355−
356−newtype Password = Password String
310+newtype Password
311+ = Password String
357
312
358hashPurposeServerAuthorization = 1 :: HashPurpose
313hashPurposeServerAuthorization = 1 :: HashPurpose
359
314
360hashPurposeLocalAuthorization = 2 :: HashPurpose
315hashPurposeLocalAuthorization = 2 :: HashPurpose
361
316
362−type HashPurpose = Int
317+type HashPurpose
318+ = Int
363
319
364−newtype StringHash = StringHash String
320+newtype StringHash
321+ = StringHash String
365
322
366−newtype AccessToken = AccessToken String
323+newtype AccessToken
324+ = AccessToken String
367
325
368derive newtype instance Show AccessToken
326derive newtype instance Show AccessToken
369derive newtype instance Eq AccessToken
327derive newtype instance Eq AccessToken
@@ -371,7 +329,8 @@ derive newtype instance Ord AccessToken
371derive newtype instance EncodeJson AccessToken
329derive newtype instance EncodeJson AccessToken
372derive newtype instance DecodeJson AccessToken
330derive newtype instance DecodeJson AccessToken
373
331
374−newtype RefreshToken = RefreshToken String
332+newtype RefreshToken
333+ = RefreshToken String
375
334
376derive newtype instance Show RefreshToken
335derive newtype instance Show RefreshToken
377derive newtype instance Eq RefreshToken
336derive newtype instance Eq RefreshToken
@@ -379,95 +338,73 @@ derive newtype instance Ord RefreshToken
379derive newtype instance EncodeJson RefreshToken
338derive newtype instance EncodeJson RefreshToken
380derive newtype instance DecodeJson RefreshToken
339derive newtype instance DecodeJson RefreshToken
381
340
382−type IdentityCaptchaResponse =
341+
383− { siteKey :: String
384− }
385−
386−type IdentityTokenResponse =
342+type IdentityTokenResponse
387− { accessToken :: AccessToken
343+ = { accessToken :: AccessToken
388− , expiresIn :: Int
344+ , expiresIn :: Int
389− , refreshToken :: RefreshToken
345+ , refreshToken :: RefreshToken
390− , tokenType :: String
346+ , tokenType :: String
391− , resetMasterPassword :: Boolean
347+ , resetMasterPassword :: Boolean
392− , privateKey :: EncryptedString
348+ , privateKey :: EncryptedString
393− , key :: EncryptedString
349+ , key :: EncryptedString
394− , twoFactorToken :: JNullable String
350+ , twoFactorToken :: JNullable String
395− , kdf :: KDF
351+ , kdf :: KDF
396− , kdfIterations :: Int
352+ , kdfIterations :: Int
397− , forcePasswordReset :: JNullable Boolean
353+ , forcePasswordReset :: JNullable Boolean
398− , apiUseKeyConnector :: JNullable Boolean
354+ , apiUseKeyConnector :: JNullable Boolean
399− , keyConnectorUrl :: JNullable String
355+ , keyConnectorUrl :: JNullable String
400− }
401−
402−newtype TwoFactorProviderTypes = TwoFactorProviderTypes (Array (Int |+| String))
403−
404−instance HasRuntimeType TwoFactorProviderTypes where
405− hasRuntimeType Proxy = Foreign.isArray
406−
407−fromTwoFactorProviderType :: TwoFactorProviderTypes -> Either String (Array Bridge.TwoFactorProviderType)
408−fromTwoFactorProviderType (TwoFactorProviderTypes xs) =
409− for xs $ \rawProvider -> do
410− providerInt <- Union.reduce (Either.Right /\ (\x -> Either.note x $ Int.fromString x)) rawProvider
411− Either.note (show providerInt) $ secondFactorTypeToBridge providerInt
412−
413−type IdentityTwoFactorResponse =
414− { twoFactorProviders :: TwoFactorProviderTypes
415− -- it is a Map type and untaged unions gets confused
416− -- , twoFactorProviders2 :: Object (Object String)
417− , captchaToken :: String |+| Undefined
418− }
356+ }
419−
357+
420−newtype Email = Email String
358+newtype Email
421−
359+ = Email String
360+
422−type SyncResponse =
361+type SyncResponse
423− { profile :: ProfileResponse
362+ = { profile :: ProfileResponse
424− , folders :: Array FolderResponse
363+ , folders :: Array FolderResponse
425− , collections :: Array CollectionDetailsResponse
364+ , collections :: Array CollectionDetailsResponse
426− , ciphers :: Array CipherResponse
365+ , ciphers :: Array CipherResponse
427− , domains :: JNullable DomainsResponse
366+ , domains :: JNullable DomainsResponse
428− , policies :: JNullable (Array PolicyResponse)
367+ , policies :: JNullable (Array PolicyResponse)
429− , sends :: Array SendResponse
368+ , sends :: Array SendResponse
430− }
369+ }
431−
370+
432−type FolderResponse =
371+type FolderResponse
433− { id :: String
372+ = { id :: String
434− , name :: JNullable String
373+ , name :: String
435− , revisionDate :: JNullable String
374+ , revisionDate :: String
436− }
375+ }
437−
376+
438−type CollectionDetailsResponse =
377+type CollectionDetailsResponse
439− { id :: String
378+ = { id :: String
440− , organizationId :: JNullable String
379+ , organizationId :: JNullable String
441− , name :: JNullable String
380+ , name :: String
442− , externalId :: JNullable String
381+ , externalId :: JNullable String
443− , readOnly :: Boolean
382+ , readOnly :: Boolean
444− }
383+ }
445−
384+
446−type CipherId = String
447−
448−type CipherResponse =
385+type CipherResponse
449− { id :: CipherId
386+ = { id :: String
450− , organizationId :: JNullable String
387+ , organizationId :: JNullable String
451− , folderId :: JNullable String
388+ , folderId :: JNullable String
452− , type :: CipherType
389+ , type :: CipherType
453− , name :: EncryptedString
390+ , name :: EncryptedString
454− , notes :: JNullable EncryptedString
391+ , notes :: JNullable EncryptedString
455− , fields :: JNullable (Array FieldApi)
392+ , fields :: JNullable (Array FieldApi)
456− , login :: JNullable LoginApi
393+ , login :: JNullable LoginApi
457− , card :: JNullable CardApi
394+ , card :: JNullable CardApi
458− , identity :: JNullable IdentityApi
395+ , identity :: JNullable IdentityApi
459− , secureNote :: JNullable SecureNoteApi
396+ , secureNote :: JNullable SecureNoteApi
460− , favorite :: Boolean
397+ , favorite :: Boolean
461− , edit :: JNullable Boolean
398+ , edit :: Boolean
462− , viewPassword :: JNullable Boolean
399+ , viewPassword :: Boolean
463− , organizationUseTotp :: JNullable Boolean
400+ , organizationUseTotp :: Boolean
464− , revisionDate :: JNullable Timestamp
401+ , revisionDate :: Timestamp
465− , attachments :: JNullable (Array AttachmentResponse)
402+ , attachments :: JNullable (Array AttachmentResponse)
466− , passwordHistory :: JNullable (Array PasswordHistoryResponse)
403+ , passwordHistory :: JNullable (Array PasswordHistoryResponse)
467− , collectionIds :: JNullable (Array String)
404+ , collectionIds :: JNullable (Array String)
468− , deletedDate :: JNullable String
405+ , deletedDate :: JNullable String
469− , reprompt :: CipherRepromptType
406+ , reprompt :: CipherRepromptType
470− }
407+ }
471
408
472cipherTypeLogin = 1 :: CipherType
409cipherTypeLogin = 1 :: CipherType
473
410
@@ -477,14 +414,15 @@ cipherTypeCard = 3 :: CipherType
477
414
478cipherTypeIdentity = 4 :: CipherType
415cipherTypeIdentity = 4 :: CipherType
479
416
480−type CipherType = Int
417+type CipherType
418+ = Int
481
419
482−type FieldApi =
420+type FieldApi
483− { name :: JNullable String
421+ = { name :: String
484− , value :: JNullable String
422+ , value :: String
485− , type :: FieldType
423+ , type :: FieldType
486− , linkedId :: JNullable LinkedIdType
424+ , linkedId :: JNullable LinkedIdType
487− }
425+ }
488
426
489fieldTypeText = 0 :: FieldType
427fieldTypeText = 0 :: FieldType
490
428
@@ -494,7 +432,8 @@ fieldTypeBoolean = 2 :: FieldType
494
432
495fieldTypeLinked = 3 :: FieldType
433fieldTypeLinked = 3 :: FieldType
496
434
497−type FieldType = Int
435+type FieldType
436+ = Int
498
437
499linkedIdTypeLoginLinkedIdUsername = 100 :: LinkedIdType
438linkedIdTypeLoginLinkedIdUsername = 100 :: LinkedIdType
500
439
@@ -550,22 +489,23 @@ linkedIdTypeIdentityLinkedIdLastName = 417 :: LinkedIdType
550
489
551linkedIdTypeIdentityLinkedIdFullName = 418 :: LinkedIdType
490linkedIdTypeIdentityLinkedIdFullName = 418 :: LinkedIdType
552
491
553−type LinkedIdType = Int
492+type LinkedIdType
493+ = Int
554
494
555−type LoginApi =
495+type LoginApi
556− { uris :: JOpt (Array LoginUriApi)
496+ = { uris :: JOpt (Array LoginUriApi)
557− , username :: JNullable EncryptedString
497+ , username :: JNullable EncryptedString
558− , password :: JNullable EncryptedString
498+ , password :: JNullable EncryptedString
559− , passwordRevisionDate :: JNullable String
499+ , passwordRevisionDate :: JNullable String
560− , totp :: JNullable EncryptedString
500+ , totp :: JNullable EncryptedString
561− -- This thing is undefined in some cases for some reson. Just ignoring it
501+ -- This thing is undefined in some cases for some reson. Just ignoring it
562− , autofillOnPageLoad :: JOpt (JNullable Boolean)
502+ , autofillOnPageLoad :: JOpt (JNullable Boolean)
563− }
503+ }
564
504
565−type LoginUriApi =
505+type LoginUriApi
566− { uri :: JNullable EncryptedString
506+ = { uri :: EncryptedString
567− , match :: JNullable UriMatchType
507+ , match :: JNullable UriMatchType
568− }
508+ }
569
509
570uriMatchTypeDomain = 0 :: UriMatchType
510uriMatchTypeDomain = 0 :: UriMatchType
571
511
@@ -579,85 +519,87 @@ uriMatchTypeRegularExpression = 4 :: UriMatchType
579
519
580uriMatchTypeNever = 5 :: UriMatchType
520uriMatchTypeNever = 5 :: UriMatchType
581
521
582−type UriMatchType = Int
522+type UriMatchType
583−
523+ = Int
524+
584−type CardApi =
525+type CardApi
585− { cardholderName :: JNullable EncryptedString
526+ = { cardholderName :: JNullable EncryptedString
586− , brand :: JNullable EncryptedString
527+ , brand :: JNullable EncryptedString
587− , number :: JNullable EncryptedString
528+ , number :: JNullable EncryptedString
588− , expMonth :: JNullable EncryptedString
529+ , expMonth :: JNullable EncryptedString
589− , expYear :: JNullable EncryptedString
530+ , expYear :: JNullable EncryptedString
590− , code :: JNullable EncryptedString
531+ , code :: JNullable EncryptedString
591− }
532+ }
592−
533+
593−type IdentityApi =
534+type IdentityApi
594− { title :: JNullable EncryptedString
535+ = { title :: JNullable EncryptedString
595− , firstName :: JNullable EncryptedString
536+ , firstName :: JNullable EncryptedString
596− , middleName :: JNullable EncryptedString
537+ , middleName :: JNullable EncryptedString
597− , lastName :: JNullable EncryptedString
538+ , lastName :: JNullable EncryptedString
598− , address1 :: JNullable EncryptedString
539+ , address1 :: JNullable EncryptedString
599− , address2 :: JNullable EncryptedString
540+ , address2 :: JNullable EncryptedString
600− , address3 :: JNullable EncryptedString
541+ , address3 :: JNullable EncryptedString
601− , city :: JNullable EncryptedString
542+ , city :: JNullable EncryptedString
602− , state :: JNullable EncryptedString
543+ , state :: JNullable EncryptedString
603− , postalCode :: JNullable EncryptedString
544+ , postalCode :: JNullable EncryptedString
604− , country :: JNullable EncryptedString
545+ , country :: JNullable EncryptedString
605− , company :: JNullable EncryptedString
546+ , company :: JNullable EncryptedString
606− , email :: JNullable EncryptedString
547+ , email :: JNullable EncryptedString
607− , phone :: JNullable EncryptedString
548+ , phone :: JNullable EncryptedString
608− , ssn :: JNullable EncryptedString
549+ , ssn :: JNullable EncryptedString
609− , username :: JNullable EncryptedString
550+ , username :: JNullable EncryptedString
610− , passportNumber :: JNullable EncryptedString
551+ , passportNumber :: JNullable EncryptedString
611− , licenseNumber :: JNullable EncryptedString
552+ , licenseNumber :: JNullable EncryptedString
612− }
553+ }
613
554
614secureNoteTypeGeneric = 0 :: SecureNoteType
555secureNoteTypeGeneric = 0 :: SecureNoteType
615
556
616−type SecureNoteType = Int
557+type SecureNoteType
558+ = Int
617
559
618−type SecureNoteApi =
560+type SecureNoteApi = {
619− {
620− -- type :: SecureNoteType
561+ type :: SecureNoteType
621− }
562+}
622
563
623−type AttachmentResponse =
564+type AttachmentResponse
624− { id :: String
565+ = { id :: String
625− , url :: JNullable String
566+ , url :: String
626− , fileName :: JNullable String
567+ , fileName :: String
627− , key :: JNullable String
568+ , key :: String
628− , size :: JNullable String
569+ , size :: String
629− , sizeName :: JNullable String
570+ , sizeName :: String
630− }
571+ }
631
572
632−type PasswordHistoryResponse =
573+type PasswordHistoryResponse
633− { password :: String
574+ = { password :: String
634− , lastUsedDate :: JNullable String
575+ , lastUsedDate :: String
635− }
576+ }
636
577
637cipherRepromptTypeNone = 0 :: CipherRepromptType
578cipherRepromptTypeNone = 0 :: CipherRepromptType
638
579
639cipherRepromptTypePassword = 1 :: CipherRepromptType
580cipherRepromptTypePassword = 1 :: CipherRepromptType
640
581
641−type CipherRepromptType = Int
582+type CipherRepromptType
583+ = Int
642
584
643−type DomainsResponse =
585+type DomainsResponse
644− { equivalentDomains :: Array (Array String)
586+ = { equivalentDomains :: Array (Array String)
645− , globalEquivalentDomains :: Array GlobalDomainResponse
587+ , globalEquivalentDomains :: Array GlobalDomainResponse
646− }
588+ }
647
589
648−type GlobalDomainResponse =
590+type GlobalDomainResponse
649− { type :: Int
591+ = { type :: Int
650− , domains :: Array String
592+ , domains :: Array String
651− , excluded :: Boolean
593+ , excluded :: Boolean
652− }
594+ }
653
595
654−type PolicyResponse =
596+type PolicyResponse
655− { id :: String
597+ = { id :: String
656− , organizationId :: JNullable String
598+ , organizationId :: JNullable String
657− , type :: PolicyType
599+ , type :: PolicyType
658− , data :: ShowableJson
600+ , data :: ShowableJson
659− , enabled :: Boolean
601+ , enabled :: Boolean
660− }
602+ }
661
603
662policyTypeTwoFactorAuthentication = 0 :: PolicyType -- Requires users to have 2fa enabled
604policyTypeTwoFactorAuthentication = 0 :: PolicyType -- Requires users to have 2fa enabled
663
605
@@ -681,46 +623,43 @@ policyTypeMaximumVaultTimeout = 9 :: PolicyType -- Sets the maximum allowed vaul
681
623
682policyTypeDisablePersonalVaultExport = 10 :: PolicyType -- Disable personal vault export
624policyTypeDisablePersonalVaultExport = 10 :: PolicyType -- Disable personal vault export
683
625
684−type PolicyType = Int
626+type PolicyType
685−
627+ = Int
628+
686−type SendResponse =
629+type SendResponse
687− { id :: String
630+ = { id :: String
688− , accessId :: JNullable String
631+ , accessId :: String
689− , type :: SendType
632+ , type :: SendType
690− , name :: JNullable String
633+ , name :: String
691− , notes :: JNullable String
634+ , notes :: JNullable String
692− , file :: JNullable SendFileApi
635+ , file :: JNullable SendFileApi
693− , text :: JNullable SendTextApi
636+ , text :: JNullable SendTextApi
694− , key :: JNullable String
637+ , key :: String
695− , maxAccessCount :: JNullable Int
638+ , maxAccessCount :: JNullable Int
696− , accessCount :: JNullable Int
639+ , accessCount :: Int
697− , revisionDate :: JNullable String
640+ , revisionDate :: String
698− , expirationDate :: JNullable String
641+ , expirationDate :: String
699− , deletionDate :: JNullable String
642+ , deletionDate :: JNullable String
700− , password :: JNullable String
643+ , password :: String
701− , disable :: Boolean
644+ , disable :: Boolean
702− , hideEmail :: Boolean
645+ , hideEmail :: Boolean
703− }
646+ }
704
647
705sendTypeText = 0 :: SendType
648sendTypeText = 0 :: SendType
706
649
707sendTypeFile = 1 :: SendType
650sendTypeFile = 1 :: SendType
708
651
709−type SendType = Int
652+type SendType
710−
653+ = Int
711−type SendFileApi =
712− { id :: String
713− , fileName :: JNullable String
714− , size :: JNullable String
715− , sizeName :: JNullable String
716− }
717
654
718−type SendTextApi =
655+type SendFileApi
656+ = { id :: String
657+ , fileName :: String
719− { text :: JNullable String
658+ , size :: String
720− , hidden :: Boolean
659+ , sizeName :: String
721− }
660+ }
722
661
723−type TwoFactorEmailRequest =
662+type SendTextApi
724− { email :: Email
663+ = { text :: String
725− , masterPasswordHash :: StringHash
664+ , hidden :: Boolean
726− }
665+ }
backend/Bridge.purs+297−495
@@ -12,593 +12,451 @@ import Data.Newtype (class Newtype)
12
12
13import Prelude
13import Prelude
14
14
15−newtype Cipher_CardCipher_brand_Maybe =
15+newtype Cmd_Login =
16− Cipher_CardCipher_brand_Maybe (Maybe String)
16+ Cmd_Login {
17−
17+ email :: String
18−derive instance newtypeCipher_CardCipher_brand_Maybe :: Newtype Cipher_CardCipher_brand_Maybe _
18+ , password :: String
19−instance encodeJsonCipher_CardCipher_brand_Maybe :: EncodeJson Cipher_CardCipher_brand_Maybe where
19+ , server :: String
20− encodeJson = genericEncodeAeson Argonaut.defaultOptions
20+ }
21−instance decodeJsonCipher_CardCipher_brand_Maybe :: DecodeJson Cipher_CardCipher_brand_Maybe where
22− decodeJson = genericDecodeAeson Argonaut.defaultOptions
23−derive instance genericCipher_CardCipher_brand_Maybe :: Generic Cipher_CardCipher_brand_Maybe _
24−derive instance eqCipher_CardCipher_brand_Maybe :: Eq Cipher_CardCipher_brand_Maybe
25−derive instance ordCipher_CardCipher_brand_Maybe :: Ord Cipher_CardCipher_brand_Maybe
26−
27−newtype Cipher_CardCipher_cardholderName_Maybe =
28− Cipher_CardCipher_cardholderName_Maybe (Maybe String)
29−
30−derive instance newtypeCipher_CardCipher_cardholderName_Maybe :: Newtype Cipher_CardCipher_cardholderName_Maybe _
31−instance encodeJsonCipher_CardCipher_cardholderName_Maybe :: EncodeJson Cipher_CardCipher_cardholderName_Maybe where
32− encodeJson = genericEncodeAeson Argonaut.defaultOptions
33−instance decodeJsonCipher_CardCipher_cardholderName_Maybe :: DecodeJson Cipher_CardCipher_cardholderName_Maybe where
34− decodeJson = genericDecodeAeson Argonaut.defaultOptions
35−derive instance genericCipher_CardCipher_cardholderName_Maybe :: Generic Cipher_CardCipher_cardholderName_Maybe _
36−derive instance eqCipher_CardCipher_cardholderName_Maybe :: Eq Cipher_CardCipher_cardholderName_Maybe
37−derive instance ordCipher_CardCipher_cardholderName_Maybe :: Ord Cipher_CardCipher_cardholderName_Maybe
38−
39−newtype Cipher_CardCipher_code_Maybe =
40− Cipher_CardCipher_code_Maybe (Maybe String)
41−
42−derive instance newtypeCipher_CardCipher_code_Maybe :: Newtype Cipher_CardCipher_code_Maybe _
43−instance encodeJsonCipher_CardCipher_code_Maybe :: EncodeJson Cipher_CardCipher_code_Maybe where
44− encodeJson = genericEncodeAeson Argonaut.defaultOptions
45−instance decodeJsonCipher_CardCipher_code_Maybe :: DecodeJson Cipher_CardCipher_code_Maybe where
46− decodeJson = genericDecodeAeson Argonaut.defaultOptions
47−derive instance genericCipher_CardCipher_code_Maybe :: Generic Cipher_CardCipher_code_Maybe _
48−derive instance eqCipher_CardCipher_code_Maybe :: Eq Cipher_CardCipher_code_Maybe
49−derive instance ordCipher_CardCipher_code_Maybe :: Ord Cipher_CardCipher_code_Maybe
50−
51−newtype Cipher_CardCipher_expMonth_Maybe =
52− Cipher_CardCipher_expMonth_Maybe (Maybe String)
53
21
54−derive instance newtypeCipher_CardCipher_expMonth_Maybe :: Newtype Cipher_CardCipher_expMonth_Maybe _
22+instance encodeJsonCmd_Login :: EncodeJson Cmd_Login where
55−instance encodeJsonCipher_CardCipher_expMonth_Maybe :: EncodeJson Cipher_CardCipher_expMonth_Maybe where
56 encodeJson = genericEncodeAeson Argonaut.defaultOptions
23 encodeJson = genericEncodeAeson Argonaut.defaultOptions
57−instance decodeJsonCipher_CardCipher_expMonth_Maybe :: DecodeJson Cipher_CardCipher_expMonth_Maybe where
24+instance decodeJsonCmd_Login :: DecodeJson Cmd_Login where
58 decodeJson = genericDecodeAeson Argonaut.defaultOptions
25 decodeJson = genericDecodeAeson Argonaut.defaultOptions
59−derive instance genericCipher_CardCipher_expMonth_Maybe :: Generic Cipher_CardCipher_expMonth_Maybe _
26+derive instance genericCmd_Login :: Generic Cmd_Login _
60−derive instance eqCipher_CardCipher_expMonth_Maybe :: Eq Cipher_CardCipher_expMonth_Maybe
27+derive instance eqCmd_Login :: Eq Cmd_Login
61−derive instance ordCipher_CardCipher_expMonth_Maybe :: Ord Cipher_CardCipher_expMonth_Maybe
28+derive instance ordCmd_Login :: Ord Cmd_Login
62
29
63−newtype Cipher_CardCipher_expYear_Maybe =
30+data Cmd =
64− Cipher_CardCipher_expYear_Maybe (Maybe String)
31+ Copy String
32+ | Init
33+ | Login Cmd_Login
34+ | NeedCiphersList
35+ | NeedEmail
36+ | NeedsReset
37+ | Open String
38+ | RequestCipher String
39+ | SendMasterPassword String
65
40
66−derive instance newtypeCipher_CardCipher_expYear_Maybe :: Newtype Cipher_CardCipher_expYear_Maybe _
41+instance encodeJsonCmd :: EncodeJson Cmd where
67−instance encodeJsonCipher_CardCipher_expYear_Maybe :: EncodeJson Cipher_CardCipher_expYear_Maybe where
68 encodeJson = genericEncodeAeson Argonaut.defaultOptions
42 encodeJson = genericEncodeAeson Argonaut.defaultOptions
69−instance decodeJsonCipher_CardCipher_expYear_Maybe :: DecodeJson Cipher_CardCipher_expYear_Maybe where
43+instance decodeJsonCmd :: DecodeJson Cmd where
70 decodeJson = genericDecodeAeson Argonaut.defaultOptions
44 decodeJson = genericDecodeAeson Argonaut.defaultOptions
71−derive instance genericCipher_CardCipher_expYear_Maybe :: Generic Cipher_CardCipher_expYear_Maybe _
45+derive instance genericCmd :: Generic Cmd _
72−derive instance eqCipher_CardCipher_expYear_Maybe :: Eq Cipher_CardCipher_expYear_Maybe
46+derive instance eqCmd :: Eq Cmd
73−derive instance ordCipher_CardCipher_expYear_Maybe :: Ord Cipher_CardCipher_expYear_Maybe
47+derive instance ordCmd :: Ord Cmd
74
48
75−newtype Cipher_CardCipher_number_Maybe =
49+newtype Sub_LoadCipher_cipherType_CardCipher_brand_Maybe =
76− Cipher_CardCipher_number_Maybe (Maybe String)
50+ Sub_LoadCipher_cipherType_CardCipher_brand_Maybe (Maybe String)
77
51
78−derive instance newtypeCipher_CardCipher_number_Maybe :: Newtype Cipher_CardCipher_number_Maybe _
52+instance encodeJsonSub_LoadCipher_cipherType_CardCipher_brand_Maybe :: EncodeJson Sub_LoadCipher_cipherType_CardCipher_brand_Maybe where
79−instance encodeJsonCipher_CardCipher_number_Maybe :: EncodeJson Cipher_CardCipher_number_Maybe where
80 encodeJson = genericEncodeAeson Argonaut.defaultOptions
53 encodeJson = genericEncodeAeson Argonaut.defaultOptions
81−instance decodeJsonCipher_CardCipher_number_Maybe :: DecodeJson Cipher_CardCipher_number_Maybe where
54+instance decodeJsonSub_LoadCipher_cipherType_CardCipher_brand_Maybe :: DecodeJson Sub_LoadCipher_cipherType_CardCipher_brand_Maybe where
82 decodeJson = genericDecodeAeson Argonaut.defaultOptions
55 decodeJson = genericDecodeAeson Argonaut.defaultOptions
83−derive instance genericCipher_CardCipher_number_Maybe :: Generic Cipher_CardCipher_number_Maybe _
56+derive instance genericSub_LoadCipher_cipherType_CardCipher_brand_Maybe :: Generic Sub_LoadCipher_cipherType_CardCipher_brand_Maybe _
84−derive instance eqCipher_CardCipher_number_Maybe :: Eq Cipher_CardCipher_number_Maybe
57+derive instance eqSub_LoadCipher_cipherType_CardCipher_brand_Maybe :: Eq Sub_LoadCipher_cipherType_CardCipher_brand_Maybe
85−derive instance ordCipher_CardCipher_number_Maybe :: Ord Cipher_CardCipher_number_Maybe
58+derive instance ordSub_LoadCipher_cipherType_CardCipher_brand_Maybe :: Ord Sub_LoadCipher_cipherType_CardCipher_brand_Maybe
86
59
87−newtype Cipher_CardCipher =
60+newtype Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe =
88− Cipher_CardCipher {
61+ Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe (Maybe String)
89− brand :: Cipher_CardCipher_brand_Maybe
90− , cardholderName :: Cipher_CardCipher_cardholderName_Maybe
91− , code :: Cipher_CardCipher_code_Maybe
92− , expMonth :: Cipher_CardCipher_expMonth_Maybe
93− , expYear :: Cipher_CardCipher_expYear_Maybe
94− , number :: Cipher_CardCipher_number_Maybe
95− }
96
62
97−derive instance newtypeCipher_CardCipher :: Newtype Cipher_CardCipher _
63+instance encodeJsonSub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe :: EncodeJson Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe where
98−instance encodeJsonCipher_CardCipher :: EncodeJson Cipher_CardCipher where
99 encodeJson = genericEncodeAeson Argonaut.defaultOptions
64 encodeJson = genericEncodeAeson Argonaut.defaultOptions
100−instance decodeJsonCipher_CardCipher :: DecodeJson Cipher_CardCipher where
65+instance decodeJsonSub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe :: DecodeJson Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe where
101 decodeJson = genericDecodeAeson Argonaut.defaultOptions
66 decodeJson = genericDecodeAeson Argonaut.defaultOptions
102−derive instance genericCipher_CardCipher :: Generic Cipher_CardCipher _
67+derive instance genericSub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe :: Generic Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe _
103−derive instance eqCipher_CardCipher :: Eq Cipher_CardCipher
68+derive instance eqSub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe :: Eq Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe
104−derive instance ordCipher_CardCipher :: Ord Cipher_CardCipher
69+derive instance ordSub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe :: Ord Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe
105
70
106−newtype Cipher_IdentityCipher_address1_Maybe =
71+newtype Sub_LoadCipher_cipherType_CardCipher_code_Maybe =
107− Cipher_IdentityCipher_address1_Maybe (Maybe String)
72+ Sub_LoadCipher_cipherType_CardCipher_code_Maybe (Maybe String)
108
73
109−derive instance newtypeCipher_IdentityCipher_address1_Maybe :: Newtype Cipher_IdentityCipher_address1_Maybe _
74+instance encodeJsonSub_LoadCipher_cipherType_CardCipher_code_Maybe :: EncodeJson Sub_LoadCipher_cipherType_CardCipher_code_Maybe where
110−instance encodeJsonCipher_IdentityCipher_address1_Maybe :: EncodeJson Cipher_IdentityCipher_address1_Maybe where
111 encodeJson = genericEncodeAeson Argonaut.defaultOptions
75 encodeJson = genericEncodeAeson Argonaut.defaultOptions
112−instance decodeJsonCipher_IdentityCipher_address1_Maybe :: DecodeJson Cipher_IdentityCipher_address1_Maybe where
76+instance decodeJsonSub_LoadCipher_cipherType_CardCipher_code_Maybe :: DecodeJson Sub_LoadCipher_cipherType_CardCipher_code_Maybe where
113 decodeJson = genericDecodeAeson Argonaut.defaultOptions
77 decodeJson = genericDecodeAeson Argonaut.defaultOptions
114−derive instance genericCipher_IdentityCipher_address1_Maybe :: Generic Cipher_IdentityCipher_address1_Maybe _
78+derive instance genericSub_LoadCipher_cipherType_CardCipher_code_Maybe :: Generic Sub_LoadCipher_cipherType_CardCipher_code_Maybe _
115−derive instance eqCipher_IdentityCipher_address1_Maybe :: Eq Cipher_IdentityCipher_address1_Maybe
79+derive instance eqSub_LoadCipher_cipherType_CardCipher_code_Maybe :: Eq Sub_LoadCipher_cipherType_CardCipher_code_Maybe
116−derive instance ordCipher_IdentityCipher_address1_Maybe :: Ord Cipher_IdentityCipher_address1_Maybe
80+derive instance ordSub_LoadCipher_cipherType_CardCipher_code_Maybe :: Ord Sub_LoadCipher_cipherType_CardCipher_code_Maybe
117
81
118−newtype Cipher_IdentityCipher_address2_Maybe =
82+newtype Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe =
119− Cipher_IdentityCipher_address2_Maybe (Maybe String)
83+ Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe (Maybe String)
120
84
121−derive instance newtypeCipher_IdentityCipher_address2_Maybe :: Newtype Cipher_IdentityCipher_address2_Maybe _
85+instance encodeJsonSub_LoadCipher_cipherType_CardCipher_expMonth_Maybe :: EncodeJson Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe where
122−instance encodeJsonCipher_IdentityCipher_address2_Maybe :: EncodeJson Cipher_IdentityCipher_address2_Maybe where
123 encodeJson = genericEncodeAeson Argonaut.defaultOptions
86 encodeJson = genericEncodeAeson Argonaut.defaultOptions
124−instance decodeJsonCipher_IdentityCipher_address2_Maybe :: DecodeJson Cipher_IdentityCipher_address2_Maybe where
87+instance decodeJsonSub_LoadCipher_cipherType_CardCipher_expMonth_Maybe :: DecodeJson Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe where
125 decodeJson = genericDecodeAeson Argonaut.defaultOptions
88 decodeJson = genericDecodeAeson Argonaut.defaultOptions
126−derive instance genericCipher_IdentityCipher_address2_Maybe :: Generic Cipher_IdentityCipher_address2_Maybe _
89+derive instance genericSub_LoadCipher_cipherType_CardCipher_expMonth_Maybe :: Generic Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe _
127−derive instance eqCipher_IdentityCipher_address2_Maybe :: Eq Cipher_IdentityCipher_address2_Maybe
90+derive instance eqSub_LoadCipher_cipherType_CardCipher_expMonth_Maybe :: Eq Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe
128−derive instance ordCipher_IdentityCipher_address2_Maybe :: Ord Cipher_IdentityCipher_address2_Maybe
91+derive instance ordSub_LoadCipher_cipherType_CardCipher_expMonth_Maybe :: Ord Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe
129
92
130−newtype Cipher_IdentityCipher_address3_Maybe =
93+newtype Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe =
131− Cipher_IdentityCipher_address3_Maybe (Maybe String)
94+ Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe (Maybe String)
132
95
133−derive instance newtypeCipher_IdentityCipher_address3_Maybe :: Newtype Cipher_IdentityCipher_address3_Maybe _
96+instance encodeJsonSub_LoadCipher_cipherType_CardCipher_expYear_Maybe :: EncodeJson Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe where
134−instance encodeJsonCipher_IdentityCipher_address3_Maybe :: EncodeJson Cipher_IdentityCipher_address3_Maybe where
135 encodeJson = genericEncodeAeson Argonaut.defaultOptions
97 encodeJson = genericEncodeAeson Argonaut.defaultOptions
136−instance decodeJsonCipher_IdentityCipher_address3_Maybe :: DecodeJson Cipher_IdentityCipher_address3_Maybe where
98+instance decodeJsonSub_LoadCipher_cipherType_CardCipher_expYear_Maybe :: DecodeJson Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe where
137 decodeJson = genericDecodeAeson Argonaut.defaultOptions
99 decodeJson = genericDecodeAeson Argonaut.defaultOptions
138−derive instance genericCipher_IdentityCipher_address3_Maybe :: Generic Cipher_IdentityCipher_address3_Maybe _
100+derive instance genericSub_LoadCipher_cipherType_CardCipher_expYear_Maybe :: Generic Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe _
139−derive instance eqCipher_IdentityCipher_address3_Maybe :: Eq Cipher_IdentityCipher_address3_Maybe
101+derive instance eqSub_LoadCipher_cipherType_CardCipher_expYear_Maybe :: Eq Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe
140−derive instance ordCipher_IdentityCipher_address3_Maybe :: Ord Cipher_IdentityCipher_address3_Maybe
102+derive instance ordSub_LoadCipher_cipherType_CardCipher_expYear_Maybe :: Ord Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe
141
103
142−newtype Cipher_IdentityCipher_city_Maybe =
104+newtype Sub_LoadCipher_cipherType_CardCipher_number_Maybe =
143− Cipher_IdentityCipher_city_Maybe (Maybe String)
105+ Sub_LoadCipher_cipherType_CardCipher_number_Maybe (Maybe String)
144
106
145−derive instance newtypeCipher_IdentityCipher_city_Maybe :: Newtype Cipher_IdentityCipher_city_Maybe _
107+instance encodeJsonSub_LoadCipher_cipherType_CardCipher_number_Maybe :: EncodeJson Sub_LoadCipher_cipherType_CardCipher_number_Maybe where
146−instance encodeJsonCipher_IdentityCipher_city_Maybe :: EncodeJson Cipher_IdentityCipher_city_Maybe where
147 encodeJson = genericEncodeAeson Argonaut.defaultOptions
108 encodeJson = genericEncodeAeson Argonaut.defaultOptions
148−instance decodeJsonCipher_IdentityCipher_city_Maybe :: DecodeJson Cipher_IdentityCipher_city_Maybe where
109+instance decodeJsonSub_LoadCipher_cipherType_CardCipher_number_Maybe :: DecodeJson Sub_LoadCipher_cipherType_CardCipher_number_Maybe where
149 decodeJson = genericDecodeAeson Argonaut.defaultOptions
110 decodeJson = genericDecodeAeson Argonaut.defaultOptions
150−derive instance genericCipher_IdentityCipher_city_Maybe :: Generic Cipher_IdentityCipher_city_Maybe _
111+derive instance genericSub_LoadCipher_cipherType_CardCipher_number_Maybe :: Generic Sub_LoadCipher_cipherType_CardCipher_number_Maybe _
151−derive instance eqCipher_IdentityCipher_city_Maybe :: Eq Cipher_IdentityCipher_city_Maybe
112+derive instance eqSub_LoadCipher_cipherType_CardCipher_number_Maybe :: Eq Sub_LoadCipher_cipherType_CardCipher_number_Maybe
152−derive instance ordCipher_IdentityCipher_city_Maybe :: Ord Cipher_IdentityCipher_city_Maybe
113+derive instance ordSub_LoadCipher_cipherType_CardCipher_number_Maybe :: Ord Sub_LoadCipher_cipherType_CardCipher_number_Maybe
153
114
154−newtype Cipher_IdentityCipher_company_Maybe =
115+newtype Sub_LoadCipher_cipherType_CardCipher =
155− Cipher_IdentityCipher_company_Maybe (Maybe String)
116+ Sub_LoadCipher_cipherType_CardCipher {
117+ brand :: Sub_LoadCipher_cipherType_CardCipher_brand_Maybe
118+ , cardholderName :: Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe
119+ , code :: Sub_LoadCipher_cipherType_CardCipher_code_Maybe
120+ , expMonth :: Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe
121+ , expYear :: Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe
122+ , number :: Sub_LoadCipher_cipherType_CardCipher_number_Maybe
123+ }
156
124
157−derive instance newtypeCipher_IdentityCipher_company_Maybe :: Newtype Cipher_IdentityCipher_company_Maybe _
125+instance encodeJsonSub_LoadCipher_cipherType_CardCipher :: EncodeJson Sub_LoadCipher_cipherType_CardCipher where
158−instance encodeJsonCipher_IdentityCipher_company_Maybe :: EncodeJson Cipher_IdentityCipher_company_Maybe where
159 encodeJson = genericEncodeAeson Argonaut.defaultOptions
126 encodeJson = genericEncodeAeson Argonaut.defaultOptions
160−instance decodeJsonCipher_IdentityCipher_company_Maybe :: DecodeJson Cipher_IdentityCipher_company_Maybe where
127+instance decodeJsonSub_LoadCipher_cipherType_CardCipher :: DecodeJson Sub_LoadCipher_cipherType_CardCipher where
161 decodeJson = genericDecodeAeson Argonaut.defaultOptions
128 decodeJson = genericDecodeAeson Argonaut.defaultOptions
162−derive instance genericCipher_IdentityCipher_company_Maybe :: Generic Cipher_IdentityCipher_company_Maybe _
129+derive instance genericSub_LoadCipher_cipherType_CardCipher :: Generic Sub_LoadCipher_cipherType_CardCipher _
163−derive instance eqCipher_IdentityCipher_company_Maybe :: Eq Cipher_IdentityCipher_company_Maybe
130+derive instance eqSub_LoadCipher_cipherType_CardCipher :: Eq Sub_LoadCipher_cipherType_CardCipher
164−derive instance ordCipher_IdentityCipher_company_Maybe :: Ord Cipher_IdentityCipher_company_Maybe
131+derive instance ordSub_LoadCipher_cipherType_CardCipher :: Ord Sub_LoadCipher_cipherType_CardCipher
165
132
166−newtype Cipher_IdentityCipher_country_Maybe =
133+newtype Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe =
167− Cipher_IdentityCipher_country_Maybe (Maybe String)
134+ Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe (Maybe String)
168
135
169−derive instance newtypeCipher_IdentityCipher_country_Maybe :: Newtype Cipher_IdentityCipher_country_Maybe _
136+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_address1_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe where
170−instance encodeJsonCipher_IdentityCipher_country_Maybe :: EncodeJson Cipher_IdentityCipher_country_Maybe where
171 encodeJson = genericEncodeAeson Argonaut.defaultOptions
137 encodeJson = genericEncodeAeson Argonaut.defaultOptions
172−instance decodeJsonCipher_IdentityCipher_country_Maybe :: DecodeJson Cipher_IdentityCipher_country_Maybe where
138+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_address1_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe where
173 decodeJson = genericDecodeAeson Argonaut.defaultOptions
139 decodeJson = genericDecodeAeson Argonaut.defaultOptions
174−derive instance genericCipher_IdentityCipher_country_Maybe :: Generic Cipher_IdentityCipher_country_Maybe _
140+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_address1_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe _
175−derive instance eqCipher_IdentityCipher_country_Maybe :: Eq Cipher_IdentityCipher_country_Maybe
141+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_address1_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe
176−derive instance ordCipher_IdentityCipher_country_Maybe :: Ord Cipher_IdentityCipher_country_Maybe
142+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_address1_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe
177
143
178−newtype Cipher_IdentityCipher_email_Maybe =
144+newtype Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe =
179− Cipher_IdentityCipher_email_Maybe (Maybe String)
145+ Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe (Maybe String)
180
146
181−derive instance newtypeCipher_IdentityCipher_email_Maybe :: Newtype Cipher_IdentityCipher_email_Maybe _
147+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_address2_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe where
182−instance encodeJsonCipher_IdentityCipher_email_Maybe :: EncodeJson Cipher_IdentityCipher_email_Maybe where
183 encodeJson = genericEncodeAeson Argonaut.defaultOptions
148 encodeJson = genericEncodeAeson Argonaut.defaultOptions
184−instance decodeJsonCipher_IdentityCipher_email_Maybe :: DecodeJson Cipher_IdentityCipher_email_Maybe where
149+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_address2_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe where
185 decodeJson = genericDecodeAeson Argonaut.defaultOptions
150 decodeJson = genericDecodeAeson Argonaut.defaultOptions
186−derive instance genericCipher_IdentityCipher_email_Maybe :: Generic Cipher_IdentityCipher_email_Maybe _
151+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_address2_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe _
187−derive instance eqCipher_IdentityCipher_email_Maybe :: Eq Cipher_IdentityCipher_email_Maybe
152+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_address2_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe
188−derive instance ordCipher_IdentityCipher_email_Maybe :: Ord Cipher_IdentityCipher_email_Maybe
153+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_address2_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe
189
154
190−newtype Cipher_IdentityCipher_firstName_Maybe =
155+newtype Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe =
191− Cipher_IdentityCipher_firstName_Maybe (Maybe String)
156+ Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe (Maybe String)
192
157
193−derive instance newtypeCipher_IdentityCipher_firstName_Maybe :: Newtype Cipher_IdentityCipher_firstName_Maybe _
158+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_address3_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe where
194−instance encodeJsonCipher_IdentityCipher_firstName_Maybe :: EncodeJson Cipher_IdentityCipher_firstName_Maybe where
195 encodeJson = genericEncodeAeson Argonaut.defaultOptions
159 encodeJson = genericEncodeAeson Argonaut.defaultOptions
196−instance decodeJsonCipher_IdentityCipher_firstName_Maybe :: DecodeJson Cipher_IdentityCipher_firstName_Maybe where
160+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_address3_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe where
197 decodeJson = genericDecodeAeson Argonaut.defaultOptions
161 decodeJson = genericDecodeAeson Argonaut.defaultOptions
198−derive instance genericCipher_IdentityCipher_firstName_Maybe :: Generic Cipher_IdentityCipher_firstName_Maybe _
162+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_address3_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe _
199−derive instance eqCipher_IdentityCipher_firstName_Maybe :: Eq Cipher_IdentityCipher_firstName_Maybe
163+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_address3_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe
200−derive instance ordCipher_IdentityCipher_firstName_Maybe :: Ord Cipher_IdentityCipher_firstName_Maybe
164+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_address3_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe
201
165
202−newtype Cipher_IdentityCipher_lastName_Maybe =
166+newtype Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe =
203− Cipher_IdentityCipher_lastName_Maybe (Maybe String)
167+ Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe (Maybe String)
204
168
205−derive instance newtypeCipher_IdentityCipher_lastName_Maybe :: Newtype Cipher_IdentityCipher_lastName_Maybe _
169+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_city_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe where
206−instance encodeJsonCipher_IdentityCipher_lastName_Maybe :: EncodeJson Cipher_IdentityCipher_lastName_Maybe where
207 encodeJson = genericEncodeAeson Argonaut.defaultOptions
170 encodeJson = genericEncodeAeson Argonaut.defaultOptions
208−instance decodeJsonCipher_IdentityCipher_lastName_Maybe :: DecodeJson Cipher_IdentityCipher_lastName_Maybe where
171+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_city_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe where
209 decodeJson = genericDecodeAeson Argonaut.defaultOptions
172 decodeJson = genericDecodeAeson Argonaut.defaultOptions
210−derive instance genericCipher_IdentityCipher_lastName_Maybe :: Generic Cipher_IdentityCipher_lastName_Maybe _
173+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_city_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe _
211−derive instance eqCipher_IdentityCipher_lastName_Maybe :: Eq Cipher_IdentityCipher_lastName_Maybe
174+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_city_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe
212−derive instance ordCipher_IdentityCipher_lastName_Maybe :: Ord Cipher_IdentityCipher_lastName_Maybe
175+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_city_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe
213
176
214−newtype Cipher_IdentityCipher_licenseNumber_Maybe =
177+newtype Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe =
215− Cipher_IdentityCipher_licenseNumber_Maybe (Maybe String)
178+ Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe (Maybe String)
216
179
217−derive instance newtypeCipher_IdentityCipher_licenseNumber_Maybe :: Newtype Cipher_IdentityCipher_licenseNumber_Maybe _
180+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_company_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe where
218−instance encodeJsonCipher_IdentityCipher_licenseNumber_Maybe :: EncodeJson Cipher_IdentityCipher_licenseNumber_Maybe where
219 encodeJson = genericEncodeAeson Argonaut.defaultOptions
181 encodeJson = genericEncodeAeson Argonaut.defaultOptions
220−instance decodeJsonCipher_IdentityCipher_licenseNumber_Maybe :: DecodeJson Cipher_IdentityCipher_licenseNumber_Maybe where
182+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_company_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe where
221 decodeJson = genericDecodeAeson Argonaut.defaultOptions
183 decodeJson = genericDecodeAeson Argonaut.defaultOptions
222−derive instance genericCipher_IdentityCipher_licenseNumber_Maybe :: Generic Cipher_IdentityCipher_licenseNumber_Maybe _
184+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_company_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe _
223−derive instance eqCipher_IdentityCipher_licenseNumber_Maybe :: Eq Cipher_IdentityCipher_licenseNumber_Maybe
185+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_company_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe
224−derive instance ordCipher_IdentityCipher_licenseNumber_Maybe :: Ord Cipher_IdentityCipher_licenseNumber_Maybe
186+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_company_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe
225
187
226−newtype Cipher_IdentityCipher_middleName_Maybe =
188+newtype Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe =
227− Cipher_IdentityCipher_middleName_Maybe (Maybe String)
189+ Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe (Maybe String)
228
190
229−derive instance newtypeCipher_IdentityCipher_middleName_Maybe :: Newtype Cipher_IdentityCipher_middleName_Maybe _
191+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_country_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe where
230−instance encodeJsonCipher_IdentityCipher_middleName_Maybe :: EncodeJson Cipher_IdentityCipher_middleName_Maybe where
231 encodeJson = genericEncodeAeson Argonaut.defaultOptions
192 encodeJson = genericEncodeAeson Argonaut.defaultOptions
232−instance decodeJsonCipher_IdentityCipher_middleName_Maybe :: DecodeJson Cipher_IdentityCipher_middleName_Maybe where
193+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_country_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe where
233 decodeJson = genericDecodeAeson Argonaut.defaultOptions
194 decodeJson = genericDecodeAeson Argonaut.defaultOptions
234−derive instance genericCipher_IdentityCipher_middleName_Maybe :: Generic Cipher_IdentityCipher_middleName_Maybe _
195+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_country_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe _
235−derive instance eqCipher_IdentityCipher_middleName_Maybe :: Eq Cipher_IdentityCipher_middleName_Maybe
196+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_country_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe
236−derive instance ordCipher_IdentityCipher_middleName_Maybe :: Ord Cipher_IdentityCipher_middleName_Maybe
197+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_country_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe
237
198
238−newtype Cipher_IdentityCipher_passportNumber_Maybe =
199+newtype Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe =
239− Cipher_IdentityCipher_passportNumber_Maybe (Maybe String)
200+ Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe (Maybe String)
240
201
241−derive instance newtypeCipher_IdentityCipher_passportNumber_Maybe :: Newtype Cipher_IdentityCipher_passportNumber_Maybe _
202+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_email_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe where
242−instance encodeJsonCipher_IdentityCipher_passportNumber_Maybe :: EncodeJson Cipher_IdentityCipher_passportNumber_Maybe where
243 encodeJson = genericEncodeAeson Argonaut.defaultOptions
203 encodeJson = genericEncodeAeson Argonaut.defaultOptions
244−instance decodeJsonCipher_IdentityCipher_passportNumber_Maybe :: DecodeJson Cipher_IdentityCipher_passportNumber_Maybe where
204+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_email_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe where
245 decodeJson = genericDecodeAeson Argonaut.defaultOptions
205 decodeJson = genericDecodeAeson Argonaut.defaultOptions
246−derive instance genericCipher_IdentityCipher_passportNumber_Maybe :: Generic Cipher_IdentityCipher_passportNumber_Maybe _
206+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_email_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe _
247−derive instance eqCipher_IdentityCipher_passportNumber_Maybe :: Eq Cipher_IdentityCipher_passportNumber_Maybe
207+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_email_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe
248−derive instance ordCipher_IdentityCipher_passportNumber_Maybe :: Ord Cipher_IdentityCipher_passportNumber_Maybe
208+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_email_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe
249
209
250−newtype Cipher_IdentityCipher_phone_Maybe =
210+newtype Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe =
251− Cipher_IdentityCipher_phone_Maybe (Maybe String)
211+ Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe (Maybe String)
252
212
253−derive instance newtypeCipher_IdentityCipher_phone_Maybe :: Newtype Cipher_IdentityCipher_phone_Maybe _
213+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe where
254−instance encodeJsonCipher_IdentityCipher_phone_Maybe :: EncodeJson Cipher_IdentityCipher_phone_Maybe where
255 encodeJson = genericEncodeAeson Argonaut.defaultOptions
214 encodeJson = genericEncodeAeson Argonaut.defaultOptions
256−instance decodeJsonCipher_IdentityCipher_phone_Maybe :: DecodeJson Cipher_IdentityCipher_phone_Maybe where
215+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe where
257 decodeJson = genericDecodeAeson Argonaut.defaultOptions
216 decodeJson = genericDecodeAeson Argonaut.defaultOptions
258−derive instance genericCipher_IdentityCipher_phone_Maybe :: Generic Cipher_IdentityCipher_phone_Maybe _
217+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe _
259−derive instance eqCipher_IdentityCipher_phone_Maybe :: Eq Cipher_IdentityCipher_phone_Maybe
218+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe
260−derive instance ordCipher_IdentityCipher_phone_Maybe :: Ord Cipher_IdentityCipher_phone_Maybe
219+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe
261
220
262−newtype Cipher_IdentityCipher_postalCode_Maybe =
221+newtype Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe =
263− Cipher_IdentityCipher_postalCode_Maybe (Maybe String)
222+ Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe (Maybe String)
264
223
265−derive instance newtypeCipher_IdentityCipher_postalCode_Maybe :: Newtype Cipher_IdentityCipher_postalCode_Maybe _
224+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe where
266−instance encodeJsonCipher_IdentityCipher_postalCode_Maybe :: EncodeJson Cipher_IdentityCipher_postalCode_Maybe where
267 encodeJson = genericEncodeAeson Argonaut.defaultOptions
225 encodeJson = genericEncodeAeson Argonaut.defaultOptions
268−instance decodeJsonCipher_IdentityCipher_postalCode_Maybe :: DecodeJson Cipher_IdentityCipher_postalCode_Maybe where
226+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe where
269 decodeJson = genericDecodeAeson Argonaut.defaultOptions
227 decodeJson = genericDecodeAeson Argonaut.defaultOptions
270−derive instance genericCipher_IdentityCipher_postalCode_Maybe :: Generic Cipher_IdentityCipher_postalCode_Maybe _
228+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe _
271−derive instance eqCipher_IdentityCipher_postalCode_Maybe :: Eq Cipher_IdentityCipher_postalCode_Maybe
229+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe
272−derive instance ordCipher_IdentityCipher_postalCode_Maybe :: Ord Cipher_IdentityCipher_postalCode_Maybe
230+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe
273
231
274−newtype Cipher_IdentityCipher_ssn_Maybe =
232+newtype Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe =
275− Cipher_IdentityCipher_ssn_Maybe (Maybe String)
233+ Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe (Maybe String)
276
234
277−derive instance newtypeCipher_IdentityCipher_ssn_Maybe :: Newtype Cipher_IdentityCipher_ssn_Maybe _
235+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe where
278−instance encodeJsonCipher_IdentityCipher_ssn_Maybe :: EncodeJson Cipher_IdentityCipher_ssn_Maybe where
279 encodeJson = genericEncodeAeson Argonaut.defaultOptions
236 encodeJson = genericEncodeAeson Argonaut.defaultOptions
280−instance decodeJsonCipher_IdentityCipher_ssn_Maybe :: DecodeJson Cipher_IdentityCipher_ssn_Maybe where
237+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe where
281 decodeJson = genericDecodeAeson Argonaut.defaultOptions
238 decodeJson = genericDecodeAeson Argonaut.defaultOptions
282−derive instance genericCipher_IdentityCipher_ssn_Maybe :: Generic Cipher_IdentityCipher_ssn_Maybe _
239+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe _
283−derive instance eqCipher_IdentityCipher_ssn_Maybe :: Eq Cipher_IdentityCipher_ssn_Maybe
240+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe
284−derive instance ordCipher_IdentityCipher_ssn_Maybe :: Ord Cipher_IdentityCipher_ssn_Maybe
241+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe
285
242
286−newtype Cipher_IdentityCipher_state_Maybe =
243+newtype Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe =
287− Cipher_IdentityCipher_state_Maybe (Maybe String)
244+ Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe (Maybe String)
288
245
289−derive instance newtypeCipher_IdentityCipher_state_Maybe :: Newtype Cipher_IdentityCipher_state_Maybe _
246+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe where
290−instance encodeJsonCipher_IdentityCipher_state_Maybe :: EncodeJson Cipher_IdentityCipher_state_Maybe where
291 encodeJson = genericEncodeAeson Argonaut.defaultOptions
247 encodeJson = genericEncodeAeson Argonaut.defaultOptions
292−instance decodeJsonCipher_IdentityCipher_state_Maybe :: DecodeJson Cipher_IdentityCipher_state_Maybe where
248+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe where
293 decodeJson = genericDecodeAeson Argonaut.defaultOptions
249 decodeJson = genericDecodeAeson Argonaut.defaultOptions
294−derive instance genericCipher_IdentityCipher_state_Maybe :: Generic Cipher_IdentityCipher_state_Maybe _
250+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe _
295−derive instance eqCipher_IdentityCipher_state_Maybe :: Eq Cipher_IdentityCipher_state_Maybe
251+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe
296−derive instance ordCipher_IdentityCipher_state_Maybe :: Ord Cipher_IdentityCipher_state_Maybe
252+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe
297
253
298−newtype Cipher_IdentityCipher_title_Maybe =
254+newtype Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe =
299− Cipher_IdentityCipher_title_Maybe (Maybe String)
255+ Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe (Maybe String)
300
256
301−derive instance newtypeCipher_IdentityCipher_title_Maybe :: Newtype Cipher_IdentityCipher_title_Maybe _
257+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe where
302−instance encodeJsonCipher_IdentityCipher_title_Maybe :: EncodeJson Cipher_IdentityCipher_title_Maybe where
303 encodeJson = genericEncodeAeson Argonaut.defaultOptions
258 encodeJson = genericEncodeAeson Argonaut.defaultOptions
304−instance decodeJsonCipher_IdentityCipher_title_Maybe :: DecodeJson Cipher_IdentityCipher_title_Maybe where
259+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe where
305 decodeJson = genericDecodeAeson Argonaut.defaultOptions
260 decodeJson = genericDecodeAeson Argonaut.defaultOptions
306−derive instance genericCipher_IdentityCipher_title_Maybe :: Generic Cipher_IdentityCipher_title_Maybe _
261+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe _
307−derive instance eqCipher_IdentityCipher_title_Maybe :: Eq Cipher_IdentityCipher_title_Maybe
262+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe
308−derive instance ordCipher_IdentityCipher_title_Maybe :: Ord Cipher_IdentityCipher_title_Maybe
263+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe
309
264
310−newtype Cipher_IdentityCipher_username_Maybe =
265+newtype Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe =
311− Cipher_IdentityCipher_username_Maybe (Maybe String)
266+ Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe (Maybe String)
312
267
313−derive instance newtypeCipher_IdentityCipher_username_Maybe :: Newtype Cipher_IdentityCipher_username_Maybe _
268+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_phone_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe where
314−instance encodeJsonCipher_IdentityCipher_username_Maybe :: EncodeJson Cipher_IdentityCipher_username_Maybe where
315 encodeJson = genericEncodeAeson Argonaut.defaultOptions
269 encodeJson = genericEncodeAeson Argonaut.defaultOptions
316−instance decodeJsonCipher_IdentityCipher_username_Maybe :: DecodeJson Cipher_IdentityCipher_username_Maybe where
270+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_phone_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe where
317 decodeJson = genericDecodeAeson Argonaut.defaultOptions
271 decodeJson = genericDecodeAeson Argonaut.defaultOptions
318−derive instance genericCipher_IdentityCipher_username_Maybe :: Generic Cipher_IdentityCipher_username_Maybe _
272+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_phone_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe _
319−derive instance eqCipher_IdentityCipher_username_Maybe :: Eq Cipher_IdentityCipher_username_Maybe
273+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_phone_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe
320−derive instance ordCipher_IdentityCipher_username_Maybe :: Ord Cipher_IdentityCipher_username_Maybe
274+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_phone_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe
321
275
322−newtype Cipher_IdentityCipher =
276+newtype Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe =
323− Cipher_IdentityCipher {
277+ Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe (Maybe String)
324− address1 :: Cipher_IdentityCipher_address1_Maybe
325− , address2 :: Cipher_IdentityCipher_address2_Maybe
326− , address3 :: Cipher_IdentityCipher_address3_Maybe
327− , city :: Cipher_IdentityCipher_city_Maybe
328− , company :: Cipher_IdentityCipher_company_Maybe
329− , country :: Cipher_IdentityCipher_country_Maybe
330− , email :: Cipher_IdentityCipher_email_Maybe
331− , firstName :: Cipher_IdentityCipher_firstName_Maybe
332− , lastName :: Cipher_IdentityCipher_lastName_Maybe
333− , licenseNumber :: Cipher_IdentityCipher_licenseNumber_Maybe
334− , middleName :: Cipher_IdentityCipher_middleName_Maybe
335− , passportNumber :: Cipher_IdentityCipher_passportNumber_Maybe
336− , phone :: Cipher_IdentityCipher_phone_Maybe
337− , postalCode :: Cipher_IdentityCipher_postalCode_Maybe
338− , ssn :: Cipher_IdentityCipher_ssn_Maybe
339− , state :: Cipher_IdentityCipher_state_Maybe
340− , title :: Cipher_IdentityCipher_title_Maybe
341− , username :: Cipher_IdentityCipher_username_Maybe
342− }
343
278
344−derive instance newtypeCipher_IdentityCipher :: Newtype Cipher_IdentityCipher _
279+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe where
345−instance encodeJsonCipher_IdentityCipher :: EncodeJson Cipher_IdentityCipher where
346 encodeJson = genericEncodeAeson Argonaut.defaultOptions
280 encodeJson = genericEncodeAeson Argonaut.defaultOptions
347−instance decodeJsonCipher_IdentityCipher :: DecodeJson Cipher_IdentityCipher where
281+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe where
348 decodeJson = genericDecodeAeson Argonaut.defaultOptions
282 decodeJson = genericDecodeAeson Argonaut.defaultOptions
349−derive instance genericCipher_IdentityCipher :: Generic Cipher_IdentityCipher _
283+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe _
350−derive instance eqCipher_IdentityCipher :: Eq Cipher_IdentityCipher
284+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe
351−derive instance ordCipher_IdentityCipher :: Ord Cipher_IdentityCipher
285+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe
352
286
353−newtype Cipher_LoginCipher_password_Maybe =
287+newtype Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe =
354− Cipher_LoginCipher_password_Maybe (Maybe String)
288+ Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe (Maybe String)
355
289
356−derive instance newtypeCipher_LoginCipher_password_Maybe :: Newtype Cipher_LoginCipher_password_Maybe _
290+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe where
357−instance encodeJsonCipher_LoginCipher_password_Maybe :: EncodeJson Cipher_LoginCipher_password_Maybe where
358 encodeJson = genericEncodeAeson Argonaut.defaultOptions
291 encodeJson = genericEncodeAeson Argonaut.defaultOptions
359−instance decodeJsonCipher_LoginCipher_password_Maybe :: DecodeJson Cipher_LoginCipher_password_Maybe where
292+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe where
360 decodeJson = genericDecodeAeson Argonaut.defaultOptions
293 decodeJson = genericDecodeAeson Argonaut.defaultOptions
361−derive instance genericCipher_LoginCipher_password_Maybe :: Generic Cipher_LoginCipher_password_Maybe _
294+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe _
362−derive instance eqCipher_LoginCipher_password_Maybe :: Eq Cipher_LoginCipher_password_Maybe
295+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe
363−derive instance ordCipher_LoginCipher_password_Maybe :: Ord Cipher_LoginCipher_password_Maybe
296+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe
364
297
365−newtype Cipher_LoginCipher_totp_Maybe =
298+newtype Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe =
366− Cipher_LoginCipher_totp_Maybe (Maybe String)
299+ Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe (Maybe String)
367
300
368−derive instance newtypeCipher_LoginCipher_totp_Maybe :: Newtype Cipher_LoginCipher_totp_Maybe _
301+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_state_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe where
369−instance encodeJsonCipher_LoginCipher_totp_Maybe :: EncodeJson Cipher_LoginCipher_totp_Maybe where
370 encodeJson = genericEncodeAeson Argonaut.defaultOptions
302 encodeJson = genericEncodeAeson Argonaut.defaultOptions
371−instance decodeJsonCipher_LoginCipher_totp_Maybe :: DecodeJson Cipher_LoginCipher_totp_Maybe where
303+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_state_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe where
372 decodeJson = genericDecodeAeson Argonaut.defaultOptions
304 decodeJson = genericDecodeAeson Argonaut.defaultOptions
373−derive instance genericCipher_LoginCipher_totp_Maybe :: Generic Cipher_LoginCipher_totp_Maybe _
305+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_state_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe _
374−derive instance eqCipher_LoginCipher_totp_Maybe :: Eq Cipher_LoginCipher_totp_Maybe
306+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_state_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe
375−derive instance ordCipher_LoginCipher_totp_Maybe :: Ord Cipher_LoginCipher_totp_Maybe
307+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_state_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe
376
308
377−newtype Cipher_LoginCipher_uris_List =
309+newtype Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe =
378− Cipher_LoginCipher_uris_List (Array String)
310+ Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe (Maybe String)
379
311
380−derive instance newtypeCipher_LoginCipher_uris_List :: Newtype Cipher_LoginCipher_uris_List _
312+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_title_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe where
381−instance encodeJsonCipher_LoginCipher_uris_List :: EncodeJson Cipher_LoginCipher_uris_List where
382 encodeJson = genericEncodeAeson Argonaut.defaultOptions
313 encodeJson = genericEncodeAeson Argonaut.defaultOptions
383−instance decodeJsonCipher_LoginCipher_uris_List :: DecodeJson Cipher_LoginCipher_uris_List where
314+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_title_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe where
384 decodeJson = genericDecodeAeson Argonaut.defaultOptions
315 decodeJson = genericDecodeAeson Argonaut.defaultOptions
385−derive instance genericCipher_LoginCipher_uris_List :: Generic Cipher_LoginCipher_uris_List _
316+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_title_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe _
386−derive instance eqCipher_LoginCipher_uris_List :: Eq Cipher_LoginCipher_uris_List
317+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_title_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe
387−derive instance ordCipher_LoginCipher_uris_List :: Ord Cipher_LoginCipher_uris_List
318+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_title_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe
388
319
389−newtype Cipher_LoginCipher_username_Maybe =
320+newtype Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe =
390− Cipher_LoginCipher_username_Maybe (Maybe String)
321+ Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe (Maybe String)
391
322
392−derive instance newtypeCipher_LoginCipher_username_Maybe :: Newtype Cipher_LoginCipher_username_Maybe _
323+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher_username_Maybe :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe where
393−instance encodeJsonCipher_LoginCipher_username_Maybe :: EncodeJson Cipher_LoginCipher_username_Maybe where
394 encodeJson = genericEncodeAeson Argonaut.defaultOptions
324 encodeJson = genericEncodeAeson Argonaut.defaultOptions
395−instance decodeJsonCipher_LoginCipher_username_Maybe :: DecodeJson Cipher_LoginCipher_username_Maybe where
325+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher_username_Maybe :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe where
396 decodeJson = genericDecodeAeson Argonaut.defaultOptions
326 decodeJson = genericDecodeAeson Argonaut.defaultOptions
397−derive instance genericCipher_LoginCipher_username_Maybe :: Generic Cipher_LoginCipher_username_Maybe _
327+derive instance genericSub_LoadCipher_cipherType_IdentityCipher_username_Maybe :: Generic Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe _
398−derive instance eqCipher_LoginCipher_username_Maybe :: Eq Cipher_LoginCipher_username_Maybe
328+derive instance eqSub_LoadCipher_cipherType_IdentityCipher_username_Maybe :: Eq Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe
399−derive instance ordCipher_LoginCipher_username_Maybe :: Ord Cipher_LoginCipher_username_Maybe
329+derive instance ordSub_LoadCipher_cipherType_IdentityCipher_username_Maybe :: Ord Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe
400
330
401−newtype Cipher_LoginCipher =
331+newtype Sub_LoadCipher_cipherType_IdentityCipher =
402− Cipher_LoginCipher {
332+ Sub_LoadCipher_cipherType_IdentityCipher {
403− password :: Cipher_LoginCipher_password_Maybe
333+ address1 :: Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe
404− , totp :: Cipher_LoginCipher_totp_Maybe
334+ , address2 :: Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe
405− , uris :: Cipher_LoginCipher_uris_List
335+ , address3 :: Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe
406− , username :: Cipher_LoginCipher_username_Maybe
336+ , city :: Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe
337+ , company :: Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe
338+ , country :: Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe
339+ , email :: Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe
340+ , firstName :: Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe
341+ , lastName :: Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe
342+ , licenseNumber :: Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe
343+ , middleName :: Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe
344+ , passportNumber :: Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe
345+ , phone :: Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe
346+ , postalCode :: Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe
347+ , ssn :: Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe
348+ , state :: Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe
349+ , title :: Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe
350+ , username :: Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe
407 }
351 }
408
352
409−derive instance newtypeCipher_LoginCipher :: Newtype Cipher_LoginCipher _
353+instance encodeJsonSub_LoadCipher_cipherType_IdentityCipher :: EncodeJson Sub_LoadCipher_cipherType_IdentityCipher where
410−instance encodeJsonCipher_LoginCipher :: EncodeJson Cipher_LoginCipher where
411 encodeJson = genericEncodeAeson Argonaut.defaultOptions
354 encodeJson = genericEncodeAeson Argonaut.defaultOptions
412−instance decodeJsonCipher_LoginCipher :: DecodeJson Cipher_LoginCipher where
355+instance decodeJsonSub_LoadCipher_cipherType_IdentityCipher :: DecodeJson Sub_LoadCipher_cipherType_IdentityCipher where
413 decodeJson = genericDecodeAeson Argonaut.defaultOptions
356 decodeJson = genericDecodeAeson Argonaut.defaultOptions
414−derive instance genericCipher_LoginCipher :: Generic Cipher_LoginCipher _
357+derive instance genericSub_LoadCipher_cipherType_IdentityCipher :: Generic Sub_LoadCipher_cipherType_IdentityCipher _
415−derive instance eqCipher_LoginCipher :: Eq Cipher_LoginCipher
358+derive instance eqSub_LoadCipher_cipherType_IdentityCipher :: Eq Sub_LoadCipher_cipherType_IdentityCipher
416−derive instance ordCipher_LoginCipher :: Ord Cipher_LoginCipher
359+derive instance ordSub_LoadCipher_cipherType_IdentityCipher :: Ord Sub_LoadCipher_cipherType_IdentityCipher
417
360
418−data Cipher =
361+newtype Sub_LoadCipher_cipherType_LoginCipher_password_Maybe =
419− CardCipher Cipher_CardCipher
362+ Sub_LoadCipher_cipherType_LoginCipher_password_Maybe (Maybe String)
420− | IdentityCipher Cipher_IdentityCipher
421− | LoginCipher Cipher_LoginCipher
422− | NoteCipher String
423
363
424−instance encodeJsonCipher :: EncodeJson Cipher where
364+instance encodeJsonSub_LoadCipher_cipherType_LoginCipher_password_Maybe :: EncodeJson Sub_LoadCipher_cipherType_LoginCipher_password_Maybe where
425 encodeJson = genericEncodeAeson Argonaut.defaultOptions
365 encodeJson = genericEncodeAeson Argonaut.defaultOptions
426−instance decodeJsonCipher :: DecodeJson Cipher where
366+instance decodeJsonSub_LoadCipher_cipherType_LoginCipher_password_Maybe :: DecodeJson Sub_LoadCipher_cipherType_LoginCipher_password_Maybe where
427 decodeJson = genericDecodeAeson Argonaut.defaultOptions
367 decodeJson = genericDecodeAeson Argonaut.defaultOptions
428−derive instance genericCipher :: Generic Cipher _
368+derive instance genericSub_LoadCipher_cipherType_LoginCipher_password_Maybe :: Generic Sub_LoadCipher_cipherType_LoginCipher_password_Maybe _
429−derive instance eqCipher :: Eq Cipher
369+derive instance eqSub_LoadCipher_cipherType_LoginCipher_password_Maybe :: Eq Sub_LoadCipher_cipherType_LoginCipher_password_Maybe
430−derive instance ordCipher :: Ord Cipher
370+derive instance ordSub_LoadCipher_cipherType_LoginCipher_password_Maybe :: Ord Sub_LoadCipher_cipherType_LoginCipher_password_Maybe
431
371
432−data CipherType =
372+newtype Sub_LoadCipher_cipherType_LoginCipher_uris_List =
433− CardType
373+ Sub_LoadCipher_cipherType_LoginCipher_uris_List (Array String)
434− | IdentityType
435− | LoginType
436− | NoteType
437
374
438−instance encodeJsonCipherType :: EncodeJson CipherType where
375+instance encodeJsonSub_LoadCipher_cipherType_LoginCipher_uris_List :: EncodeJson Sub_LoadCipher_cipherType_LoginCipher_uris_List where
439 encodeJson = genericEncodeAeson Argonaut.defaultOptions
376 encodeJson = genericEncodeAeson Argonaut.defaultOptions
440−instance decodeJsonCipherType :: DecodeJson CipherType where
377+instance decodeJsonSub_LoadCipher_cipherType_LoginCipher_uris_List :: DecodeJson Sub_LoadCipher_cipherType_LoginCipher_uris_List where
441 decodeJson = genericDecodeAeson Argonaut.defaultOptions
378 decodeJson = genericDecodeAeson Argonaut.defaultOptions
442−derive instance genericCipherType :: Generic CipherType _
379+derive instance genericSub_LoadCipher_cipherType_LoginCipher_uris_List :: Generic Sub_LoadCipher_cipherType_LoginCipher_uris_List _
443−derive instance eqCipherType :: Eq CipherType
380+derive instance eqSub_LoadCipher_cipherType_LoginCipher_uris_List :: Eq Sub_LoadCipher_cipherType_LoginCipher_uris_List
444−derive instance ordCipherType :: Ord CipherType
381+derive instance ordSub_LoadCipher_cipherType_LoginCipher_uris_List :: Ord Sub_LoadCipher_cipherType_LoginCipher_uris_List
445
382
446−newtype Cmd_ChooseSecondFactor =
383+newtype Sub_LoadCipher_cipherType_LoginCipher_username_Maybe =
447− Cmd_ChooseSecondFactor {
384+ Sub_LoadCipher_cipherType_LoginCipher_username_Maybe (Maybe String)
448− email :: String
449− , factor :: TwoFactorProviderType
450− , password :: String
451− , requestFromServer :: Boolean
452− , server :: String
453− }
454
385
455−derive instance newtypeCmd_ChooseSecondFactor :: Newtype Cmd_ChooseSecondFactor _
386+instance encodeJsonSub_LoadCipher_cipherType_LoginCipher_username_Maybe :: EncodeJson Sub_LoadCipher_cipherType_LoginCipher_username_Maybe where
456−instance encodeJsonCmd_ChooseSecondFactor :: EncodeJson Cmd_ChooseSecondFactor where
457 encodeJson = genericEncodeAeson Argonaut.defaultOptions
387 encodeJson = genericEncodeAeson Argonaut.defaultOptions
458−instance decodeJsonCmd_ChooseSecondFactor :: DecodeJson Cmd_ChooseSecondFactor where
388+instance decodeJsonSub_LoadCipher_cipherType_LoginCipher_username_Maybe :: DecodeJson Sub_LoadCipher_cipherType_LoginCipher_username_Maybe where
459 decodeJson = genericDecodeAeson Argonaut.defaultOptions
389 decodeJson = genericDecodeAeson Argonaut.defaultOptions
460−derive instance genericCmd_ChooseSecondFactor :: Generic Cmd_ChooseSecondFactor _
390+derive instance genericSub_LoadCipher_cipherType_LoginCipher_username_Maybe :: Generic Sub_LoadCipher_cipherType_LoginCipher_username_Maybe _
461−derive instance eqCmd_ChooseSecondFactor :: Eq Cmd_ChooseSecondFactor
391+derive instance eqSub_LoadCipher_cipherType_LoginCipher_username_Maybe :: Eq Sub_LoadCipher_cipherType_LoginCipher_username_Maybe
462−derive instance ordCmd_ChooseSecondFactor :: Ord Cmd_ChooseSecondFactor
392+derive instance ordSub_LoadCipher_cipherType_LoginCipher_username_Maybe :: Ord Sub_LoadCipher_cipherType_LoginCipher_username_Maybe
463
393
464−newtype Cmd_Login_secondFactor =
394+newtype Sub_LoadCipher_cipherType_LoginCipher =
465− Cmd_Login_secondFactor {
395+ Sub_LoadCipher_cipherType_LoginCipher {
466− provider :: TwoFactorProviderType
396+ password :: Sub_LoadCipher_cipherType_LoginCipher_password_Maybe
467− , remember :: Boolean
397+ , uris :: Sub_LoadCipher_cipherType_LoginCipher_uris_List
468− , token :: String
398+ , username :: Sub_LoadCipher_cipherType_LoginCipher_username_Maybe
469 }
399 }
470
400
471−derive instance newtypeCmd_Login_secondFactor :: Newtype Cmd_Login_secondFactor _
401+instance encodeJsonSub_LoadCipher_cipherType_LoginCipher :: EncodeJson Sub_LoadCipher_cipherType_LoginCipher where
472−instance encodeJsonCmd_Login_secondFactor :: EncodeJson Cmd_Login_secondFactor where
473 encodeJson = genericEncodeAeson Argonaut.defaultOptions
402 encodeJson = genericEncodeAeson Argonaut.defaultOptions
474−instance decodeJsonCmd_Login_secondFactor :: DecodeJson Cmd_Login_secondFactor where
403+instance decodeJsonSub_LoadCipher_cipherType_LoginCipher :: DecodeJson Sub_LoadCipher_cipherType_LoginCipher where
475 decodeJson = genericDecodeAeson Argonaut.defaultOptions
404 decodeJson = genericDecodeAeson Argonaut.defaultOptions
476−derive instance genericCmd_Login_secondFactor :: Generic Cmd_Login_secondFactor _
405+derive instance genericSub_LoadCipher_cipherType_LoginCipher :: Generic Sub_LoadCipher_cipherType_LoginCipher _
477−derive instance eqCmd_Login_secondFactor :: Eq Cmd_Login_secondFactor
406+derive instance eqSub_LoadCipher_cipherType_LoginCipher :: Eq Sub_LoadCipher_cipherType_LoginCipher
478−derive instance ordCmd_Login_secondFactor :: Ord Cmd_Login_secondFactor
407+derive instance ordSub_LoadCipher_cipherType_LoginCipher :: Ord Sub_LoadCipher_cipherType_LoginCipher
479
408
480−newtype Cmd_Login_secondFactor_Maybe =
409+data Sub_LoadCipher_cipherType =
481− Cmd_Login_secondFactor_Maybe (Maybe Cmd_Login_secondFactor)
410+ CardCipher Sub_LoadCipher_cipherType_CardCipher
411+ | IdentityCipher Sub_LoadCipher_cipherType_IdentityCipher
412+ | LoginCipher Sub_LoadCipher_cipherType_LoginCipher
413+ | NoteCipher String
482
414
483−derive instance newtypeCmd_Login_secondFactor_Maybe :: Newtype Cmd_Login_secondFactor_Maybe _
415+instance encodeJsonSub_LoadCipher_cipherType :: EncodeJson Sub_LoadCipher_cipherType where
484−instance encodeJsonCmd_Login_secondFactor_Maybe :: EncodeJson Cmd_Login_secondFactor_Maybe where
485 encodeJson = genericEncodeAeson Argonaut.defaultOptions
416 encodeJson = genericEncodeAeson Argonaut.defaultOptions
486−instance decodeJsonCmd_Login_secondFactor_Maybe :: DecodeJson Cmd_Login_secondFactor_Maybe where
417+instance decodeJsonSub_LoadCipher_cipherType :: DecodeJson Sub_LoadCipher_cipherType where
487 decodeJson = genericDecodeAeson Argonaut.defaultOptions
418 decodeJson = genericDecodeAeson Argonaut.defaultOptions
488−derive instance genericCmd_Login_secondFactor_Maybe :: Generic Cmd_Login_secondFactor_Maybe _
419+derive instance genericSub_LoadCipher_cipherType :: Generic Sub_LoadCipher_cipherType _
489−derive instance eqCmd_Login_secondFactor_Maybe :: Eq Cmd_Login_secondFactor_Maybe
420+derive instance eqSub_LoadCipher_cipherType :: Eq Sub_LoadCipher_cipherType
490−derive instance ordCmd_Login_secondFactor_Maybe :: Ord Cmd_Login_secondFactor_Maybe
421+derive instance ordSub_LoadCipher_cipherType :: Ord Sub_LoadCipher_cipherType
491
422
492−newtype Cmd_Login =
423+newtype Sub_LoadCipher =
493− Cmd_Login {
424+ Sub_LoadCipher {
494− email :: String
425+ cipherType :: Sub_LoadCipher_cipherType
495− , password :: String
426+ , id :: String
496− , secondFactor :: Cmd_Login_secondFactor_Maybe
497− , server :: String
427+ , name :: String
498 }
428 }
499
429
500−derive instance newtypeCmd_Login :: Newtype Cmd_Login _
430+instance encodeJsonSub_LoadCipher :: EncodeJson Sub_LoadCipher where
501−instance encodeJsonCmd_Login :: EncodeJson Cmd_Login where
502 encodeJson = genericEncodeAeson Argonaut.defaultOptions
431 encodeJson = genericEncodeAeson Argonaut.defaultOptions
503−instance decodeJsonCmd_Login :: DecodeJson Cmd_Login where
432+instance decodeJsonSub_LoadCipher :: DecodeJson Sub_LoadCipher where
504 decodeJson = genericDecodeAeson Argonaut.defaultOptions
433 decodeJson = genericDecodeAeson Argonaut.defaultOptions
505−derive instance genericCmd_Login :: Generic Cmd_Login _
434+derive instance genericSub_LoadCipher :: Generic Sub_LoadCipher _
506−derive instance eqCmd_Login :: Eq Cmd_Login
507−derive instance ordCmd_Login :: Ord Cmd_Login
508−
509−data Cmd =
510− ChooseSecondFactor Cmd_ChooseSecondFactor
511− | Copy String
512− | CreateCipher FullCipher
513− | DeleteCipher FullCipher
514− | GeneratePassword PasswordGeneratorConfig
515− | Init
516− | Login Cmd_Login
517− | NeedCiphersList
518− | NeedEmail
519− | NeedsReset
520− | Open String
521− | RequestCipher String
522− | RequestTotp String
523− | SendMasterPassword String
524− | UpdateCipher FullCipher
525−
526−instance encodeJsonCmd :: EncodeJson Cmd where
527− encodeJson = genericEncodeAeson Argonaut.defaultOptions
528−instance decodeJsonCmd :: DecodeJson Cmd where
529− decodeJson = genericDecodeAeson Argonaut.defaultOptions
530−derive instance genericCmd :: Generic Cmd _
531−derive instance eqCmd :: Eq Cmd
435+derive instance eqSub_LoadCipher :: Eq Sub_LoadCipher
532−derive instance ordCmd :: Ord Cmd
436+derive instance ordSub_LoadCipher :: Ord Sub_LoadCipher
533
437
534−newtype FullCipher_collectionIds_List =
438+data Sub_LoadCiphers_cipherType =
535− FullCipher_collectionIds_List (Array String)
439+ CardType
536−
440+ | IdentityType
537−derive instance newtypeFullCipher_collectionIds_List :: Newtype FullCipher_collectionIds_List _
441+ | LoginType
538−instance encodeJsonFullCipher_collectionIds_List :: EncodeJson FullCipher_collectionIds_List where
442+ | NoteType
539− encodeJson = genericEncodeAeson Argonaut.defaultOptions
540−instance decodeJsonFullCipher_collectionIds_List :: DecodeJson FullCipher_collectionIds_List where
541− decodeJson = genericDecodeAeson Argonaut.defaultOptions
542−derive instance genericFullCipher_collectionIds_List :: Generic FullCipher_collectionIds_List _
543−derive instance eqFullCipher_collectionIds_List :: Eq FullCipher_collectionIds_List
544−derive instance ordFullCipher_collectionIds_List :: Ord FullCipher_collectionIds_List
545−
546−newtype FullCipher =
547− FullCipher {
548− cipher :: Cipher
549− , collectionIds :: FullCipher_collectionIds_List
550− , favorite :: Boolean
551− , id :: String
552− , name :: String
553− , reprompt :: Int
554− }
555−
556−derive instance newtypeFullCipher :: Newtype FullCipher _
557−instance encodeJsonFullCipher :: EncodeJson FullCipher where
558− encodeJson = genericEncodeAeson Argonaut.defaultOptions
559−instance decodeJsonFullCipher :: DecodeJson FullCipher where
560− decodeJson = genericDecodeAeson Argonaut.defaultOptions
561−derive instance genericFullCipher :: Generic FullCipher _
562−derive instance eqFullCipher :: Eq FullCipher
563−derive instance ordFullCipher :: Ord FullCipher
564−
565−newtype PasswordGeneratorConfig =
566− PasswordGeneratorConfig {
567− ambiguous :: Boolean
568− , capitalize :: Boolean
569− , includeNumber :: Boolean
570− , length :: Int
571− , lowercase :: Boolean
572− , minLowercase :: Int
573− , minNumber :: Int
574− , minSpecial :: Int
575− , minUppercase :: Int
576− , numWords :: Int
577− , number :: Boolean
578− , special :: Boolean
579− , type :: String
580− , uppercase :: Boolean
581− , wordSeparator :: String
582− }
583
443
584−derive instance newtypePasswordGeneratorConfig :: Newtype PasswordGeneratorConfig _
444+instance encodeJsonSub_LoadCiphers_cipherType :: EncodeJson Sub_LoadCiphers_cipherType where
585−instance encodeJsonPasswordGeneratorConfig :: EncodeJson PasswordGeneratorConfig where
586 encodeJson = genericEncodeAeson Argonaut.defaultOptions
445 encodeJson = genericEncodeAeson Argonaut.defaultOptions
587−instance decodeJsonPasswordGeneratorConfig :: DecodeJson PasswordGeneratorConfig where
446+instance decodeJsonSub_LoadCiphers_cipherType :: DecodeJson Sub_LoadCiphers_cipherType where
588 decodeJson = genericDecodeAeson Argonaut.defaultOptions
447 decodeJson = genericDecodeAeson Argonaut.defaultOptions
589−derive instance genericPasswordGeneratorConfig :: Generic PasswordGeneratorConfig _
448+derive instance genericSub_LoadCiphers_cipherType :: Generic Sub_LoadCiphers_cipherType _
590−derive instance eqPasswordGeneratorConfig :: Eq PasswordGeneratorConfig
449+derive instance eqSub_LoadCiphers_cipherType :: Eq Sub_LoadCiphers_cipherType
591−derive instance ordPasswordGeneratorConfig :: Ord PasswordGeneratorConfig
450+derive instance ordSub_LoadCiphers_cipherType :: Ord Sub_LoadCiphers_cipherType
592
451
593newtype Sub_LoadCiphers =
452newtype Sub_LoadCiphers =
594 Sub_LoadCiphers {
453 Sub_LoadCiphers {
595− cipherType :: CipherType
454+ cipherType :: Sub_LoadCiphers_cipherType
596 , date :: String
455 , date :: String
597 , id :: String
456 , id :: String
598 , name :: String
457 , name :: String
599 }
458 }
600
459
601−derive instance newtypeSub_LoadCiphers :: Newtype Sub_LoadCiphers _
602instance encodeJsonSub_LoadCiphers :: EncodeJson Sub_LoadCiphers where
460instance encodeJsonSub_LoadCiphers :: EncodeJson Sub_LoadCiphers where
603 encodeJson = genericEncodeAeson Argonaut.defaultOptions
461 encodeJson = genericEncodeAeson Argonaut.defaultOptions
604instance decodeJsonSub_LoadCiphers :: DecodeJson Sub_LoadCiphers where
462instance decodeJsonSub_LoadCiphers :: DecodeJson Sub_LoadCiphers where
@@ -610,7 +468,6 @@ derive instance ordSub_LoadCiphers :: Ord Sub_LoadCiphers
610newtype Sub_LoadCiphers_List =
468newtype Sub_LoadCiphers_List =
611 Sub_LoadCiphers_List (Array Sub_LoadCiphers)
469 Sub_LoadCiphers_List (Array Sub_LoadCiphers)
612
470
613−derive instance newtypeSub_LoadCiphers_List :: Newtype Sub_LoadCiphers_List _
614instance encodeJsonSub_LoadCiphers_List :: EncodeJson Sub_LoadCiphers_List where
471instance encodeJsonSub_LoadCiphers_List :: EncodeJson Sub_LoadCiphers_List where
615 encodeJson = genericEncodeAeson Argonaut.defaultOptions
472 encodeJson = genericEncodeAeson Argonaut.defaultOptions
616instance decodeJsonSub_LoadCiphers_List :: DecodeJson Sub_LoadCiphers_List where
473instance decodeJsonSub_LoadCiphers_List :: DecodeJson Sub_LoadCiphers_List where
@@ -625,7 +482,6 @@ newtype Sub_NeedsMasterPassword =
625 , server :: String
482 , server :: String
626 }
483 }
627
484
628−derive instance newtypeSub_NeedsMasterPassword :: Newtype Sub_NeedsMasterPassword _
629instance encodeJsonSub_NeedsMasterPassword :: EncodeJson Sub_NeedsMasterPassword where
485instance encodeJsonSub_NeedsMasterPassword :: EncodeJson Sub_NeedsMasterPassword where
630 encodeJson = genericEncodeAeson Argonaut.defaultOptions
486 encodeJson = genericEncodeAeson Argonaut.defaultOptions
631instance decodeJsonSub_NeedsMasterPassword :: DecodeJson Sub_NeedsMasterPassword where
487instance decodeJsonSub_NeedsMasterPassword :: DecodeJson Sub_NeedsMasterPassword where
@@ -634,51 +490,15 @@ derive instance genericSub_NeedsMasterPassword :: Generic Sub_NeedsMasterPasswor
634derive instance eqSub_NeedsMasterPassword :: Eq Sub_NeedsMasterPassword
490derive instance eqSub_NeedsMasterPassword :: Eq Sub_NeedsMasterPassword
635derive instance ordSub_NeedsMasterPassword :: Ord Sub_NeedsMasterPassword
491derive instance ordSub_NeedsMasterPassword :: Ord Sub_NeedsMasterPassword
636
492
637−newtype Sub_NeedsSecondFactor_List =
638− Sub_NeedsSecondFactor_List (Array TwoFactorProviderType)
639−
640−derive instance newtypeSub_NeedsSecondFactor_List :: Newtype Sub_NeedsSecondFactor_List _
641−instance encodeJsonSub_NeedsSecondFactor_List :: EncodeJson Sub_NeedsSecondFactor_List where
642− encodeJson = genericEncodeAeson Argonaut.defaultOptions
643−instance decodeJsonSub_NeedsSecondFactor_List :: DecodeJson Sub_NeedsSecondFactor_List where
644− decodeJson = genericDecodeAeson Argonaut.defaultOptions
645−derive instance genericSub_NeedsSecondFactor_List :: Generic Sub_NeedsSecondFactor_List _
646−derive instance eqSub_NeedsSecondFactor_List :: Eq Sub_NeedsSecondFactor_List
647−derive instance ordSub_NeedsSecondFactor_List :: Ord Sub_NeedsSecondFactor_List
648−
649−newtype Sub_Totp =
650− Sub_Totp {
651− code :: String
652− , interval :: Int
653− , source :: String
654− }
655−
656−derive instance newtypeSub_Totp :: Newtype Sub_Totp _
657−instance encodeJsonSub_Totp :: EncodeJson Sub_Totp where
658− encodeJson = genericEncodeAeson Argonaut.defaultOptions
659−instance decodeJsonSub_Totp :: DecodeJson Sub_Totp where
660− decodeJson = genericDecodeAeson Argonaut.defaultOptions
661−derive instance genericSub_Totp :: Generic Sub_Totp _
662−derive instance eqSub_Totp :: Eq Sub_Totp
663−derive instance ordSub_Totp :: Ord Sub_Totp
664−
665data Sub =
493data Sub =
666− CaptchaDone
667− | CipherChanged FullCipher
668− | CipherDeleted FullCipher
669− | Error String
494+ Error String
670− | GeneratedPassword String
671− | LoadCipher FullCipher
495+ | LoadCipher Sub_LoadCipher
672 | LoadCiphers Sub_LoadCiphers_List
496 | LoadCiphers Sub_LoadCiphers_List
673 | LoginSuccessful
497 | LoginSuccessful
674− | NeedsCaptcha String
675 | NeedsLogin
498 | NeedsLogin
676 | NeedsMasterPassword Sub_NeedsMasterPassword
499 | NeedsMasterPassword Sub_NeedsMasterPassword
677− | NeedsSecondFactor Sub_NeedsSecondFactor_List
678 | RecieveEmail String
500 | RecieveEmail String
679 | Reset
501 | Reset
680− | Totp Sub_Totp
681− | WrongPassword
682
502
683instance encodeJsonSub :: EncodeJson Sub where
503instance encodeJsonSub :: EncodeJson Sub where
684 encodeJson = genericEncodeAeson Argonaut.defaultOptions
504 encodeJson = genericEncodeAeson Argonaut.defaultOptions
@@ -688,21 +508,3 @@ derive instance genericSub :: Generic Sub _
688derive instance eqSub :: Eq Sub
508derive instance eqSub :: Eq Sub
689derive instance ordSub :: Ord Sub
509derive instance ordSub :: Ord Sub
690
510
691−data TwoFactorProviderType =
692− Authenticator
693− | Duo
694− | Email
695− | OrganizationDuo
696− | Remember
697− | U2f
698− | WebAuthn
699− | Yubikey
700−
701−instance encodeJsonTwoFactorProviderType :: EncodeJson TwoFactorProviderType where
702− encodeJson = genericEncodeAeson Argonaut.defaultOptions
703−instance decodeJsonTwoFactorProviderType :: DecodeJson TwoFactorProviderType where
704− decodeJson = genericDecodeAeson Argonaut.defaultOptions
705−derive instance genericTwoFactorProviderType :: Generic TwoFactorProviderType _
706−derive instance eqTwoFactorProviderType :: Eq TwoFactorProviderType
707−derive instance ordTwoFactorProviderType :: Ord TwoFactorProviderType
708−
backend/Data/EncString.js+2−5
@@ -1,14 +1,11 @@
1−import { EncString } from "../../bw/models/domain/enc-string"
1+import { EncString } from "../../deps/bw/libs/shared/dist/src/models/domain/encString"
2
2
3export function fromString(str) {
3export function fromString(str) {
4+ console.log("fromString " + str)
4 const x = new EncString(str)
5 const x = new EncString(str)
5 return x
6 return x
6}
7}
7
8
8−export function toString(encStr) {
9− return encStr.encryptedString
10−}
11−
12export function encryptionType(encStr) {
9export function encryptionType(encStr) {
13 return encStr.encryptionType
10 return encStr.encryptionType
14}
11}
backend/Data/EncString.purs−2
@@ -25,5 +25,3 @@ type EncryptionType
25 = Int
25 = Int
26
26
27foreign import fromString :: EncryptedString -> EncString
27foreign import fromString :: EncryptedString -> EncString
28−
29−foreign import toString :: EncString -> EncryptedString
backend/Data/HCaptcha.js+1
@@ -5,5 +5,6 @@ export function bindHCaptchToken(callback) {
5 callback(e.data.hCaptchaToken)();
5 callback(e.data.hCaptchaToken)();
6 }
6 }
7 })
7 })
8+
8 }
9 }
9}
10}
backend/Data/SymmetricCryptoKey.js+2−1
@@ -1,5 +1,6 @@
1−import { SymmetricCryptoKey } from '../../bw/models/domain/symmetric-crypto-key.js'
1+import { SymmetricCryptoKey } from '../../deps/bw/libs/shared/dist/src/models/domain/symmetricCryptoKey.js';
2
2
3export function fromArrayBuffer(arr) {
3export function fromArrayBuffer(arr) {
4+ console.log("fromArrayBuffer " + arr)
4 return new SymmetricCryptoKey(arr)
5 return new SymmetricCryptoKey(arr)
5}
6}
backend/FFI.js+1−16
@@ -1,21 +1,6 @@
1−function searchForInit(obj) {
2− if (obj.init) {
3− return obj.init
4− } else {
5− for (let key in obj) {
6− if (obj.hasOwnProperty(key)) {
7− const result = searchForInit(obj[key])
8− if (result) {
9− return result
10− }
11− }
12− }
13− }
14−}
15−
16export function startElm(element) {
1export function startElm(element) {
17 return function () {
2 return function () {
18− return searchForInit(Elm)({
3+ return Elm.Main.init({
19 node: document.getElementById(element)
4 node: document.getElementById(element)
20 })
5 })
21 }
6 }
backend/Main.purs+240−360
@@ -4,23 +4,25 @@ module Main
4
4
5import Prelude
5import Prelude
6
6
7−import BW (ApiService, CryptoFunctions, Services, CryptoService)
7+import BW (ApiService, CryptoService, Hash, Services)
8import BW as WB
8import BW as WB
9−import BW.Logic (bwPasswordStringHash, decodeCipher, decrypt, encodeCipher, hashPassword, liftPromise, supportedCipher)
9+import BW.Logic (decrypt, hashPassword, liftPromise)
10import BW.Logic as Logic
10import BW.Logic as Logic
11−import BW.Types (CipherResponse, Email(..), Password(..), Urls, cipherTypeCard, cipherTypeIdentity, cipherTypeLogin, cipherTypeSecureNote, fromTwoFactorProviderType)
11+import BW.Types (CipherResponse, Email(..), IdentityTokenResponse, Password(..), PreloginResponse, SyncResponse, Urls, cipherTypeCard, cipherTypeIdentity, cipherTypeLogin, cipherTypeSecureNote)
12import Bridge as Bridge
12import Bridge as Bridge
13−import Control.Monad.Error.Class (catchError)
13+import Control.El (class HasL, Al, L(..), l)
14+import Control.Monad.Error.Class (throwError)
15+import Control.Monad.Reader (runReaderT)
14import Data.Argonaut (class DecodeJson)
16import Data.Argonaut (class DecodeJson)
15import Data.Array as Array
17import Data.Array as Array
16import Data.Clipboard as Clipboard
18import Data.Clipboard as Clipboard
17import Data.DateTime (DateTime)
19import Data.DateTime (DateTime)
18import Data.Either (Either(..))
20import Data.Either (Either(..))
19−import Data.Foldable (for_)
20import Data.HCaptcha (bindHCaptchToken)
21import Data.HCaptcha (bindHCaptchToken)
21−import Data.JNullable (jnull, nullify)
22+import Data.JNullable (fromJNullable, jnull, nullify)
22import Data.JNullable as JNullable
23import Data.JNullable as JNullable
24+import Data.JOpt (fromJOpt)
23−import Data.Maybe (Maybe(..), maybe)
25+import Data.Maybe (Maybe(..))
24import Data.OpenURL (openURL)
26import Data.OpenURL (openURL)
25import Data.Ord.Down (Down(..))
27import Data.Ord.Down (Down(..))
26import Data.SymmetricCryptoKey (SymmetricCryptoKey)
28import Data.SymmetricCryptoKey (SymmetricCryptoKey)
@@ -30,7 +32,7 @@ import Effect (Effect)
30import Effect.Aff (Aff, runAff_, try)
32import Effect.Aff (Aff, runAff_, try)
31import Effect.Class (liftEffect)
33import Effect.Class (liftEffect)
32import Effect.Class.Console (log)
34import Effect.Class.Console (log)
33−import Effect.Exception (throw)
35+import Effect.Exception (error)
34import Effect.Exception as Exc
36import Effect.Exception as Exc
35import Effect.Ref as Ref
37import Effect.Ref as Ref
36import Elm as Elm
38import Elm as Elm
@@ -38,12 +40,6 @@ import FFI (Elm)
38import FFI as FFI
40import FFI as FFI
39import Localstorage (class StorageKey)
41import Localstorage (class StorageKey)
40import Localstorage as Storage
42import Localstorage as Storage
41−import Run (AFF, EFFECT, Run, liftAff, runBaseAff')
42−import Run.Reader (Reader, askAt, runReaderAt)
43−import Storage (MasterPasswordHashKey(..), PreloginResponseKey(..), SyncKey(..), TokenKey(..), UrlsKey(..))
44−import Type.Prelude (Proxy(..))
45−import Type.Row (type (+))
46−import Untagged.Union (toEither1)
47import Web.HTML as Html
43import Web.HTML as Html
48import Web.HTML.Window as Window
44import Web.HTML.Window as Window
49import Web.Storage.Storage (Storage)
45import Web.Storage.Storage (Storage)
@@ -55,273 +51,231 @@ main = do
55 storage <- Html.window >>= Window.localStorage
51 storage <- Html.window >>= Window.localStorage
56 services <- WB.getServices
52 services <- WB.getServices
57 masterKeyRef <- Ref.new Nothing
53 masterKeyRef <- Ref.new Nothing
58− hCaptchaTokenRef <- Ref.new Nothing
59− bindHCaptchToken \captchaToken -> do
54+ bindHCaptchToken log
60− Ref.write (Just captchaToken) hCaptchaTokenRef
61− Elm.send app Bridge.CaptchaDone
62− let
55+ let run act = do
63− runAff act = runElmAff app $ run $ act
64−
65− run
66− :: forall a
67− . Run
68− ( app :: Reader Elm
69− , aff :: Aff
70− , effect :: Effect
71− , crypto :: Reader CryptoService
72− , storage :: Reader Storage
73− , services :: Reader Services
74− , cryptoFunctions :: Reader CryptoFunctions
75− )
76− a
77− -> Run (EFFECT + AFF + ()) a
78− run act =
79− runReaderAt (Proxy :: _ "app") app
80− $ runReaderAt (Proxy :: _ "crypto") services.crypto
81− $ runReaderAt (Proxy :: _ "storage") storage
82− $ runReaderAt (Proxy :: _ "services") services
83− $ runReaderAt (Proxy :: _ "cryptoFunctions") services.cryptoFunctions
84− $ act
85−
86− runWithDecryptionKey
87− :: Run
88− ( app :: Reader Elm
89− , aff :: Aff
90− , effect :: Effect
91− , key :: Reader SymmetricCryptoKey
92− , crypto :: Reader CryptoService
93− , storage :: Reader Storage
94− , services :: Reader Services
95− , cryptoFunctions :: Reader CryptoFunctions
96− )
97− Unit
98− -> Effect Unit
99− runWithDecryptionKey act = do
100− maybeKey <- Ref.read masterKeyRef
56+ maybeKey <- Ref.read masterKeyRef
101− runAff
57+ runElmAff app $ flip runReaderT {app: app, crypto : services.crypto, storage: storage} $
102− $ case maybeKey of
58+ case maybeKey of
103− Just masterKey -> do
59+ Just masterKey -> do
104− token <- getOrReset TokenKey
60+ token <- getOrReset storage TokenKey
105− key <- Logic.makeDecryptionKey masterKey token.key
61+ key <- Logic.makeDecryptionKey masterKey token.key
106− runReaderAt (Proxy :: _ "key") key $ act
62+ liftEffect $ runElmAff app $ runReaderT act
63+ {app : app , storage : storage, services : services, crypto : services.crypto
64+ , key : key}
107− Nothing -> requestMasterPassword
65+ Nothing -> requestMasterPassword
108 Elm.subscribe app \cmd -> case cmd of
66 Elm.subscribe app \cmd -> case cmd of
109− Bridge.Login (Bridge.Cmd_Login { email: email', server, password, secondFactor }) -> do
67+ Bridge.Login (Bridge.Cmd_Login { email, server, password }) -> do
110− let
111− email = Email email'
112− captchaResponse <- Ref.read hCaptchaTokenRef
113− Ref.write Nothing hCaptchaTokenRef
114 let
68 let
115 urls = baseUrl server
69 urls = baseUrl server
116− runAff do
70+ runElmAff app do
117 unauthedApi <- liftPromise $ services.getApi urls jnull
71 unauthedApi <- liftPromise $ services.getApi urls jnull
72+ flip runReaderT { api: unauthedApi, crypto: services.crypto, storage:
73+ storage, cryptoFunctions: services.cryptoFunctions } do
74+ {token, prelogin: (prelogin :: PreloginResponse)} <-
75+ try (do
118− prelogin <- liftPromise $ unauthedApi.postPrelogin { email }
76+ prelogin <- liftPromise $ unauthedApi.postPrelogin {email}
119− runReaderAt (Proxy :: _ "api") unauthedApi do
120− loginResponse <-
121− liftAff
122− $ catchError
123− ( do
124− resp <-
125− runBaseAff' $ run $ runReaderAt (Proxy :: _ "api") unauthedApi
126− $ Logic.getLogInRequestToken
77+ token <- (Logic.getLogInRequestToken prelogin (Email email) (Password password))
127− { prelogin
78+ pure {token, prelogin}
128− , email
129− , password: Password password
130− , captchaResponse
131− , secondFactor
132− }
133− pure $ Right resp
134− )
79+ )
135− ( \err -> do
80+ >>= \et -> case et of
136− log $ show err
81+ Left _ -> liftEffect $ Exc.throw "Could not log in. Please check your data and try again."
137− pure $ Left unit
82+ Right t -> pure t
138− )
139− case map (toEither1 >>> map toEither1) $ loginResponse of
140− Left _ -> send Bridge.WrongPassword
141− Right (Left { siteKey }) -> send $ Bridge.NeedsCaptcha siteKey
142− Right (Right (Right token)) -> do
143− masterKey <- Logic.makePreloginKey prelogin email (Password password)
83+ masterKey <- Logic.makePreloginKey prelogin (Email email) (Password password)
144− api <- liftPromise $ services.getApi urls (nullify token)
84+ api <- liftPromise $ services.getApi urls (nullify token)
145− sync <- liftPromise $ api.getSync unit
85+ sync <- liftPromise $ api.getSync unit
146− hash <- hashPassword (Password password)
86+ hash <- hashPassword (Password password)
147− log $ show sync
87+ log $ show sync
148− liftEffect do
149− Ref.write (Just masterKey) masterKeyRef
88+ liftEffect $ Ref.write (Just masterKey) masterKeyRef
150− Storage.store storage UrlsKey server
89+ liftEffect $ Storage.store storage UrlsKey server
151− Storage.store storage MasterPasswordHashKey hash
90+ liftEffect $ Storage.store storage MasterPasswordHashKey hash
152− Storage.store storage PreloginResponseKey prelogin
91+ liftEffect $ Storage.store storage PreloginResponseKey prelogin
153− Storage.store storage SyncKey sync
92+ liftEffect $ Storage.store storage SyncKey sync
154− Storage.store storage TokenKey token
93+ liftEffect $ Storage.store storage TokenKey token
155− send Bridge.LoginSuccessful
94+ liftEffect $ Elm.send app Bridge.LoginSuccessful
156− Right (Right (Left { twoFactorProviders, captchaToken })) -> do
157− case toEither1 captchaToken of
158− Left captchaTokenString ->
159− liftEffect
160− $ Ref.write (Just captchaTokenString) hCaptchaTokenRef
161− Right _ -> pure unit
95+ pure unit
162− providers <- case fromTwoFactorProviderType twoFactorProviders of
163− Left x -> liftEffect $ throw $ "Unknown second factor provider: " <> x
164− Right x -> pure x
96+ pure unit
165− send $ Bridge.NeedsSecondFactor $ Bridge.Sub_NeedsSecondFactor_List providers
166− Bridge.NeedCiphersList ->
97+ Bridge.NeedCiphersList -> run do
167− runWithDecryptionKey do
98+ sync <- getOrReset storage SyncKey
168− sendCiphers
99+ ciphers <- traverse processCipher sync.ciphers
169− performSync
100+ let sortedCiphers = Array.sortWith (_.date >>> Down) ciphers
101+ liftEffect $ Elm.send app $ Bridge.LoadCiphers $ Bridge.Sub_LoadCiphers_List $ map _.cipher sortedCiphers
102+ liftEffect $ Storage.store storage SyncKey sync
103+ pure unit
170 Bridge.NeedsReset -> do
104 Bridge.NeedsReset -> do
171 WebStorage.clear storage
105 WebStorage.clear storage
172 Elm.send app Bridge.Reset
106 Elm.send app Bridge.Reset
107+ pure unit
173− Bridge.SendMasterPassword masterPassword ->
108+ Bridge.SendMasterPassword masterPassword -> runElmAff app $ do
174− runAff do
109+ flip runReaderT {app: app, storage: storage, crypto: services.crypto, cryptoFunctions: services.cryptoFunctions} $ do
175− hash <- getOrReset MasterPasswordHashKey
110+ hash <- getOrReset storage MasterPasswordHashKey
176 newHash <- hashPassword (Password masterPassword)
111 newHash <- hashPassword (Password masterPassword)
177− if hash == newHash then do
112+ if hash == newHash
113+ then do
178− sync <- getOrReset SyncKey
114+ sync <- getOrReset storage SyncKey
179− prelogin <- getOrReset PreloginResponseKey
115+ prelogin <- getOrReset storage PreloginResponseKey
180− masterKey <- Logic.makePreloginKey prelogin (Email sync.profile.email) (Password masterPassword)
116+ masterKey <- Logic.makePreloginKey prelogin (Email sync.profile.email) (Password masterPassword)
181− liftEffect $ Ref.write (Just masterKey) masterKeyRef
117+ liftEffect $ Ref.write (Just masterKey) masterKeyRef
182− send Bridge.LoginSuccessful
118+ liftEffect $ Elm.send app Bridge.LoginSuccessful
183− else do
119+ else do
184− send $ Bridge.Error "The password is wrong. Please try again."
120+ liftEffect $ Elm.send app $ Bridge.Error "The password is wrong. Please try again."
185− requestMasterPassword
121+ requestMasterPassword
186− Bridge.Init -> do
187− Storage.get storage TokenKey
188− >>= \x ->
189− Elm.send app case x of
190− Just _ -> Bridge.LoginSuccessful
191− Nothing -> Bridge.NeedsLogin
192− Bridge.RequestCipher id ->
193− runWithDecryptionKey do
194− sync <- getOrReset SyncKey
195− case Array.find (\c -> c.id == id) sync.ciphers of
196− Nothing -> pure unit
197− Just cipherResponse -> do
198− cipher <- decodeCipher cipherResponse
199− for_ cipher $ send <<< Bridge.LoadCipher
200− pure unit
201− Bridge.NeedEmail ->
202− runWithDecryptionKey do
203− sync <- getOrReset SyncKey
204− send $ Bridge.RecieveEmail sync.profile.email
205 pure unit
122 pure unit
123+ Bridge.Init -> do
124+ liftEffect $ Storage.get storage TokenKey >>= \x -> case x of
125+ Just _ -> do liftEffect $ Elm.send app Bridge.LoginSuccessful
126+ Nothing -> Elm.send app Bridge.NeedsLogin
127+ Bridge.RequestCipher id -> run do
128+ sync <- getOrReset storage SyncKey
129+ case Array.find (\c -> c.id == id) sync.ciphers of
130+ Nothing -> pure unit
131+ Just cipher -> do
132+ name <- decrypt cipher.name
133+ cipherType <- do
134+ case cipher.type of
135+ n | cipherTypeSecureNote == n -> do
136+ note <- fromJNullable "" <$> (traverse decrypt cipher.notes)
137+ pure $ Bridge.NoteCipher note
138+ n | cipherTypeLogin == n -> do
139+ case JNullable.toMaybe cipher.login of
140+ Nothing -> throwError $ error "Login data is missing"
141+ Just login -> do
142+ username <- Bridge.Sub_LoadCipher_cipherType_LoginCipher_username_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt login.username)
143+ password <- Bridge.Sub_LoadCipher_cipherType_LoginCipher_password_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt login.password)
144+ uris <- fromJOpt [] <$> ((traverse >>> traverse) (_.uri >>> decrypt) login.uris)
145+ pure $ Bridge.LoginCipher $ Bridge.Sub_LoadCipher_cipherType_LoginCipher
146+ { username
147+ , password
148+ , uris: Bridge.Sub_LoadCipher_cipherType_LoginCipher_uris_List uris
149+ }
150+ n | cipherTypeCard == n -> do
151+ case JNullable.toMaybe cipher.card of
152+ Nothing -> throwError $ error "Card data is missing"
153+ Just card -> do
154+ cardholderName <- Bridge.Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt card.cardholderName)
155+ number <- Bridge.Sub_LoadCipher_cipherType_CardCipher_number_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt card.number)
156+ code <- Bridge.Sub_LoadCipher_cipherType_CardCipher_code_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt card.code)
157+ brand <- Bridge.Sub_LoadCipher_cipherType_CardCipher_brand_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt card.brand)
158+ expMonth <- Bridge.Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt card.expMonth)
159+ expYear <- Bridge.Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt card.expYear)
160+ pure $ Bridge.CardCipher $ Bridge.Sub_LoadCipher_cipherType_CardCipher
161+ { brand, cardholderName, code, expMonth, expYear, number }
162+ n | cipherTypeIdentity == n -> do
163+ case JNullable.toMaybe cipher.identity of
164+ Nothing -> throwError $ error "Identity data is missing"
165+ Just identity -> do
166+ firstName <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.firstName)
167+ middleName <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.middleName)
168+ lastName <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.lastName)
169+ address1 <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.address1)
170+ address2 <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.address2)
171+ address3 <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.address3)
172+ city <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.city)
173+ company <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.company)
174+ country <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.country)
175+ email <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.email)
176+ licenseNumber <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.licenseNumber)
177+ passportNumber <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.passportNumber)
178+ phone <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.phone)
179+ postalCode <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.postalCode)
180+ ssn <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.ssn)
181+ state <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.state)
182+ title <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.title)
183+ username <- Bridge.Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt identity.username)
184+ pure $ Bridge.IdentityCipher $ Bridge.Sub_LoadCipher_cipherType_IdentityCipher
185+ { firstName,
186+ middleName,
187+ lastName,
188+ address1,
189+ address2,
190+ address3,
191+ city,
192+ company,
193+ country,
194+ email,
195+ licenseNumber,
196+ passportNumber,
197+ phone,
198+ postalCode,
199+ ssn,
200+ state,
201+ title,
202+ username
203+ }
204+ n -> throwError $ error $ "Unsupported cipher type: " <> show n
205+ send $ Bridge.LoadCipher $ Bridge.Sub_LoadCipher {cipherType, name, id}
206+ pure unit
207+ pure unit
208+ Bridge.NeedEmail -> run do
209+ sync <- getOrReset storage SyncKey
210+ send $ Bridge.RecieveEmail sync.profile.email
211+ pure unit
206− Bridge.Copy text ->
212+ Bridge.Copy text -> run do
207− runWithDecryptionKey do
208− liftPromise $ Clipboard.clipboard text
213+ liftPromise $ Clipboard.clipboard text
209 Bridge.Open uri -> openURL uri
214 Bridge.Open uri -> openURL uri
210− Bridge.UpdateCipher fullCipher ->
211− runWithDecryptionKey do
212− api <- getAuthedApi
213− cipher <- encodeCipher fullCipher
214− newCipher <- liftPromise (api.putCipher cipher) >>= decodeCipher
215− for_ newCipher $ send <<< Bridge.CipherChanged
216− performSync
217− pure unit
218− Bridge.GeneratePassword cfg ->
219− runWithDecryptionKey do
220− password <- liftPromise $ services.passwordGeneration.generatePassword cfg
221− send $ Bridge.GeneratedPassword password
222− pure unit
223− Bridge.CreateCipher fullCipher ->
224− runWithDecryptionKey do
225− api <- getAuthedApi
226− cipher <- encodeCipher fullCipher
227− newCipher <- liftPromise (api.postCipherCreate cipher) >>= decodeCipher
228− for_ newCipher $ send <<< Bridge.CipherChanged
229− performSync
230− pure unit
231− Bridge.DeleteCipher c@(Bridge.FullCipher { id }) ->
232− runWithDecryptionKey do
233− api <- getAuthedApi
234− liftPromise $ api.deleteCipher id
235− send $ Bridge.CipherDeleted c
236− performSync
237− pure unit
238− Bridge.RequestTotp totp ->
239− runWithDecryptionKey do
240− { totpService } <- askAt (Proxy :: _ "services")
241− code <- liftPromise $ totpService.getCode totp
242− let
243− interval = totpService.getTimeInterval totp
244− send $ Bridge.Totp
245− $ Bridge.Sub_Totp
246− { interval
247− , code
248− , source: totp
249− }
250− pure unit
251− Bridge.ChooseSecondFactor
252− ( Bridge.Cmd_ChooseSecondFactor
253− { email: email'
254− , factor
255− , server
256− , password
257− , requestFromServer
258− }
259− ) ->
260− when requestFromServer
261− let
262− email = Email email'
263− in
264− case factor of
265− Bridge.Email ->
266− runAff do
267− let
268− urls = baseUrl server
269− unauthedApi <- liftPromise $ services.getApi urls jnull
270− prelogin <- liftPromise $ unauthedApi.postPrelogin { email }
271− masterPasswordHash <- bwPasswordStringHash prelogin email (Password password)
272− liftPromise $ unauthedApi.postTwoFactorEmail { email, masterPasswordHash }
273− pure unit
274− _ -> pure unit
275
215
276−processCipher
216+data SyncKey = SyncKey
217+
218+instance StorageKey SyncKey SyncResponse where
219+ storageKey SyncKey = "sync"
220+
221+data TokenKey
222+ = TokenKey
223+
224+instance StorageKey TokenKey IdentityTokenResponse where
225+ storageKey TokenKey = "token"
226+
227+data UrlsKey
228+ = UrlsKey
229+
230+instance StorageKey UrlsKey String where
231+ storageKey UrlsKey = "urls"
232+
233+data PreloginResponseKey
234+ = PreloginResponseKey
235+
236+instance StorageKey PreloginResponseKey PreloginResponse where
237+ storageKey PreloginResponseKey = "prelogin-reponse"
238+
239+data MasterPasswordHashKey
240+ = MasterPasswordHashKey
241+
242+instance StorageKey MasterPasswordHashKey Hash where
243+ storageKey MasterPasswordHashKey = "master-password-hash"
244+
245+
246+processCipher ::
277− :: forall r
247+ forall r.
278− . CipherResponse
279− -> Run
280− ( crypto :: Reader CryptoService
248+ HasL "crypto" CryptoService r =>
281− , key :: Reader SymmetricCryptoKey
249+ HasL "key" SymmetricCryptoKey r =>
282− , aff :: Aff
283− , effect :: Effect
284− | r
285− )
286− (Maybe { cipher :: Bridge.Sub_LoadCiphers, date :: DateTime })
250+ CipherResponse -> Al r {cipher :: Bridge.Sub_LoadCiphers, date :: DateTime}
287−processCipher cipher | not (supportedCipher cipher) = pure Nothing
288processCipher cipher = do
251processCipher cipher = do
289 name <- decrypt cipher.name
252 name <- decrypt cipher.name
290 cipherType <- case cipher.type of
253 cipherType <- case cipher.type of
291− n
292− | n == cipherTypeLogin -> pure Bridge.LoginType
254+ n | n == cipherTypeLogin -> pure Bridge.LoginType
293− n
294− | n == cipherTypeSecureNote -> pure Bridge.NoteType
255+ n | n == cipherTypeSecureNote -> pure Bridge.NoteType
295− n
296− | n == cipherTypeCard -> pure Bridge.CardType
256+ n | n == cipherTypeCard -> pure Bridge.CardType
297− n
298− | n == cipherTypeIdentity -> pure Bridge.IdentityType
257+ n | n == cipherTypeIdentity -> pure Bridge.IdentityType
299− n -> liftEffect $ throw $ "Unsupported cipher type: " <> show n
258+ n -> throwError $ error $ "Unsupported cipher type: " <> show n
300− date <- liftEffect $ maybe (pure bottom) (Timestamp.toDateTime) $ JNullable.toMaybe cipher.revisionDate
259+ date <- liftEffect $ Timestamp.toDateTime cipher.revisionDate
301 pure
260 pure
302− $ Just
303− $
304− { cipher:
305− Bridge.Sub_LoadCiphers
261+ $ {cipher: Bridge.Sub_LoadCiphers
306− { name: name
262+ { name: name
307− , date: maybe "" Timestamp.toLocalDateTimeString $ JNullable.toMaybe cipher.revisionDate
263+ , date: Timestamp.toLocalDateTimeString cipher.revisionDate
308− , id: cipher.id
264+ , id: cipher.id
309− , cipherType
265+ , cipherType
310− }
266+ }
311 , date
267 , date
312 }
268 }
313
269
314−runElmAff :: FFI.Elm -> Run (AFF + EFFECT + ()) Unit -> Effect Unit
270+runElmAff :: FFI.Elm -> Aff Unit -> Effect Unit
315runElmAff app =
271runElmAff app =
316 runAff_
272 runAff_
317− ( \res -> do
273+ $ \res -> do
318 case res of
274 case res of
319 Left e -> do
275 Left e -> do
320 log $ show e
276 log $ show e
321 Elm.send app (Bridge.Error $ Exc.message e)
277 Elm.send app (Bridge.Error $ Exc.message e)
322 Right unit -> pure unit
278 Right unit -> pure unit
323− )
324− <<< runBaseAff'
325
279
326baseUrl :: String -> Urls
280baseUrl :: String -> Urls
327baseUrl server =
281baseUrl server =
@@ -335,115 +289,41 @@ baseUrl server =
335 , keyConnector: jnull
289 , keyConnector: jnull
336 }
290 }
337
291
338−getOrReset
292+getOrReset :: forall k t r. HasL "app" Elm r =>
339− :: forall k t r
340− . StorageKey k t
293+ StorageKey k t => DecodeJson t => Storage -> k -> Al r t
341− => DecodeJson t
342− => k
343− -> Run
344− ( storage :: Reader Storage
345− , app :: Reader Elm
346− , effect :: Effect
347− | r
348− )
349− t
350−getOrReset key = do
294+getOrReset storage key = do
351− storage <- askAt (Proxy :: _ "storage")
352− app <- askAt (Proxy :: _ "app")
353− let
354− handleError = do
295+ let handleError = do
296+ app <- l (L :: L "app")
355− WebStorage.clear storage
297+ liftEffect $ WebStorage.clear storage
356− Elm.send app Bridge.Reset
298+ liftEffect $ Elm.send app Bridge.Reset
357− Exc.throw "Encountered an internal error. Resetting the app."
299+ liftEffect $ Exc.throw "Encountered an internal error. Resetting the app."
358− liftEffect $ try (Storage.get storage key)
300+ try (liftEffect $ Storage.get storage key) >>= \x -> case x of
359− >>= \x -> case x of
360− Left err -> do
301+ Left err -> do
361− log $ show err
302+ liftEffect $ log $ show err
362− handleError
303+ handleError
363− Right Nothing -> handleError
304+ Right Nothing -> handleError
364− Right (Just y) -> pure y
305+ Right (Just y) -> pure y
365
306
366−getAuthedApi
307+getAuthedApi :: forall r. HasL "services" Services r => HasL "storage" Storage r
367− :: forall r
368− . Run
369− ( storage :: Reader Storage
370− , app :: Reader Elm
308+ => HasL "app" Elm r =>
371− , aff :: Aff
372− , effect :: Effect
373− , services :: Reader Services
374− | r
375− )
376− ApiService
309+ Al r ApiService
377getAuthedApi = do
310getAuthedApi = do
311+ storage <- l (L :: L "storage")
378− services <- askAt (Proxy :: _ "services")
312+ services <- l (L :: L "services")
379− token <- getOrReset TokenKey
313+ token <- getOrReset storage TokenKey
380− url <- getOrReset UrlsKey
314+ url <- getOrReset storage UrlsKey
381 liftPromise $ services.getApi (baseUrl url) (nullify token)
315 liftPromise $ services.getApi (baseUrl url) (nullify token)
382
316
383−requestMasterPassword
317+requestMasterPassword :: forall r. HasL "storage" Storage r => HasL "app" Elm r => Al r Unit
384− :: forall r
385− . Run
386− ( storage :: Reader Storage
387− , app :: Reader Elm
388− , effect :: Effect
389− | r
390− )
391− Unit
392requestMasterPassword = do
318requestMasterPassword = do
319+ storage <- l (L :: L "storage")
320+ app <- l (L :: L "app")
393− url <- getOrReset UrlsKey
321+ url <- getOrReset storage UrlsKey
394− sync <- getOrReset SyncKey
322+ sync <- getOrReset storage SyncKey
323+ liftEffect $ Elm.send app $ Bridge.NeedsMasterPassword
395− send $ Bridge.NeedsMasterPassword $ Bridge.Sub_NeedsMasterPassword { server: url, login: sync.profile.email }
324+ $ Bridge.Sub_NeedsMasterPassword {server: url, login: sync.profile.email}
396
325
397−send
326+send :: forall r. HasL "app" Elm r => Bridge.Sub -> Al r Unit
398− :: forall r
399− . Bridge.Sub
400− -> Run
401− ( app :: Reader Elm
402− , effect :: Effect
403− | r
404− )
405− Unit
406send sub = do
327send sub = do
407− app <- askAt (Proxy :: _ "app")
328+ app <- l (L :: L "app")
408 liftEffect $ Elm.send app sub
329 liftEffect $ Elm.send app sub
409−
410−performSync
411− :: forall r
412− . Run
413− ( storage :: Reader Storage
414− , app :: Reader Elm
415− , aff :: Aff
416− , effect :: Effect
417− , services :: Reader Services
418− , crypto :: Reader CryptoService
419− , key :: Reader SymmetricCryptoKey
420− | r
421− )
422− Unit
423−performSync = do
424− api <- getAuthedApi
425− storage <- askAt (Proxy :: _ "storage")
426− newSync <- liftPromise $ api.getSync unit
427− liftEffect $ Storage.store storage SyncKey newSync
428− sendCiphers
429−
430−sendCiphers
431− :: forall r
432− . Run
433− ( storage :: Reader Storage
434− , app :: Reader Elm
435− , aff :: Aff
436− , effect :: Effect
437− , services :: Reader Services
438− , crypto :: Reader CryptoService
439− , key :: Reader SymmetricCryptoKey
440− | r
441− )
442− Unit
443−sendCiphers = do
444− sync <- getOrReset SyncKey
445− ciphers <- Array.catMaybes <$> traverse processCipher sync.ciphers
446− let
447− sortedCiphers = Array.sortWith (_.date >>> Down) ciphers
448− send $ Bridge.LoadCiphers $ Bridge.Sub_LoadCiphers_List $ map _.cipher sortedCiphers
449− pure unit
backend/Storage.pursdeleted−43
@@ -1,43 +0,0 @@
1−module Storage where
2−
3−import Prelude
4−
5−import BW (Hash)
6−import BW.Types (IdentityTokenResponse, SyncResponse, PreloginResponse)
7−import Localstorage (class StorageKey)
8−
9−data SyncKey
10− = SyncKey
11−
12−instance StorageKey SyncKey SyncResponse where
13− storageKey SyncKey = "sync"
14−
15−data TokenKey
16− = TokenKey
17−
18−instance StorageKey TokenKey IdentityTokenResponse where
19− storageKey TokenKey = "token"
20−
21−data UrlsKey
22− = UrlsKey
23−
24−instance StorageKey UrlsKey String where
25− storageKey UrlsKey = "urls"
26−
27−data PreloginResponseKey
28− = PreloginResponseKey
29−
30−instance StorageKey PreloginResponseKey PreloginResponse where
31− storageKey PreloginResponseKey = "prelogin-reponse"
32−
33−data MasterPasswordHashKey
34− = MasterPasswordHashKey
35−
36−instance StorageKey MasterPasswordHashKey Hash where
37− storageKey MasterPasswordHashKey = "master-password-hash"
38−
39−data DeviceIDKey
40− = DeviceIDKey
41−
42−instance StorageKey DeviceIDKey String where
43− storageKey DeviceIDKey = "device-uuid"
bridge.yaml+88−153
@@ -1,159 +1,94 @@
1Sub:
1Sub:
2− - NeedsLogin
2+- NeedsLogin
3− - NeedsCaptcha: String
4− - NeedsSecondFactor: { List: TwoFactorProviderType }
5− - CaptchaDone
6− - Error: String
3+- Error: String
7− - LoadCiphers:
4+- LoadCiphers:
8− List:
5+ List:
9 name: String
6 name: String
10 date: String
7 date: String
11 id: String
8 id: String
12− cipherType: CipherType
9+ cipherType:
10+ - LoginType
11+ - CardType
12+ - NoteType
13+ - IdentityType
13− - LoginSuccessful
14+- LoginSuccessful
14− - WrongPassword
15− - NeedsMasterPassword:
15+- NeedsMasterPassword:
16− server: String
16+ server: String
17− login: String
17+ login: String
18− - Reset
18+- Reset
19− - LoadCipher: FullCipher
19+- LoadCipher:
20+ id: String
21+ name: String
22+ cipherType:
23+ - LoginCipher:
24+ uris: {List: String}
25+ username:
26+ Maybe: String
27+ password:
28+ Maybe: String
29+ - NoteCipher: String
30+ - CardCipher:
31+ cardholderName:
32+ Maybe: String
33+ brand:
34+ Maybe: String
35+ number:
36+ Maybe: String
37+ expMonth:
38+ Maybe: String
39+ expYear:
40+ Maybe: String
41+ code:
42+ Maybe: String
43+ - IdentityCipher:
44+ title:
45+ Maybe: String
46+ firstName:
47+ Maybe: String
48+ middleName:
49+ Maybe: String
50+ lastName:
51+ Maybe: String
52+ address1:
53+ Maybe: String
54+ address2:
55+ Maybe: String
56+ address3:
57+ Maybe: String
58+ city:
59+ Maybe: String
60+ state:
61+ Maybe: String
62+ postalCode:
63+ Maybe: String
64+ country:
65+ Maybe: String
66+ company:
67+ Maybe: String
68+ email:
69+ Maybe: String
70+ phone:
71+ Maybe: String
72+ ssn:
73+ Maybe: String
74+ username:
75+ Maybe: String
76+ passportNumber:
77+ Maybe: String
78+ licenseNumber:
79+ Maybe: String
20− - RecieveEmail: String
80+- RecieveEmail: String
21− - CipherChanged: FullCipher
22− - GeneratedPassword: String
23− - CipherDeleted: FullCipher
24− - Totp:
25− source: String
26− code: String
27− interval: Int
28
81
29Cmd:
82Cmd:
30− - Init
83+- Init
31− - Login:
84+- Login:
32− email: String
33− server: String
34− password: String
35− secondFactor:
36− Maybe:
37− provider: TwoFactorProviderType
38− token: String
39− remember: Bool
40− - ChooseSecondFactor:
41− factor: TwoFactorProviderType
42− email: String
85+ email: String
43− server: String
86+ server: String
44− password: String
87+ password: String
45− requestFromServer: Bool
46− - NeedCiphersList
88+- NeedCiphersList
47− - SendMasterPassword: String
89+- SendMasterPassword: String
48− - NeedsReset
90+- NeedsReset
49− - RequestCipher: String
91+- RequestCipher: String
50− - NeedEmail
92+- NeedEmail
51− - Copy: String
93+- Copy: String
52− - Open: String
94+- Open: String
53− - UpdateCipher: FullCipher
54− - CreateCipher: FullCipher
55− - GeneratePassword: PasswordGeneratorConfig
56− - DeleteCipher: FullCipher
57− - RequestTotp: String
58−
59−FullCipher:
60− reprompt: Int
61− favorite: Bool
62− id: String
63− name: String
64− cipher: Cipher
65− collectionIds: { List: String }
66−
67−Cipher:
68− - LoginCipher:
69− uris: { List: String }
70− username:
71− Maybe: String
72− password:
73− Maybe: String
74− totp:
75− Maybe: String
76− - NoteCipher: String
77− - CardCipher:
78− cardholderName:
79− Maybe: String
80− brand:
81− Maybe: String
82− number:
83− Maybe: String
84− expMonth:
85− Maybe: String
86− expYear:
87− Maybe: String
88− code:
89− Maybe: String
90− - IdentityCipher:
91− title:
92− Maybe: String
93− firstName:
94− Maybe: String
95− middleName:
96− Maybe: String
97− lastName:
98− Maybe: String
99− address1:
100− Maybe: String
101− address2:
102− Maybe: String
103− address3:
104− Maybe: String
105− city:
106− Maybe: String
107− state:
108− Maybe: String
109− postalCode:
110− Maybe: String
111− country:
112− Maybe: String
113− company:
114− Maybe: String
115− email:
116− Maybe: String
117− phone:
118− Maybe: String
119− ssn:
120− Maybe: String
121− username:
122− Maybe: String
123− passportNumber:
124− Maybe: String
125− licenseNumber:
126− Maybe: String
127−
128−CipherType:
129− - LoginType
130− - CardType
131− - NoteType
132− - IdentityType
133−
134−PasswordGeneratorConfig:
135− length: Int
136− ambiguous: Bool
137− number: Bool
138− minNumber: Int
139− uppercase: Bool
140− minUppercase: Int
141− lowercase: Bool
142− minLowercase: Int
143− special: Bool
144− minSpecial: Int
145− type: String
146− numWords: Int
147− wordSeparator: String
148− capitalize: Bool
149− includeNumber: Bool
150−
151−TwoFactorProviderType:
152− - Authenticator
153− - Email
154− - Duo
155− - Yubikey
156− - U2f
157− - Remember
158− - OrganizationDuo
159− - WebAuthn
build.sh+10−2
@@ -1,5 +1,13 @@
1−#!/bin/sh
1+#!/bin/bash
2
2
3set -e
3set -e
4
4
5−cp -r "$SRC_DIR/dist"/* "$INSTALL_DIR"
5+TEMP=$(mktemp -d)
6+
7+cp -r "$SRC_DIR"/{vanilla,appname.apparmor,appname.desktop,manifest.json,logo.png,index.html,style.css} "$INSTALL_DIR"
8+
9+elm make "$SRC_DIR/frontend/Main.elm" --optimize --output="$TEMP/elm.js"
10+
11+terser "$TEMP/elm.js" --ecma 2018 --compress 'pure_funcs=[F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9],pure_getters,keep_fargs=false,unsafe_comps,unsafe' | terser --ecma 2018 --mangle --compress --output "$INSTALL_DIR/elm.js"
12+
13+(cd "$SRC_DIR" && spago bundle-app --minify --to "$INSTALL_DIR/backend.js")
clickable.yaml+10−2
@@ -1,8 +1,16 @@
1clickable_minimum_required: 7.1.2
1clickable_minimum_required: 7.1.2
2−framework: ubuntu-sdk-20.04
3builder: custom
2builder: custom
4build: $SRC_DIR/build.sh
3build: $SRC_DIR/build.sh
5kill: webapp-container*
4kill: webapp-container*
6−docker_image: clickable/amd64-20.04-amd64
5+image_setup:
6+ env: {}
7+ # DEB_URL: http://archive.ubuntu.com/ubuntu
8+ # HOST_ARCH: amd64
9+
10+ # PATH: /opt/someprogram/bin:$PATH
11+ run:
12+
13+ - (cd /tmp && curl -L -o elm.gz https://github.com/elm/compiler/releases/download/0.19.1/binary-for-linux-64-bit.gz && gunzip elm.gz && chmod +x elm && mv elm /usr/local/bin/)
14+ - npm install -g spago esbuild purescript terser --unsafe-perm=true
7
15
8restrict_arch: all
16restrict_arch: all
deps/bwnew file+1

Submodule changed.

dev/build-backend.sh+1−7
@@ -1,9 +1,3 @@
1#!/bin/sh
1#!/bin/sh
2
2
3−set -e
3+spago bundle-app --to backend.js
4−
5−spago build
6−
7−export out="$(pwd)/backend.js"
8−
9−$(nix build .#backendBuildScript --print-out-paths) "$(pwd)/output"
dev/build-bw.sh−2
@@ -1,7 +1,5 @@
1#!/bin/sh
1#!/bin/sh
2
2
3−set -e
4−
5(cd deps/bw && npm install)
3(cd deps/bw && npm install)
6
4
7(cd deps/bw/libs/common/ && npm run clean && npm exec -c "tsc -m es2020 -t es2018")
5(cd deps/bw/libs/common/ && npm run clean && npm exec -c "tsc -m es2020 -t es2018")
dev/build.shdeleted−10
@@ -1,10 +0,0 @@
1−#!/bin/sh
2−
3−
4−rm -r dist
5−
6−mkdir -p dist
7−
8−cp -r "$(nix build ".#warden-click-src" --print-out-paths)"/* dist
9−
10−chmod -R 777 dist
dev/elm-live.sh+1−5
@@ -1,7 +1,3 @@
1#!/bin/sh
1#!/bin/sh
2
2
3−set -e
4−
5−nix build .#vanilla -o vanilla
6−
7−nix run github:NixOS/nixpkgs?rev=d9a1414346059619d9e13ab93e749bbb82e5252a#elmPackages.elm-live -- $1 --start-page=index.html --proxy-prefix=/api --proxy-host=http://localhost:6009 -- --debug --output=elm.js
3+elm-live frontend/Main.elm --start-page=index.html --proxy-prefix=/api --proxy-host=http://localhost:6009 --pushstate -- --debug --output=elm.js
dev/elm2nix.shdeleted−8
@@ -1,8 +0,0 @@
1−#!/bin/sh
2−
3−set -e
4−
5−cd "$(dirname "$0")/.."
6−
7−nix run github:NixOS/nixpkgs#elm2nix -- snapshot
8−nix run github:NixOS/nixpkgs#elm2nix -- convert > elm-srcs.nix
dev/generate-bridge.sh+1−1
@@ -1,3 +1,3 @@
1#!/bin/sh
1#!/bin/sh
2
2
3−nix run github:ilyakooo0/elm-ps-bridge -- --input bridge.yaml --elmOutput=frontend/Bridge.elm --psOutput=backend/Bridge.purs
3+elm-ps-bridge --input bridge.yaml --elmOutput=Frontend/Bridge.elm --psOutput=backend/Bridge.purs
dev/record-test.shdeleted−11
@@ -1,11 +0,0 @@
1−#!/bin/sh
2−
3−set -e
4−
5−cd tests
6−
7−npm install
8−
9−export RECORD_TEST=true
10−
11−npx playwright test
dev/spago2nix.shdeleted−3
@@ -1,3 +0,0 @@
1−#!/bin/sh
2−
3−nix run "github:justinwoo/spago2nix#spago2nix" -- generate
dev/start-chrome.sh+1−7
@@ -1,9 +1,3 @@
1#!/bin/sh
1#!/bin/sh
2
2
3−if test -x "$(which chromium)"; then
4− chromium --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
5−elif test -x /Applications/Chromium.app/Contents/MacOS/Chromium; then
3+/Applications/Chromium.app/Contents/MacOS/Chromium --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
6− /Applications/Chromium.app/Contents/MacOS/Chromium --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
7−else
8− flatpak run com.github.Eloston.UngoogledChromium --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
9−fi
dev/test.shdeleted−9
@@ -1,9 +0,0 @@
1−#!/bin/sh
2−
3−set -e
4−
5−cd tests
6−
7−npm install
8−
9−npx playwright test
dev/update-tests.shdeleted−9
@@ -1,9 +0,0 @@
1−#!/bin/sh
2−
3−set -e
4−
5−cd tests
6−
7−npm install
8−
9−npx playwright test --update-snapshots
el/spago.dhallnew file+14
@@ -0,0 +1,14 @@
1+{ name = "bw"
2+, dependencies =
3+ [ "aff"
4+ , "effect"
5+ , "newtype"
6+ , "prelude"
7+ , "record"
8+ , "test-unit"
9+ , "transformers"
10+ , "unsafe-coerce"
11+ ]
12+, packages = ../packages.dhall
13+, sources = [ "src/**/*.purs", "test/**/*.purs" ]
14+}
el/src/Control/El.pursnew file+23
@@ -0,0 +1,23 @@
1+module Control.El (El, Al, l, class HasL, L(..)) where
2+
3+
4+import Control.Monad.Reader (class MonadAsk, ReaderT, asks)
5+import Data.Symbol (class IsSymbol, reflectSymbol)
6+import Effect (Effect)
7+import Effect.Aff (Aff)
8+import Prim.Row (class Cons, class Nub)
9+import Record.Unsafe (unsafeGet)
10+import Type.Proxy (Proxy(..))
11+
12+data L :: forall k. k -> Type
13+data L t = L
14+
15+type El r = ReaderT (Record r) Effect
16+type Al r = ReaderT (Record r) Aff
17+
18+l :: forall res r field m. MonadAsk (Record r) m => HasL field res r => IsSymbol field => L field -> m res
19+l L = asks (unsafeGet (reflectSymbol (Proxy :: Proxy field)))
20+
21+class HasL :: forall k1 k2 k3. k1 -> k2 -> k3 -> Constraint
22+class HasL field t r | field r -> t
23+instance (Cons field t r r', Nub r' r) => HasL field t r
el/test/Main.pursnew file+27
@@ -0,0 +1,27 @@
1+module Test.Main
2+ ( main
3+ ) where
4+
5+import Prelude
6+import Test.Unit
7+import Control.El
8+import Control.Monad.Reader (runReaderT)
9+import Effect (Effect)
10+import Effect.Aff (launchAff_)
11+import Test.Unit.Assert as Assert
12+import Test.Unit.Output.Fancy (runTest)
13+import Type.Proxy (Proxy(..))
14+
15+main ∷ Effect Unit
16+main =
17+ launchAff_ $ void
18+ $ runTest do
19+ suite "sync code" do
20+ test "arithmetic" do
21+ x <- runReaderT singleHandler { handle: 2, ignored: "Hello" }
22+ Assert.equal x 2
23+
24+singleHandler :: forall r. HasL "handle" Int r => Al r Int
25+singleHandler = do
26+ x <- l (L :: L "handle")
27+ pure $ x + 1
elm-srcs.nixdeleted−62
@@ -1,62 +0,0 @@
1−{
2−
3− "FabienHenon/elm-infinite-scroll" = {
4− sha256 = "0vhh7j3lna05l5hwjazag52lbkjv11s80jj62m9wb53qxkarw948";
5− version = "3.0.3";
6− };
7−
8− "bartavelle/json-helpers" = {
9− sha256 = "0k96qra2nq1j4j4ahfl98dkpkc6f2831mq5d5xxg27mp31qwq5nn";
10− version = "2.0.2";
11− };
12−
13− "elm/browser" = {
14− sha256 = "0nagb9ajacxbbg985r4k9h0jadqpp0gp84nm94kcgbr5sf8i9x13";
15− version = "1.0.2";
16− };
17−
18− "elm/core" = {
19− sha256 = "19w0iisdd66ywjayyga4kv2p1v9rxzqjaxhckp8ni6n8i0fb2dvf";
20− version = "1.0.5";
21− };
22−
23− "elm/html" = {
24− sha256 = "1n3gpzmpqqdsldys4ipgyl1zacn0kbpc3g4v3hdpiyfjlgh8bf3k";
25− version = "1.0.0";
26− };
27−
28− "elm/json" = {
29− sha256 = "0kjwrz195z84kwywaxhhlnpl3p251qlbm5iz6byd6jky2crmyqyh";
30− version = "1.1.3";
31− };
32−
33− "elm/time" = {
34− sha256 = "0vch7i86vn0x8b850w1p69vplll1bnbkp8s383z7pinyg94cm2z1";
35− version = "1.0.0";
36− };
37−
38− "mdgriffith/elm-ui" = {
39− sha256 = "0ffcqv4a4ad400hwp824m3qq4jy82cqp5ghmhp1m0q7n004z6kgv";
40− version = "1.1.8";
41− };
42−
43− "mgold/elm-nonempty-list" = {
44− sha256 = "02d3xgasgy5knh02rgl403z9hwlbyrsnp9wavc2lhkxxa2misrgl";
45− version = "4.2.0";
46− };
47−
48− "elm/random" = {
49− sha256 = "138n2455wdjwa657w6sjq18wx2r0k60ibpc4frhbqr50sncxrfdl";
50− version = "1.0.0";
51− };
52−
53− "elm/url" = {
54− sha256 = "0av8x5syid40sgpl5vd7pry2rq0q4pga28b4yykn9gd9v12rs3l4";
55− version = "1.0.0";
56− };
57−
58− "elm/virtual-dom" = {
59− sha256 = "1yvb8px2z62xd578ag2q0r5hd1vkz9y7dfkx05355iiy1d7jwq4v";
60− version = "1.0.3";
61− };
62−}
elm.json−1
@@ -13,7 +13,6 @@
13 "elm/html": "1.0.0",
13 "elm/html": "1.0.0",
14 "elm/json": "1.1.3",
14 "elm/json": "1.1.3",
15 "elm/time": "1.0.0",
15 "elm/time": "1.0.0",
16− "mdgriffith/elm-ui": "1.1.8",
17 "mgold/elm-nonempty-list": "4.2.0"
16 "mgold/elm-nonempty-list": "4.2.0"
18 },
17 },
19 "indirect": {
18 "indirect": {
flake.lockdeleted−177
@@ -1,177 +0,0 @@
1−{
2− "nodes": {
3− "bw": {
4− "flake": false,
5− "locked": {
6− "lastModified": 1675446731,
7− "narHash": "sha256-IbFjYNYZep6W9c+dztJ9CXrwQ0cep3EKb6qnEvv4pj4=",
8− "owner": "bitwarden",
9− "repo": "clients",
10− "rev": "ff143760d4f527f2349333ee4b3004eeda68fac5",
11− "type": "github"
12− },
13− "original": {
14− "owner": "bitwarden",
15− "repo": "clients",
16− "rev": "ff143760d4f527f2349333ee4b3004eeda68fac5",
17− "type": "github"
18− }
19− },
20− "easy-ps": {
21− "flake": false,
22− "locked": {
23− "lastModified": 1671011575,
24− "narHash": "sha256-tESal32bcqqdZO+aKnBzc1GoL2mtnaDtj2y7ociCRGA=",
25− "owner": "justinwoo",
26− "repo": "easy-purescript-nix",
27− "rev": "11d3bd58ce6e32703bf69cec04dc7c38eabe14ba",
28− "type": "github"
29− },
30− "original": {
31− "owner": "justinwoo",
32− "repo": "easy-purescript-nix",
33− "type": "github"
34− }
35− },
36− "easy-purescript-nix": {
37− "flake": false,
38− "locked": {
39− "lastModified": 1670198178,
40− "narHash": "sha256-5KkyNpPakv4xIP2ba0S5GX+dcmd3AcO9kPhwa482BbA=",
41− "owner": "justinwoo",
42− "repo": "easy-purescript-nix",
43− "rev": "7a4cb3cd6ca53566ea1675692eab0aa13907ff09",
44− "type": "github"
45− },
46− "original": {
47− "owner": "justinwoo",
48− "repo": "easy-purescript-nix",
49− "type": "github"
50− }
51− },
52− "flake-utils": {
53− "locked": {
54− "lastModified": 1676283394,
55− "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=",
56− "owner": "numtide",
57− "repo": "flake-utils",
58− "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073",
59− "type": "github"
60− },
61− "original": {
62− "owner": "numtide",
63− "repo": "flake-utils",
64− "type": "github"
65− }
66− },
67− "flake-utils_2": {
68− "locked": {
69− "lastModified": 1667395993,
70− "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
71− "owner": "numtide",
72− "repo": "flake-utils",
73− "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
74− "type": "github"
75− },
76− "original": {
77− "owner": "numtide",
78− "repo": "flake-utils",
79− "type": "github"
80− }
81− },
82− "nix-filter": {
83− "locked": {
84− "lastModified": 1676294984,
85− "narHash": "sha256-hdLUa/3RH1VJ+gMUysQE0JGM4F2Q/tIIFbtoxAOurJQ=",
86− "owner": "numtide",
87− "repo": "nix-filter",
88− "rev": "fc282c5478e4141842f9644c239a41cfe9586732",
89− "type": "github"
90− },
91− "original": {
92− "owner": "numtide",
93− "repo": "nix-filter",
94− "type": "github"
95− }
96− },
97− "nixpkgs": {
98− "locked": {
99− "lastModified": 1677080879,
100− "narHash": "sha256-0SjW4/d3Rkw6C7hHZ5lxT4r6Pw9vzQb6Il6zYWwe2Bo=",
101− "owner": "NixOS",
102− "repo": "nixpkgs",
103− "rev": "f5dad40450d272a1ea2413f4a67ac08760649e89",
104− "type": "github"
105− },
106− "original": {
107− "id": "nixpkgs",
108− "type": "indirect"
109− }
110− },
111− "nixpkgs_2": {
112− "locked": {
113− "lastModified": 1670507980,
114− "narHash": "sha256-riNZa0xzM1it3pzxciwALeMs+0CsBMWIW2FqulzK8vM=",
115− "owner": "NixOS",
116− "repo": "nixpkgs",
117− "rev": "2787fc7d1e51404678614bf0fe92fc296746eec0",
118− "type": "github"
119− },
120− "original": {
121− "owner": "NixOS",
122− "ref": "nixos-unstable",
123− "repo": "nixpkgs",
124− "type": "github"
125− }
126− },
127− "root": {
128− "inputs": {
129− "bw": "bw",
130− "easy-ps": "easy-ps",
131− "flake-utils": "flake-utils",
132− "nix-filter": "nix-filter",
133− "nixpkgs": "nixpkgs",
134− "spago2nix": "spago2nix",
135− "vanilla": "vanilla"
136− }
137− },
138− "spago2nix": {
139− "inputs": {
140− "easy-purescript-nix": "easy-purescript-nix",
141− "flake-utils": "flake-utils_2",
142− "nixpkgs": "nixpkgs_2"
143− },
144− "locked": {
145− "lastModified": 1671225584,
146− "narHash": "sha256-h9r67pmvDuA3TV9299L4CN60XSm8RRtX1EwUoKu9Pyw=",
147− "owner": "justinwoo",
148− "repo": "spago2nix",
149− "rev": "1b8ec352bc7eac077b934d6b9f6efa0129926e59",
150− "type": "github"
151− },
152− "original": {
153− "owner": "justinwoo",
154− "repo": "spago2nix",
155− "type": "github"
156− }
157− },
158− "vanilla": {
159− "flake": false,
160− "locked": {
161− "lastModified": 1663430347,
162− "narHash": "sha256-J+KyCcCMdC8SYINKAtUsNfM0/lnbwOnsY8TKOP+yY0s=",
163− "owner": "ilyakooo0",
164− "repo": "vanilla-compiled",
165− "rev": "7a0ee46ce9b958b51c57b37c46e86a0a1868bfa9",
166− "type": "github"
167− },
168− "original": {
169− "owner": "ilyakooo0",
170− "repo": "vanilla-compiled",
171− "type": "github"
172− }
173− }
174− },
175− "root": "root",
176− "version": 7
177−}
flake.nixdeleted−133
@@ -1,133 +0,0 @@
1−{
2− inputs = {
3− flake-utils.url = "github:numtide/flake-utils";
4− bw = {
5− url =
6− # Afer this commit they started requiring path at the top level and I can't deal with this right now
7− "github:bitwarden/clients?rev=ff143760d4f527f2349333ee4b3004eeda68fac5";
8− flake = false;
9− };
10− spago2nix.url = "github:justinwoo/spago2nix";
11− easy-ps = {
12− url = "github:justinwoo/easy-purescript-nix";
13− flake = false;
14− };
15− vanilla = {
16− url = "github:ilyakooo0/vanilla-compiled";
17− flake = false;
18− };
19− nix-filter.url = "github:numtide/nix-filter";
20− };
21−
22− outputs = inputs@{ self, nixpkgs, flake-utils, spago2nix, ... }:
23− flake-utils.lib.eachDefaultSystem (system:
24− let
25− pkgs = import nixpkgs { inherit system; };
26− spagoPkgs = pkgs.callPackage ./spago-packages.nix { };
27− easy-ps = pkgs.callPackage inputs.easy-ps { };
28− nix-filter = import inputs.nix-filter;
29−
30− bw = pkgs.buildNpmPackage {
31− pname = "bw";
32− version = "latest";
33− npmDepsHash = "sha256-jQvL7/SzXqVk03ncU6Mxq8lqFFy+lIrF2QheheXrQ0w=";
34− makeCacheWritable = true;
35− src = inputs.bw;
36− nativeBuildInputs = [ pkgs.python3 ];
37− buildPhase = ''
38− (cd libs/common/ && rm -r spec && find . -name "*.spec.ts" -exec rm {} \; && npm exec -c "tsc -m es2020 -t es2018") '';
39− installPhase = ''
40− mkdir -p $out
41− cp -r libs/shared/dist/* $out
42− cp -r node_modules $out/node_modules
43− cp package.json $out/package.json
44− '';
45− ELECTRON_SKIP_BINARY_DOWNLOAD = 1;
46− };
47−
48− backendBuildScript = pkgs.writeScript "build-backend.sh" ''
49− workdir=$(mktemp -d)
50− (
51− cd $workdir
52− cp -r $1 ./backend
53− cp -r ${bw} ./bw
54− cp ${./backend-main.js} backend.js
55− ${pkgs.esbuild}/bin/esbuild backend.js --bundle --define:ENVIRONMENT_IS_WEB=true --define:ENVIRONMENT_IS_WORKER=false --define:ENVIRONMENT_IS_NODE=false --define:ENVIRONMENT_IS_SHELL=false --external:fs --external:path --loader:.wasm=base64 --outfile=$out
56− )
57−
58− '';
59− backend-js = pkgs.stdenv.mkDerivation {
60− name = "backend-js";
61− buildInputs =
62− [ spagoPkgs.installSpagoStyle spagoPkgs.buildSpagoStyle ];
63− nativeBuildInputs = [ easy-ps.purs-0_15_7 easy-ps.spago ];
64− src = nix-filter {
65− root = ./.;
66− include = [
67− ./spago.dhall
68− ./packages.dhall
69− (nix-filter.inDirectory ./backend)
70− ];
71− };
72− unpackPhase = ''
73− cp $src/spago.dhall .
74− cp $src/packages.dhall .
75− cp -r $src/backend .
76− install-spago-style
77− '';
78− buildPhase = ''
79− build-spago-style "./backend/**/*.purs"
80− '';
81− installPhase = ''
82− mkdir $out
83− cp -r output/* $out/
84− '';
85− };
86−
87− backend =
88− pkgs.runCommand "backend.js" { buildInputs = [ pkgs.esbuild ]; } ''
89− ${backendBuildScript} ${backend-js}
90− '';
91−
92− frontend = pkgs.callPackage ./frontend.nix { inherit nix-filter; };
93−
94− warden-src = pkgs.runCommand "warden-src" { } ''
95− mkdir -p $out
96−
97− cp ${backend} $out/backend.js
98− cp -r ${frontend}/Main.min.js $out/elm.js
99− cp ${./index.html} $out/index.html
100− cp ${./style.css} $out/style.css
101− cp -r ${inputs.vanilla} $out/vanilla
102− '';
103−
104− warden-click-src = pkgs.runCommand "warden-click-src" { } ''
105− mkdir -p $out
106−
107− cp ${./warden.apparmor} $out/warden.apparmor
108− cp ${./warden.desktop} $out/warden.desktop
109− cp ${./manifest.json} $out/manifest.json
110− cp ${./logo.png} $out/logo.png
111− cp -r ${warden-src}/* $out/
112− '';
113−
114− warden = pkgs.writeScript "warden" ''
115− ${pkgs.electron}/bin/electron ${warden-src}/index.html
116− '';
117−
118− in {
119− packages = {
120− inherit bw frontend warden-src backendBuildScript warden-click-src;
121− vanilla = inputs.vanilla.outPath;
122− };
123− apps = {
124− inherit (spago2nix.apps.${system}) spago2nix;
125− warden = {
126− type = "app";
127− program = warden.outPath;
128− };
129− };
130−
131− devShells.default = import ./shell.nix { inherit pkgs; };
132− });
133−}
frontend.nixdeleted−49
@@ -1,49 +0,0 @@
1−{ pkgs, nix-filter }:
2−with pkgs;
3−
4−let
5− mkDerivation = { srcs ? ./elm-srcs.nix, src, name, srcdir ? "./frontend"
6− , targets ? [ ], registryDat ? ./registry.dat, outputJavaScript ? true }:
7− stdenv.mkDerivation {
8− inherit name src;
9−
10− buildInputs = [ elmPackages.elm ]
11− ++ lib.optional outputJavaScript nodePackages.uglify-js;
12−
13− buildPhase = pkgs.elmPackages.fetchElmDeps {
14− elmPackages = import srcs;
15− elmVersion = "0.19.1";
16− inherit registryDat;
17− };
18−
19− installPhase = let
20− elmfile = module:
21− "${srcdir}/${builtins.replaceStrings [ "." ] [ "/" ] module}.elm";
22− extension = if outputJavaScript then "js" else "html";
23− in ''
24− mkdir -p $out/share/doc
25− ${lib.concatStrings (map (module: ''
26− echo "compiling ${elmfile module}"
27− elm make ${
28− elmfile module
29− } --output $out/${module}.${extension} --docs $out/share/doc/${module}.json
30− ${lib.optionalString outputJavaScript ''
31− echo "minifying ${elmfile module}"
32− uglifyjs $out/${module}.${extension} --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' \
33− | uglifyjs --mangle --output $out/${module}.min.${extension}
34− ''}
35− '') targets)}
36− '';
37− };
38−in mkDerivation {
39− name = "frontend";
40− srcs = ./elm-srcs.nix;
41− src = nix-filter {
42− root = ./.;
43− include = [ (nix-filter.inDirectory ./frontend) ./elm.json ];
44− };
45− targets = [ "Main" ];
46− srcdir = "./frontend";
47− outputJavaScript = true;
48−}
49−
frontend/Bridge.elm+354−618
@@ -8,743 +8,566 @@ import Dict exposing (Dict)
8import Set exposing (Set)
8import Set exposing (Set)
9
9
10
10
11−type alias Cipher_CardCipher_brand_Maybe = (Maybe String)
11+type alias Cmd_Login =
12+ { email: String
13+ , password: String
14+ , server: String
15+ }
16+
17+jsonDecCmd_Login : Json.Decode.Decoder ( Cmd_Login )
18+jsonDecCmd_Login =
19+ Json.Decode.succeed (\pemail ppassword pserver -> {email = pemail, password = ppassword, server = pserver})
20+ |> required "email" (Json.Decode.string)
21+ |> required "password" (Json.Decode.string)
22+ |> required "server" (Json.Decode.string)
23+
24+jsonEncCmd_Login : Cmd_Login -> Value
25+jsonEncCmd_Login val =
26+ Json.Encode.object
27+ [ ("email", Json.Encode.string val.email)
28+ , ("password", Json.Encode.string val.password)
29+ , ("server", Json.Encode.string val.server)
30+ ]
31+
32+
33+
34+type Cmd =
35+ Copy String
36+ | Init
37+ | Login Cmd_Login
38+ | NeedCiphersList
39+ | NeedEmail
40+ | NeedsReset
41+ | Open String
42+ | RequestCipher String
43+ | SendMasterPassword String
12
44
13−jsonDecCipher_CardCipher_brand_Maybe : Json.Decode.Decoder ( Cipher_CardCipher_brand_Maybe )
45+jsonDecCmd : Json.Decode.Decoder ( Cmd )
14−jsonDecCipher_CardCipher_brand_Maybe =
46+jsonDecCmd =
47+ let jsonDecDictCmd = Dict.fromList
48+ [ ("Copy", Json.Decode.lazy (\_ -> Json.Decode.map Copy (Json.Decode.string)))
49+ , ("Init", Json.Decode.lazy (\_ -> Json.Decode.succeed Init))
50+ , ("Login", Json.Decode.lazy (\_ -> Json.Decode.map Login (jsonDecCmd_Login)))
51+ , ("NeedCiphersList", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedCiphersList))
52+ , ("NeedEmail", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedEmail))
53+ , ("NeedsReset", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedsReset))
54+ , ("Open", Json.Decode.lazy (\_ -> Json.Decode.map Open (Json.Decode.string)))
55+ , ("RequestCipher", Json.Decode.lazy (\_ -> Json.Decode.map RequestCipher (Json.Decode.string)))
56+ , ("SendMasterPassword", Json.Decode.lazy (\_ -> Json.Decode.map SendMasterPassword (Json.Decode.string)))
57+ ]
58+ jsonDecObjectSetCmd = Set.fromList []
59+ in decodeSumTaggedObject "Cmd" "tag" "contents" jsonDecDictCmd jsonDecObjectSetCmd
60+
61+jsonEncCmd : Cmd -> Value
62+jsonEncCmd val =
63+ let keyval v = case v of
64+ Copy v1 -> ("Copy", encodeValue (Json.Encode.string v1))
65+ Init -> ("Init", encodeValue (Json.Encode.list identity []))
66+ Login v1 -> ("Login", encodeValue (jsonEncCmd_Login v1))
67+ NeedCiphersList -> ("NeedCiphersList", encodeValue (Json.Encode.list identity []))
68+ NeedEmail -> ("NeedEmail", encodeValue (Json.Encode.list identity []))
69+ NeedsReset -> ("NeedsReset", encodeValue (Json.Encode.list identity []))
70+ Open v1 -> ("Open", encodeValue (Json.Encode.string v1))
71+ RequestCipher v1 -> ("RequestCipher", encodeValue (Json.Encode.string v1))
72+ SendMasterPassword v1 -> ("SendMasterPassword", encodeValue (Json.Encode.string v1))
73+ in encodeSumTaggedObject "tag" "contents" keyval val
74+
75+
76+
77+type alias Sub_LoadCipher_cipherType_CardCipher_brand_Maybe = (Maybe String)
78+
79+jsonDecSub_LoadCipher_cipherType_CardCipher_brand_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_CardCipher_brand_Maybe )
80+jsonDecSub_LoadCipher_cipherType_CardCipher_brand_Maybe =
15 Json.Decode.maybe (Json.Decode.string)
81 Json.Decode.maybe (Json.Decode.string)
16
82
17−jsonEncCipher_CardCipher_brand_Maybe : Cipher_CardCipher_brand_Maybe -> Value
83+jsonEncSub_LoadCipher_cipherType_CardCipher_brand_Maybe : Sub_LoadCipher_cipherType_CardCipher_brand_Maybe -> Value
18−jsonEncCipher_CardCipher_brand_Maybe val = (maybeEncode (Json.Encode.string)) val
84+jsonEncSub_LoadCipher_cipherType_CardCipher_brand_Maybe val = (maybeEncode (Json.Encode.string)) val
19
85
20
86
21
87
22−type alias Cipher_CardCipher_cardholderName_Maybe = (Maybe String)
88+type alias Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe = (Maybe String)
23
89
24−jsonDecCipher_CardCipher_cardholderName_Maybe : Json.Decode.Decoder ( Cipher_CardCipher_cardholderName_Maybe )
90+jsonDecSub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe )
25−jsonDecCipher_CardCipher_cardholderName_Maybe =
91+jsonDecSub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe =
26 Json.Decode.maybe (Json.Decode.string)
92 Json.Decode.maybe (Json.Decode.string)
27
93
28−jsonEncCipher_CardCipher_cardholderName_Maybe : Cipher_CardCipher_cardholderName_Maybe -> Value
94+jsonEncSub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe : Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe -> Value
29−jsonEncCipher_CardCipher_cardholderName_Maybe val = (maybeEncode (Json.Encode.string)) val
95+jsonEncSub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe val = (maybeEncode (Json.Encode.string)) val
30
96
31
97
32
98
33−type alias Cipher_CardCipher_code_Maybe = (Maybe String)
99+type alias Sub_LoadCipher_cipherType_CardCipher_code_Maybe = (Maybe String)
34
100
35−jsonDecCipher_CardCipher_code_Maybe : Json.Decode.Decoder ( Cipher_CardCipher_code_Maybe )
101+jsonDecSub_LoadCipher_cipherType_CardCipher_code_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_CardCipher_code_Maybe )
36−jsonDecCipher_CardCipher_code_Maybe =
102+jsonDecSub_LoadCipher_cipherType_CardCipher_code_Maybe =
37 Json.Decode.maybe (Json.Decode.string)
103 Json.Decode.maybe (Json.Decode.string)
38
104
39−jsonEncCipher_CardCipher_code_Maybe : Cipher_CardCipher_code_Maybe -> Value
105+jsonEncSub_LoadCipher_cipherType_CardCipher_code_Maybe : Sub_LoadCipher_cipherType_CardCipher_code_Maybe -> Value
40−jsonEncCipher_CardCipher_code_Maybe val = (maybeEncode (Json.Encode.string)) val
106+jsonEncSub_LoadCipher_cipherType_CardCipher_code_Maybe val = (maybeEncode (Json.Encode.string)) val
41
107
42
108
43
109
44−type alias Cipher_CardCipher_expMonth_Maybe = (Maybe String)
110+type alias Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe = (Maybe String)
45
111
46−jsonDecCipher_CardCipher_expMonth_Maybe : Json.Decode.Decoder ( Cipher_CardCipher_expMonth_Maybe )
112+jsonDecSub_LoadCipher_cipherType_CardCipher_expMonth_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe )
47−jsonDecCipher_CardCipher_expMonth_Maybe =
113+jsonDecSub_LoadCipher_cipherType_CardCipher_expMonth_Maybe =
48 Json.Decode.maybe (Json.Decode.string)
114 Json.Decode.maybe (Json.Decode.string)
49
115
50−jsonEncCipher_CardCipher_expMonth_Maybe : Cipher_CardCipher_expMonth_Maybe -> Value
116+jsonEncSub_LoadCipher_cipherType_CardCipher_expMonth_Maybe : Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe -> Value
51−jsonEncCipher_CardCipher_expMonth_Maybe val = (maybeEncode (Json.Encode.string)) val
117+jsonEncSub_LoadCipher_cipherType_CardCipher_expMonth_Maybe val = (maybeEncode (Json.Encode.string)) val
52
118
53
119
54
120
55−type alias Cipher_CardCipher_expYear_Maybe = (Maybe String)
121+type alias Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe = (Maybe String)
56
122
57−jsonDecCipher_CardCipher_expYear_Maybe : Json.Decode.Decoder ( Cipher_CardCipher_expYear_Maybe )
123+jsonDecSub_LoadCipher_cipherType_CardCipher_expYear_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe )
58−jsonDecCipher_CardCipher_expYear_Maybe =
124+jsonDecSub_LoadCipher_cipherType_CardCipher_expYear_Maybe =
59 Json.Decode.maybe (Json.Decode.string)
125 Json.Decode.maybe (Json.Decode.string)
60
126
61−jsonEncCipher_CardCipher_expYear_Maybe : Cipher_CardCipher_expYear_Maybe -> Value
127+jsonEncSub_LoadCipher_cipherType_CardCipher_expYear_Maybe : Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe -> Value
62−jsonEncCipher_CardCipher_expYear_Maybe val = (maybeEncode (Json.Encode.string)) val
128+jsonEncSub_LoadCipher_cipherType_CardCipher_expYear_Maybe val = (maybeEncode (Json.Encode.string)) val
63
129
64
130
65
131
66−type alias Cipher_CardCipher_number_Maybe = (Maybe String)
132+type alias Sub_LoadCipher_cipherType_CardCipher_number_Maybe = (Maybe String)
67
133
68−jsonDecCipher_CardCipher_number_Maybe : Json.Decode.Decoder ( Cipher_CardCipher_number_Maybe )
134+jsonDecSub_LoadCipher_cipherType_CardCipher_number_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_CardCipher_number_Maybe )
69−jsonDecCipher_CardCipher_number_Maybe =
135+jsonDecSub_LoadCipher_cipherType_CardCipher_number_Maybe =
70 Json.Decode.maybe (Json.Decode.string)
136 Json.Decode.maybe (Json.Decode.string)
71
137
72−jsonEncCipher_CardCipher_number_Maybe : Cipher_CardCipher_number_Maybe -> Value
138+jsonEncSub_LoadCipher_cipherType_CardCipher_number_Maybe : Sub_LoadCipher_cipherType_CardCipher_number_Maybe -> Value
73−jsonEncCipher_CardCipher_number_Maybe val = (maybeEncode (Json.Encode.string)) val
139+jsonEncSub_LoadCipher_cipherType_CardCipher_number_Maybe val = (maybeEncode (Json.Encode.string)) val
74
140
75
141
76
142
77−type alias Cipher_CardCipher =
143+type alias Sub_LoadCipher_cipherType_CardCipher =
78− { brand: Cipher_CardCipher_brand_Maybe
144+ { brand: Sub_LoadCipher_cipherType_CardCipher_brand_Maybe
79− , cardholderName: Cipher_CardCipher_cardholderName_Maybe
145+ , cardholderName: Sub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe
80− , code: Cipher_CardCipher_code_Maybe
146+ , code: Sub_LoadCipher_cipherType_CardCipher_code_Maybe
81− , expMonth: Cipher_CardCipher_expMonth_Maybe
147+ , expMonth: Sub_LoadCipher_cipherType_CardCipher_expMonth_Maybe
82− , expYear: Cipher_CardCipher_expYear_Maybe
148+ , expYear: Sub_LoadCipher_cipherType_CardCipher_expYear_Maybe
83− , number: Cipher_CardCipher_number_Maybe
149+ , number: Sub_LoadCipher_cipherType_CardCipher_number_Maybe
84 }
150 }
85
151
86−jsonDecCipher_CardCipher : Json.Decode.Decoder ( Cipher_CardCipher )
152+jsonDecSub_LoadCipher_cipherType_CardCipher : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_CardCipher )
87−jsonDecCipher_CardCipher =
153+jsonDecSub_LoadCipher_cipherType_CardCipher =
88 Json.Decode.succeed (\pbrand pcardholderName pcode pexpMonth pexpYear pnumber -> {brand = pbrand, cardholderName = pcardholderName, code = pcode, expMonth = pexpMonth, expYear = pexpYear, number = pnumber})
154 Json.Decode.succeed (\pbrand pcardholderName pcode pexpMonth pexpYear pnumber -> {brand = pbrand, cardholderName = pcardholderName, code = pcode, expMonth = pexpMonth, expYear = pexpYear, number = pnumber})
89− |> required "brand" (jsonDecCipher_CardCipher_brand_Maybe)
155+ |> required "brand" (jsonDecSub_LoadCipher_cipherType_CardCipher_brand_Maybe)
90− |> required "cardholderName" (jsonDecCipher_CardCipher_cardholderName_Maybe)
156+ |> required "cardholderName" (jsonDecSub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe)
91− |> required "code" (jsonDecCipher_CardCipher_code_Maybe)
157+ |> required "code" (jsonDecSub_LoadCipher_cipherType_CardCipher_code_Maybe)
92− |> required "expMonth" (jsonDecCipher_CardCipher_expMonth_Maybe)
158+ |> required "expMonth" (jsonDecSub_LoadCipher_cipherType_CardCipher_expMonth_Maybe)
93− |> required "expYear" (jsonDecCipher_CardCipher_expYear_Maybe)
159+ |> required "expYear" (jsonDecSub_LoadCipher_cipherType_CardCipher_expYear_Maybe)
94− |> required "number" (jsonDecCipher_CardCipher_number_Maybe)
160+ |> required "number" (jsonDecSub_LoadCipher_cipherType_CardCipher_number_Maybe)
95−
161+
96−jsonEncCipher_CardCipher : Cipher_CardCipher -> Value
162+jsonEncSub_LoadCipher_cipherType_CardCipher : Sub_LoadCipher_cipherType_CardCipher -> Value
97−jsonEncCipher_CardCipher val =
163+jsonEncSub_LoadCipher_cipherType_CardCipher val =
98 Json.Encode.object
164 Json.Encode.object
99− [ ("brand", jsonEncCipher_CardCipher_brand_Maybe val.brand)
165+ [ ("brand", jsonEncSub_LoadCipher_cipherType_CardCipher_brand_Maybe val.brand)
100− , ("cardholderName", jsonEncCipher_CardCipher_cardholderName_Maybe val.cardholderName)
166+ , ("cardholderName", jsonEncSub_LoadCipher_cipherType_CardCipher_cardholderName_Maybe val.cardholderName)
101− , ("code", jsonEncCipher_CardCipher_code_Maybe val.code)
167+ , ("code", jsonEncSub_LoadCipher_cipherType_CardCipher_code_Maybe val.code)
102− , ("expMonth", jsonEncCipher_CardCipher_expMonth_Maybe val.expMonth)
168+ , ("expMonth", jsonEncSub_LoadCipher_cipherType_CardCipher_expMonth_Maybe val.expMonth)
103− , ("expYear", jsonEncCipher_CardCipher_expYear_Maybe val.expYear)
169+ , ("expYear", jsonEncSub_LoadCipher_cipherType_CardCipher_expYear_Maybe val.expYear)
104− , ("number", jsonEncCipher_CardCipher_number_Maybe val.number)
170+ , ("number", jsonEncSub_LoadCipher_cipherType_CardCipher_number_Maybe val.number)
105 ]
171 ]
106
172
107
173
108
174
109−type alias Cipher_IdentityCipher_address1_Maybe = (Maybe String)
175+type alias Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe = (Maybe String)
110
176
111−jsonDecCipher_IdentityCipher_address1_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_address1_Maybe )
177+jsonDecSub_LoadCipher_cipherType_IdentityCipher_address1_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe )
112−jsonDecCipher_IdentityCipher_address1_Maybe =
178+jsonDecSub_LoadCipher_cipherType_IdentityCipher_address1_Maybe =
113 Json.Decode.maybe (Json.Decode.string)
179 Json.Decode.maybe (Json.Decode.string)
114
180
115−jsonEncCipher_IdentityCipher_address1_Maybe : Cipher_IdentityCipher_address1_Maybe -> Value
181+jsonEncSub_LoadCipher_cipherType_IdentityCipher_address1_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe -> Value
116−jsonEncCipher_IdentityCipher_address1_Maybe val = (maybeEncode (Json.Encode.string)) val
182+jsonEncSub_LoadCipher_cipherType_IdentityCipher_address1_Maybe val = (maybeEncode (Json.Encode.string)) val
117
183
118
184
119
185
120−type alias Cipher_IdentityCipher_address2_Maybe = (Maybe String)
186+type alias Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe = (Maybe String)
121
187
122−jsonDecCipher_IdentityCipher_address2_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_address2_Maybe )
188+jsonDecSub_LoadCipher_cipherType_IdentityCipher_address2_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe )
123−jsonDecCipher_IdentityCipher_address2_Maybe =
189+jsonDecSub_LoadCipher_cipherType_IdentityCipher_address2_Maybe =
124 Json.Decode.maybe (Json.Decode.string)
190 Json.Decode.maybe (Json.Decode.string)
125
191
126−jsonEncCipher_IdentityCipher_address2_Maybe : Cipher_IdentityCipher_address2_Maybe -> Value
192+jsonEncSub_LoadCipher_cipherType_IdentityCipher_address2_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe -> Value
127−jsonEncCipher_IdentityCipher_address2_Maybe val = (maybeEncode (Json.Encode.string)) val
193+jsonEncSub_LoadCipher_cipherType_IdentityCipher_address2_Maybe val = (maybeEncode (Json.Encode.string)) val
128
194
129
195
130
196
131−type alias Cipher_IdentityCipher_address3_Maybe = (Maybe String)
197+type alias Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe = (Maybe String)
132
198
133−jsonDecCipher_IdentityCipher_address3_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_address3_Maybe )
199+jsonDecSub_LoadCipher_cipherType_IdentityCipher_address3_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe )
134−jsonDecCipher_IdentityCipher_address3_Maybe =
200+jsonDecSub_LoadCipher_cipherType_IdentityCipher_address3_Maybe =
135 Json.Decode.maybe (Json.Decode.string)
201 Json.Decode.maybe (Json.Decode.string)
136
202
137−jsonEncCipher_IdentityCipher_address3_Maybe : Cipher_IdentityCipher_address3_Maybe -> Value
203+jsonEncSub_LoadCipher_cipherType_IdentityCipher_address3_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe -> Value
138−jsonEncCipher_IdentityCipher_address3_Maybe val = (maybeEncode (Json.Encode.string)) val
204+jsonEncSub_LoadCipher_cipherType_IdentityCipher_address3_Maybe val = (maybeEncode (Json.Encode.string)) val
139
205
140
206
141
207
142−type alias Cipher_IdentityCipher_city_Maybe = (Maybe String)
208+type alias Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe = (Maybe String)
143
209
144−jsonDecCipher_IdentityCipher_city_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_city_Maybe )
210+jsonDecSub_LoadCipher_cipherType_IdentityCipher_city_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe )
145−jsonDecCipher_IdentityCipher_city_Maybe =
211+jsonDecSub_LoadCipher_cipherType_IdentityCipher_city_Maybe =
146 Json.Decode.maybe (Json.Decode.string)
212 Json.Decode.maybe (Json.Decode.string)
147
213
148−jsonEncCipher_IdentityCipher_city_Maybe : Cipher_IdentityCipher_city_Maybe -> Value
214+jsonEncSub_LoadCipher_cipherType_IdentityCipher_city_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe -> Value
149−jsonEncCipher_IdentityCipher_city_Maybe val = (maybeEncode (Json.Encode.string)) val
215+jsonEncSub_LoadCipher_cipherType_IdentityCipher_city_Maybe val = (maybeEncode (Json.Encode.string)) val
150
216
151
217
152
218
153−type alias Cipher_IdentityCipher_company_Maybe = (Maybe String)
219+type alias Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe = (Maybe String)
154
220
155−jsonDecCipher_IdentityCipher_company_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_company_Maybe )
221+jsonDecSub_LoadCipher_cipherType_IdentityCipher_company_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe )
156−jsonDecCipher_IdentityCipher_company_Maybe =
222+jsonDecSub_LoadCipher_cipherType_IdentityCipher_company_Maybe =
157 Json.Decode.maybe (Json.Decode.string)
223 Json.Decode.maybe (Json.Decode.string)
158
224
159−jsonEncCipher_IdentityCipher_company_Maybe : Cipher_IdentityCipher_company_Maybe -> Value
225+jsonEncSub_LoadCipher_cipherType_IdentityCipher_company_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe -> Value
160−jsonEncCipher_IdentityCipher_company_Maybe val = (maybeEncode (Json.Encode.string)) val
226+jsonEncSub_LoadCipher_cipherType_IdentityCipher_company_Maybe val = (maybeEncode (Json.Encode.string)) val
161
227
162
228
163
229
164−type alias Cipher_IdentityCipher_country_Maybe = (Maybe String)
230+type alias Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe = (Maybe String)
165
231
166−jsonDecCipher_IdentityCipher_country_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_country_Maybe )
232+jsonDecSub_LoadCipher_cipherType_IdentityCipher_country_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe )
167−jsonDecCipher_IdentityCipher_country_Maybe =
233+jsonDecSub_LoadCipher_cipherType_IdentityCipher_country_Maybe =
168 Json.Decode.maybe (Json.Decode.string)
234 Json.Decode.maybe (Json.Decode.string)
169
235
170−jsonEncCipher_IdentityCipher_country_Maybe : Cipher_IdentityCipher_country_Maybe -> Value
236+jsonEncSub_LoadCipher_cipherType_IdentityCipher_country_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe -> Value
171−jsonEncCipher_IdentityCipher_country_Maybe val = (maybeEncode (Json.Encode.string)) val
237+jsonEncSub_LoadCipher_cipherType_IdentityCipher_country_Maybe val = (maybeEncode (Json.Encode.string)) val
172
238
173
239
174
240
175−type alias Cipher_IdentityCipher_email_Maybe = (Maybe String)
241+type alias Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe = (Maybe String)
176
242
177−jsonDecCipher_IdentityCipher_email_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_email_Maybe )
243+jsonDecSub_LoadCipher_cipherType_IdentityCipher_email_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe )
178−jsonDecCipher_IdentityCipher_email_Maybe =
244+jsonDecSub_LoadCipher_cipherType_IdentityCipher_email_Maybe =
179 Json.Decode.maybe (Json.Decode.string)
245 Json.Decode.maybe (Json.Decode.string)
180
246
181−jsonEncCipher_IdentityCipher_email_Maybe : Cipher_IdentityCipher_email_Maybe -> Value
247+jsonEncSub_LoadCipher_cipherType_IdentityCipher_email_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe -> Value
182−jsonEncCipher_IdentityCipher_email_Maybe val = (maybeEncode (Json.Encode.string)) val
248+jsonEncSub_LoadCipher_cipherType_IdentityCipher_email_Maybe val = (maybeEncode (Json.Encode.string)) val
183
249
184
250
185
251
186−type alias Cipher_IdentityCipher_firstName_Maybe = (Maybe String)
252+type alias Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe = (Maybe String)
187
253
188−jsonDecCipher_IdentityCipher_firstName_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_firstName_Maybe )
254+jsonDecSub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe )
189−jsonDecCipher_IdentityCipher_firstName_Maybe =
255+jsonDecSub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe =
190 Json.Decode.maybe (Json.Decode.string)
256 Json.Decode.maybe (Json.Decode.string)
191
257
192−jsonEncCipher_IdentityCipher_firstName_Maybe : Cipher_IdentityCipher_firstName_Maybe -> Value
258+jsonEncSub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe -> Value
193−jsonEncCipher_IdentityCipher_firstName_Maybe val = (maybeEncode (Json.Encode.string)) val
259+jsonEncSub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe val = (maybeEncode (Json.Encode.string)) val
194
260
195
261
196
262
197−type alias Cipher_IdentityCipher_lastName_Maybe = (Maybe String)
263+type alias Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe = (Maybe String)
198
264
199−jsonDecCipher_IdentityCipher_lastName_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_lastName_Maybe )
265+jsonDecSub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe )
200−jsonDecCipher_IdentityCipher_lastName_Maybe =
266+jsonDecSub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe =
201 Json.Decode.maybe (Json.Decode.string)
267 Json.Decode.maybe (Json.Decode.string)
202
268
203−jsonEncCipher_IdentityCipher_lastName_Maybe : Cipher_IdentityCipher_lastName_Maybe -> Value
269+jsonEncSub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe -> Value
204−jsonEncCipher_IdentityCipher_lastName_Maybe val = (maybeEncode (Json.Encode.string)) val
270+jsonEncSub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe val = (maybeEncode (Json.Encode.string)) val
205
271
206
272
207
273
208−type alias Cipher_IdentityCipher_licenseNumber_Maybe = (Maybe String)
274+type alias Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe = (Maybe String)
209
275
210−jsonDecCipher_IdentityCipher_licenseNumber_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_licenseNumber_Maybe )
276+jsonDecSub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe )
211−jsonDecCipher_IdentityCipher_licenseNumber_Maybe =
277+jsonDecSub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe =
212 Json.Decode.maybe (Json.Decode.string)
278 Json.Decode.maybe (Json.Decode.string)
213
279
214−jsonEncCipher_IdentityCipher_licenseNumber_Maybe : Cipher_IdentityCipher_licenseNumber_Maybe -> Value
280+jsonEncSub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe -> Value
215−jsonEncCipher_IdentityCipher_licenseNumber_Maybe val = (maybeEncode (Json.Encode.string)) val
281+jsonEncSub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe val = (maybeEncode (Json.Encode.string)) val
216
282
217
283
218
284
219−type alias Cipher_IdentityCipher_middleName_Maybe = (Maybe String)
285+type alias Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe = (Maybe String)
220
286
221−jsonDecCipher_IdentityCipher_middleName_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_middleName_Maybe )
287+jsonDecSub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe )
222−jsonDecCipher_IdentityCipher_middleName_Maybe =
288+jsonDecSub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe =
223 Json.Decode.maybe (Json.Decode.string)
289 Json.Decode.maybe (Json.Decode.string)
224
290
225−jsonEncCipher_IdentityCipher_middleName_Maybe : Cipher_IdentityCipher_middleName_Maybe -> Value
291+jsonEncSub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe -> Value
226−jsonEncCipher_IdentityCipher_middleName_Maybe val = (maybeEncode (Json.Encode.string)) val
292+jsonEncSub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe val = (maybeEncode (Json.Encode.string)) val
227
293
228
294
229
295
230−type alias Cipher_IdentityCipher_passportNumber_Maybe = (Maybe String)
296+type alias Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe = (Maybe String)
231
297
232−jsonDecCipher_IdentityCipher_passportNumber_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_passportNumber_Maybe )
298+jsonDecSub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe )
233−jsonDecCipher_IdentityCipher_passportNumber_Maybe =
299+jsonDecSub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe =
234 Json.Decode.maybe (Json.Decode.string)
300 Json.Decode.maybe (Json.Decode.string)
235
301
236−jsonEncCipher_IdentityCipher_passportNumber_Maybe : Cipher_IdentityCipher_passportNumber_Maybe -> Value
302+jsonEncSub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe -> Value
237−jsonEncCipher_IdentityCipher_passportNumber_Maybe val = (maybeEncode (Json.Encode.string)) val
303+jsonEncSub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe val = (maybeEncode (Json.Encode.string)) val
238
304
239
305
240
306
241−type alias Cipher_IdentityCipher_phone_Maybe = (Maybe String)
307+type alias Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe = (Maybe String)
242
308
243−jsonDecCipher_IdentityCipher_phone_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_phone_Maybe )
309+jsonDecSub_LoadCipher_cipherType_IdentityCipher_phone_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe )
244−jsonDecCipher_IdentityCipher_phone_Maybe =
310+jsonDecSub_LoadCipher_cipherType_IdentityCipher_phone_Maybe =
245 Json.Decode.maybe (Json.Decode.string)
311 Json.Decode.maybe (Json.Decode.string)
246
312
247−jsonEncCipher_IdentityCipher_phone_Maybe : Cipher_IdentityCipher_phone_Maybe -> Value
313+jsonEncSub_LoadCipher_cipherType_IdentityCipher_phone_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe -> Value
248−jsonEncCipher_IdentityCipher_phone_Maybe val = (maybeEncode (Json.Encode.string)) val
314+jsonEncSub_LoadCipher_cipherType_IdentityCipher_phone_Maybe val = (maybeEncode (Json.Encode.string)) val
249
315
250
316
251
317
252−type alias Cipher_IdentityCipher_postalCode_Maybe = (Maybe String)
318+type alias Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe = (Maybe String)
253
319
254−jsonDecCipher_IdentityCipher_postalCode_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_postalCode_Maybe )
320+jsonDecSub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe )
255−jsonDecCipher_IdentityCipher_postalCode_Maybe =
321+jsonDecSub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe =
256 Json.Decode.maybe (Json.Decode.string)
322 Json.Decode.maybe (Json.Decode.string)
257
323
258−jsonEncCipher_IdentityCipher_postalCode_Maybe : Cipher_IdentityCipher_postalCode_Maybe -> Value
324+jsonEncSub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe -> Value
259−jsonEncCipher_IdentityCipher_postalCode_Maybe val = (maybeEncode (Json.Encode.string)) val
325+jsonEncSub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe val = (maybeEncode (Json.Encode.string)) val
260
326
261
327
262
328
263−type alias Cipher_IdentityCipher_ssn_Maybe = (Maybe String)
329+type alias Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe = (Maybe String)
264
330
265−jsonDecCipher_IdentityCipher_ssn_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_ssn_Maybe )
331+jsonDecSub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe )
266−jsonDecCipher_IdentityCipher_ssn_Maybe =
332+jsonDecSub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe =
267 Json.Decode.maybe (Json.Decode.string)
333 Json.Decode.maybe (Json.Decode.string)
268
334
269−jsonEncCipher_IdentityCipher_ssn_Maybe : Cipher_IdentityCipher_ssn_Maybe -> Value
335+jsonEncSub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe -> Value
270−jsonEncCipher_IdentityCipher_ssn_Maybe val = (maybeEncode (Json.Encode.string)) val
336+jsonEncSub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe val = (maybeEncode (Json.Encode.string)) val
271
337
272
338
273
339
274−type alias Cipher_IdentityCipher_state_Maybe = (Maybe String)
340+type alias Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe = (Maybe String)
275
341
276−jsonDecCipher_IdentityCipher_state_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_state_Maybe )
342+jsonDecSub_LoadCipher_cipherType_IdentityCipher_state_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe )
277−jsonDecCipher_IdentityCipher_state_Maybe =
343+jsonDecSub_LoadCipher_cipherType_IdentityCipher_state_Maybe =
278 Json.Decode.maybe (Json.Decode.string)
344 Json.Decode.maybe (Json.Decode.string)
279
345
280−jsonEncCipher_IdentityCipher_state_Maybe : Cipher_IdentityCipher_state_Maybe -> Value
346+jsonEncSub_LoadCipher_cipherType_IdentityCipher_state_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe -> Value
281−jsonEncCipher_IdentityCipher_state_Maybe val = (maybeEncode (Json.Encode.string)) val
347+jsonEncSub_LoadCipher_cipherType_IdentityCipher_state_Maybe val = (maybeEncode (Json.Encode.string)) val
282
348
283
349
284
350
285−type alias Cipher_IdentityCipher_title_Maybe = (Maybe String)
351+type alias Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe = (Maybe String)
286
352
287−jsonDecCipher_IdentityCipher_title_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_title_Maybe )
353+jsonDecSub_LoadCipher_cipherType_IdentityCipher_title_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe )
288−jsonDecCipher_IdentityCipher_title_Maybe =
354+jsonDecSub_LoadCipher_cipherType_IdentityCipher_title_Maybe =
289 Json.Decode.maybe (Json.Decode.string)
355 Json.Decode.maybe (Json.Decode.string)
290
356
291−jsonEncCipher_IdentityCipher_title_Maybe : Cipher_IdentityCipher_title_Maybe -> Value
357+jsonEncSub_LoadCipher_cipherType_IdentityCipher_title_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe -> Value
292−jsonEncCipher_IdentityCipher_title_Maybe val = (maybeEncode (Json.Encode.string)) val
358+jsonEncSub_LoadCipher_cipherType_IdentityCipher_title_Maybe val = (maybeEncode (Json.Encode.string)) val
293
359
294
360
295
361
296−type alias Cipher_IdentityCipher_username_Maybe = (Maybe String)
362+type alias Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe = (Maybe String)
297
363
298−jsonDecCipher_IdentityCipher_username_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_username_Maybe )
364+jsonDecSub_LoadCipher_cipherType_IdentityCipher_username_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe )
299−jsonDecCipher_IdentityCipher_username_Maybe =
365+jsonDecSub_LoadCipher_cipherType_IdentityCipher_username_Maybe =
300 Json.Decode.maybe (Json.Decode.string)
366 Json.Decode.maybe (Json.Decode.string)
301
367
302−jsonEncCipher_IdentityCipher_username_Maybe : Cipher_IdentityCipher_username_Maybe -> Value
368+jsonEncSub_LoadCipher_cipherType_IdentityCipher_username_Maybe : Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe -> Value
303−jsonEncCipher_IdentityCipher_username_Maybe val = (maybeEncode (Json.Encode.string)) val
369+jsonEncSub_LoadCipher_cipherType_IdentityCipher_username_Maybe val = (maybeEncode (Json.Encode.string)) val
304−
370+
305−
371+
306−
372+
307−type alias Cipher_IdentityCipher =
373+type alias Sub_LoadCipher_cipherType_IdentityCipher =
308− { address1: Cipher_IdentityCipher_address1_Maybe
374+ { address1: Sub_LoadCipher_cipherType_IdentityCipher_address1_Maybe
309− , address2: Cipher_IdentityCipher_address2_Maybe
375+ , address2: Sub_LoadCipher_cipherType_IdentityCipher_address2_Maybe
310− , address3: Cipher_IdentityCipher_address3_Maybe
376+ , address3: Sub_LoadCipher_cipherType_IdentityCipher_address3_Maybe
311− , city: Cipher_IdentityCipher_city_Maybe
377+ , city: Sub_LoadCipher_cipherType_IdentityCipher_city_Maybe
312− , company: Cipher_IdentityCipher_company_Maybe
378+ , company: Sub_LoadCipher_cipherType_IdentityCipher_company_Maybe
313− , country: Cipher_IdentityCipher_country_Maybe
379+ , country: Sub_LoadCipher_cipherType_IdentityCipher_country_Maybe
314− , email: Cipher_IdentityCipher_email_Maybe
380+ , email: Sub_LoadCipher_cipherType_IdentityCipher_email_Maybe
315− , firstName: Cipher_IdentityCipher_firstName_Maybe
381+ , firstName: Sub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe
316− , lastName: Cipher_IdentityCipher_lastName_Maybe
382+ , lastName: Sub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe
317− , licenseNumber: Cipher_IdentityCipher_licenseNumber_Maybe
383+ , licenseNumber: Sub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe
318− , middleName: Cipher_IdentityCipher_middleName_Maybe
384+ , middleName: Sub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe
319− , passportNumber: Cipher_IdentityCipher_passportNumber_Maybe
385+ , passportNumber: Sub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe
320− , phone: Cipher_IdentityCipher_phone_Maybe
386+ , phone: Sub_LoadCipher_cipherType_IdentityCipher_phone_Maybe
321− , postalCode: Cipher_IdentityCipher_postalCode_Maybe
387+ , postalCode: Sub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe
322− , ssn: Cipher_IdentityCipher_ssn_Maybe
388+ , ssn: Sub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe
323− , state: Cipher_IdentityCipher_state_Maybe
389+ , state: Sub_LoadCipher_cipherType_IdentityCipher_state_Maybe
324− , title: Cipher_IdentityCipher_title_Maybe
390+ , title: Sub_LoadCipher_cipherType_IdentityCipher_title_Maybe
325− , username: Cipher_IdentityCipher_username_Maybe
391+ , username: Sub_LoadCipher_cipherType_IdentityCipher_username_Maybe
326 }
392 }
327
393
328−jsonDecCipher_IdentityCipher : Json.Decode.Decoder ( Cipher_IdentityCipher )
394+jsonDecSub_LoadCipher_cipherType_IdentityCipher : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_IdentityCipher )
329−jsonDecCipher_IdentityCipher =
395+jsonDecSub_LoadCipher_cipherType_IdentityCipher =
330 Json.Decode.succeed (\paddress1 paddress2 paddress3 pcity pcompany pcountry pemail pfirstName plastName plicenseNumber pmiddleName ppassportNumber pphone ppostalCode pssn pstate ptitle pusername -> {address1 = paddress1, address2 = paddress2, address3 = paddress3, city = pcity, company = pcompany, country = pcountry, email = pemail, firstName = pfirstName, lastName = plastName, licenseNumber = plicenseNumber, middleName = pmiddleName, passportNumber = ppassportNumber, phone = pphone, postalCode = ppostalCode, ssn = pssn, state = pstate, title = ptitle, username = pusername})
396 Json.Decode.succeed (\paddress1 paddress2 paddress3 pcity pcompany pcountry pemail pfirstName plastName plicenseNumber pmiddleName ppassportNumber pphone ppostalCode pssn pstate ptitle pusername -> {address1 = paddress1, address2 = paddress2, address3 = paddress3, city = pcity, company = pcompany, country = pcountry, email = pemail, firstName = pfirstName, lastName = plastName, licenseNumber = plicenseNumber, middleName = pmiddleName, passportNumber = ppassportNumber, phone = pphone, postalCode = ppostalCode, ssn = pssn, state = pstate, title = ptitle, username = pusername})
331− |> required "address1" (jsonDecCipher_IdentityCipher_address1_Maybe)
397+ |> required "address1" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_address1_Maybe)
332− |> required "address2" (jsonDecCipher_IdentityCipher_address2_Maybe)
398+ |> required "address2" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_address2_Maybe)
333− |> required "address3" (jsonDecCipher_IdentityCipher_address3_Maybe)
399+ |> required "address3" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_address3_Maybe)
334− |> required "city" (jsonDecCipher_IdentityCipher_city_Maybe)
400+ |> required "city" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_city_Maybe)
335− |> required "company" (jsonDecCipher_IdentityCipher_company_Maybe)
401+ |> required "company" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_company_Maybe)
336− |> required "country" (jsonDecCipher_IdentityCipher_country_Maybe)
402+ |> required "country" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_country_Maybe)
337− |> required "email" (jsonDecCipher_IdentityCipher_email_Maybe)
403+ |> required "email" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_email_Maybe)
338− |> required "firstName" (jsonDecCipher_IdentityCipher_firstName_Maybe)
404+ |> required "firstName" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe)
339− |> required "lastName" (jsonDecCipher_IdentityCipher_lastName_Maybe)
405+ |> required "lastName" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe)
340− |> required "licenseNumber" (jsonDecCipher_IdentityCipher_licenseNumber_Maybe)
406+ |> required "licenseNumber" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe)
341− |> required "middleName" (jsonDecCipher_IdentityCipher_middleName_Maybe)
407+ |> required "middleName" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe)
342− |> required "passportNumber" (jsonDecCipher_IdentityCipher_passportNumber_Maybe)
408+ |> required "passportNumber" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe)
343− |> required "phone" (jsonDecCipher_IdentityCipher_phone_Maybe)
409+ |> required "phone" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_phone_Maybe)
344− |> required "postalCode" (jsonDecCipher_IdentityCipher_postalCode_Maybe)
410+ |> required "postalCode" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe)
345− |> required "ssn" (jsonDecCipher_IdentityCipher_ssn_Maybe)
411+ |> required "ssn" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe)
346− |> required "state" (jsonDecCipher_IdentityCipher_state_Maybe)
412+ |> required "state" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_state_Maybe)
347− |> required "title" (jsonDecCipher_IdentityCipher_title_Maybe)
413+ |> required "title" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_title_Maybe)
348− |> required "username" (jsonDecCipher_IdentityCipher_username_Maybe)
414+ |> required "username" (jsonDecSub_LoadCipher_cipherType_IdentityCipher_username_Maybe)
349−
415+
350−jsonEncCipher_IdentityCipher : Cipher_IdentityCipher -> Value
416+jsonEncSub_LoadCipher_cipherType_IdentityCipher : Sub_LoadCipher_cipherType_IdentityCipher -> Value
351−jsonEncCipher_IdentityCipher val =
417+jsonEncSub_LoadCipher_cipherType_IdentityCipher val =
352 Json.Encode.object
418 Json.Encode.object
353− [ ("address1", jsonEncCipher_IdentityCipher_address1_Maybe val.address1)
419+ [ ("address1", jsonEncSub_LoadCipher_cipherType_IdentityCipher_address1_Maybe val.address1)
354− , ("address2", jsonEncCipher_IdentityCipher_address2_Maybe val.address2)
420+ , ("address2", jsonEncSub_LoadCipher_cipherType_IdentityCipher_address2_Maybe val.address2)
355− , ("address3", jsonEncCipher_IdentityCipher_address3_Maybe val.address3)
421+ , ("address3", jsonEncSub_LoadCipher_cipherType_IdentityCipher_address3_Maybe val.address3)
356− , ("city", jsonEncCipher_IdentityCipher_city_Maybe val.city)
422+ , ("city", jsonEncSub_LoadCipher_cipherType_IdentityCipher_city_Maybe val.city)
357− , ("company", jsonEncCipher_IdentityCipher_company_Maybe val.company)
423+ , ("company", jsonEncSub_LoadCipher_cipherType_IdentityCipher_company_Maybe val.company)
358− , ("country", jsonEncCipher_IdentityCipher_country_Maybe val.country)
424+ , ("country", jsonEncSub_LoadCipher_cipherType_IdentityCipher_country_Maybe val.country)
359− , ("email", jsonEncCipher_IdentityCipher_email_Maybe val.email)
425+ , ("email", jsonEncSub_LoadCipher_cipherType_IdentityCipher_email_Maybe val.email)
360− , ("firstName", jsonEncCipher_IdentityCipher_firstName_Maybe val.firstName)
426+ , ("firstName", jsonEncSub_LoadCipher_cipherType_IdentityCipher_firstName_Maybe val.firstName)
361− , ("lastName", jsonEncCipher_IdentityCipher_lastName_Maybe val.lastName)
427+ , ("lastName", jsonEncSub_LoadCipher_cipherType_IdentityCipher_lastName_Maybe val.lastName)
362− , ("licenseNumber", jsonEncCipher_IdentityCipher_licenseNumber_Maybe val.licenseNumber)
428+ , ("licenseNumber", jsonEncSub_LoadCipher_cipherType_IdentityCipher_licenseNumber_Maybe val.licenseNumber)
363− , ("middleName", jsonEncCipher_IdentityCipher_middleName_Maybe val.middleName)
429+ , ("middleName", jsonEncSub_LoadCipher_cipherType_IdentityCipher_middleName_Maybe val.middleName)
364− , ("passportNumber", jsonEncCipher_IdentityCipher_passportNumber_Maybe val.passportNumber)
430+ , ("passportNumber", jsonEncSub_LoadCipher_cipherType_IdentityCipher_passportNumber_Maybe val.passportNumber)
365− , ("phone", jsonEncCipher_IdentityCipher_phone_Maybe val.phone)
431+ , ("phone", jsonEncSub_LoadCipher_cipherType_IdentityCipher_phone_Maybe val.phone)
366− , ("postalCode", jsonEncCipher_IdentityCipher_postalCode_Maybe val.postalCode)
432+ , ("postalCode", jsonEncSub_LoadCipher_cipherType_IdentityCipher_postalCode_Maybe val.postalCode)
367− , ("ssn", jsonEncCipher_IdentityCipher_ssn_Maybe val.ssn)
433+ , ("ssn", jsonEncSub_LoadCipher_cipherType_IdentityCipher_ssn_Maybe val.ssn)
368− , ("state", jsonEncCipher_IdentityCipher_state_Maybe val.state)
434+ , ("state", jsonEncSub_LoadCipher_cipherType_IdentityCipher_state_Maybe val.state)
369− , ("title", jsonEncCipher_IdentityCipher_title_Maybe val.title)
435+ , ("title", jsonEncSub_LoadCipher_cipherType_IdentityCipher_title_Maybe val.title)
370− , ("username", jsonEncCipher_IdentityCipher_username_Maybe val.username)
436+ , ("username", jsonEncSub_LoadCipher_cipherType_IdentityCipher_username_Maybe val.username)
371 ]
437 ]
372
438
373
439
374
440
375−type alias Cipher_LoginCipher_password_Maybe = (Maybe String)
441+type alias Sub_LoadCipher_cipherType_LoginCipher_password_Maybe = (Maybe String)
376
442
377−jsonDecCipher_LoginCipher_password_Maybe : Json.Decode.Decoder ( Cipher_LoginCipher_password_Maybe )
443+jsonDecSub_LoadCipher_cipherType_LoginCipher_password_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_LoginCipher_password_Maybe )
378−jsonDecCipher_LoginCipher_password_Maybe =
444+jsonDecSub_LoadCipher_cipherType_LoginCipher_password_Maybe =
379 Json.Decode.maybe (Json.Decode.string)
445 Json.Decode.maybe (Json.Decode.string)
380
446
381−jsonEncCipher_LoginCipher_password_Maybe : Cipher_LoginCipher_password_Maybe -> Value
447+jsonEncSub_LoadCipher_cipherType_LoginCipher_password_Maybe : Sub_LoadCipher_cipherType_LoginCipher_password_Maybe -> Value
382−jsonEncCipher_LoginCipher_password_Maybe val = (maybeEncode (Json.Encode.string)) val
448+jsonEncSub_LoadCipher_cipherType_LoginCipher_password_Maybe val = (maybeEncode (Json.Encode.string)) val
383−
384−
385−
386−type alias Cipher_LoginCipher_totp_Maybe = (Maybe String)
387−
388−jsonDecCipher_LoginCipher_totp_Maybe : Json.Decode.Decoder ( Cipher_LoginCipher_totp_Maybe )
389−jsonDecCipher_LoginCipher_totp_Maybe =
390− Json.Decode.maybe (Json.Decode.string)
391
449
392−jsonEncCipher_LoginCipher_totp_Maybe : Cipher_LoginCipher_totp_Maybe -> Value
393−jsonEncCipher_LoginCipher_totp_Maybe val = (maybeEncode (Json.Encode.string)) val
394
450
395
451
452+type alias Sub_LoadCipher_cipherType_LoginCipher_uris_List = (List String)
396
453
397−type alias Cipher_LoginCipher_uris_List = (List String)
454+jsonDecSub_LoadCipher_cipherType_LoginCipher_uris_List : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_LoginCipher_uris_List )
398−
455+jsonDecSub_LoadCipher_cipherType_LoginCipher_uris_List =
399−jsonDecCipher_LoginCipher_uris_List : Json.Decode.Decoder ( Cipher_LoginCipher_uris_List )
400−jsonDecCipher_LoginCipher_uris_List =
401 Json.Decode.list (Json.Decode.string)
456 Json.Decode.list (Json.Decode.string)
402
457
403−jsonEncCipher_LoginCipher_uris_List : Cipher_LoginCipher_uris_List -> Value
458+jsonEncSub_LoadCipher_cipherType_LoginCipher_uris_List : Sub_LoadCipher_cipherType_LoginCipher_uris_List -> Value
404−jsonEncCipher_LoginCipher_uris_List val = (Json.Encode.list Json.Encode.string) val
459+jsonEncSub_LoadCipher_cipherType_LoginCipher_uris_List val = (Json.Encode.list Json.Encode.string) val
405
460
406
461
407
462
408−type alias Cipher_LoginCipher_username_Maybe = (Maybe String)
463+type alias Sub_LoadCipher_cipherType_LoginCipher_username_Maybe = (Maybe String)
409
464
410−jsonDecCipher_LoginCipher_username_Maybe : Json.Decode.Decoder ( Cipher_LoginCipher_username_Maybe )
465+jsonDecSub_LoadCipher_cipherType_LoginCipher_username_Maybe : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_LoginCipher_username_Maybe )
411−jsonDecCipher_LoginCipher_username_Maybe =
466+jsonDecSub_LoadCipher_cipherType_LoginCipher_username_Maybe =
412 Json.Decode.maybe (Json.Decode.string)
467 Json.Decode.maybe (Json.Decode.string)
413
468
414−jsonEncCipher_LoginCipher_username_Maybe : Cipher_LoginCipher_username_Maybe -> Value
469+jsonEncSub_LoadCipher_cipherType_LoginCipher_username_Maybe : Sub_LoadCipher_cipherType_LoginCipher_username_Maybe -> Value
415−jsonEncCipher_LoginCipher_username_Maybe val = (maybeEncode (Json.Encode.string)) val
470+jsonEncSub_LoadCipher_cipherType_LoginCipher_username_Maybe val = (maybeEncode (Json.Encode.string)) val
416
471
417
472
418
473
419−type alias Cipher_LoginCipher =
474+type alias Sub_LoadCipher_cipherType_LoginCipher =
420− { password: Cipher_LoginCipher_password_Maybe
475+ { password: Sub_LoadCipher_cipherType_LoginCipher_password_Maybe
421− , totp: Cipher_LoginCipher_totp_Maybe
476+ , uris: Sub_LoadCipher_cipherType_LoginCipher_uris_List
422− , uris: Cipher_LoginCipher_uris_List
477+ , username: Sub_LoadCipher_cipherType_LoginCipher_username_Maybe
423− , username: Cipher_LoginCipher_username_Maybe
424 }
478 }
425
479
426−jsonDecCipher_LoginCipher : Json.Decode.Decoder ( Cipher_LoginCipher )
480+jsonDecSub_LoadCipher_cipherType_LoginCipher : Json.Decode.Decoder ( Sub_LoadCipher_cipherType_LoginCipher )
427−jsonDecCipher_LoginCipher =
481+jsonDecSub_LoadCipher_cipherType_LoginCipher =
428− Json.Decode.succeed (\ppassword ptotp puris pusername -> {password = ppassword, totp = ptotp, uris = puris, username = pusername})
482+ Json.Decode.succeed (\ppassword puris pusername -> {password = ppassword, uris = puris, username = pusername})
429− |> required "password" (jsonDecCipher_LoginCipher_password_Maybe)
483+ |> required "password" (jsonDecSub_LoadCipher_cipherType_LoginCipher_password_Maybe)
430− |> required "totp" (jsonDecCipher_LoginCipher_totp_Maybe)
484+ |> required "uris" (jsonDecSub_LoadCipher_cipherType_LoginCipher_uris_List)
431− |> required "uris" (jsonDecCipher_LoginCipher_uris_List)
485+ |> required "username" (jsonDecSub_LoadCipher_cipherType_LoginCipher_username_Maybe)
432− |> required "username" (jsonDecCipher_LoginCipher_username_Maybe)
433
486
434−jsonEncCipher_LoginCipher : Cipher_LoginCipher -> Value
487+jsonEncSub_LoadCipher_cipherType_LoginCipher : Sub_LoadCipher_cipherType_LoginCipher -> Value
435−jsonEncCipher_LoginCipher val =
488+jsonEncSub_LoadCipher_cipherType_LoginCipher val =
436 Json.Encode.object
489 Json.Encode.object
437− [ ("password", jsonEncCipher_LoginCipher_password_Maybe val.password)
490+ [ ("password", jsonEncSub_LoadCipher_cipherType_LoginCipher_password_Maybe val.password)
438− , ("totp", jsonEncCipher_LoginCipher_totp_Maybe val.totp)
491+ , ("uris", jsonEncSub_LoadCipher_cipherType_LoginCipher_uris_List val.uris)
439− , ("uris", jsonEncCipher_LoginCipher_uris_List val.uris)
492+ , ("username", jsonEncSub_LoadCipher_cipherType_LoginCipher_username_Maybe val.username)
440− , ("username", jsonEncCipher_LoginCipher_username_Maybe val.username)
441 ]
493 ]
442
494
443
495
444
496
445−type Cipher =
497+type Sub_LoadCipher_cipherType =
446− CardCipher Cipher_CardCipher
498+ CardCipher Sub_LoadCipher_cipherType_CardCipher
447− | IdentityCipher Cipher_IdentityCipher
499+ | IdentityCipher Sub_LoadCipher_cipherType_IdentityCipher
448− | LoginCipher Cipher_LoginCipher
500+ | LoginCipher Sub_LoadCipher_cipherType_LoginCipher
449 | NoteCipher String
501 | NoteCipher String
450
502
451−jsonDecCipher : Json.Decode.Decoder ( Cipher )
503+jsonDecSub_LoadCipher_cipherType : Json.Decode.Decoder ( Sub_LoadCipher_cipherType )
452−jsonDecCipher =
504+jsonDecSub_LoadCipher_cipherType =
453− let jsonDecDictCipher = Dict.fromList
505+ let jsonDecDictSub_LoadCipher_cipherType = Dict.fromList
454− [ ("CardCipher", Json.Decode.lazy (\_ -> Json.Decode.map CardCipher (jsonDecCipher_CardCipher)))
506+ [ ("CardCipher", Json.Decode.lazy (\_ -> Json.Decode.map CardCipher (jsonDecSub_LoadCipher_cipherType_CardCipher)))
455− , ("IdentityCipher", Json.Decode.lazy (\_ -> Json.Decode.map IdentityCipher (jsonDecCipher_IdentityCipher)))
507+ , ("IdentityCipher", Json.Decode.lazy (\_ -> Json.Decode.map IdentityCipher (jsonDecSub_LoadCipher_cipherType_IdentityCipher)))
456− , ("LoginCipher", Json.Decode.lazy (\_ -> Json.Decode.map LoginCipher (jsonDecCipher_LoginCipher)))
508+ , ("LoginCipher", Json.Decode.lazy (\_ -> Json.Decode.map LoginCipher (jsonDecSub_LoadCipher_cipherType_LoginCipher)))
457 , ("NoteCipher", Json.Decode.lazy (\_ -> Json.Decode.map NoteCipher (Json.Decode.string)))
509 , ("NoteCipher", Json.Decode.lazy (\_ -> Json.Decode.map NoteCipher (Json.Decode.string)))
458 ]
510 ]
459− jsonDecObjectSetCipher = Set.fromList []
511+ jsonDecObjectSetSub_LoadCipher_cipherType = Set.fromList []
460− in decodeSumTaggedObject "Cipher" "tag" "contents" jsonDecDictCipher jsonDecObjectSetCipher
512+ in decodeSumTaggedObject "Sub_LoadCipher_cipherType" "tag" "contents" jsonDecDictSub_LoadCipher_cipherType jsonDecObjectSetSub_LoadCipher_cipherType
461
513
462−jsonEncCipher : Cipher -> Value
514+jsonEncSub_LoadCipher_cipherType : Sub_LoadCipher_cipherType -> Value
463−jsonEncCipher val =
515+jsonEncSub_LoadCipher_cipherType val =
464 let keyval v = case v of
516 let keyval v = case v of
465− CardCipher v1 -> ("CardCipher", encodeValue (jsonEncCipher_CardCipher v1))
517+ CardCipher v1 -> ("CardCipher", encodeValue (jsonEncSub_LoadCipher_cipherType_CardCipher v1))
466− IdentityCipher v1 -> ("IdentityCipher", encodeValue (jsonEncCipher_IdentityCipher v1))
518+ IdentityCipher v1 -> ("IdentityCipher", encodeValue (jsonEncSub_LoadCipher_cipherType_IdentityCipher v1))
467− LoginCipher v1 -> ("LoginCipher", encodeValue (jsonEncCipher_LoginCipher v1))
519+ LoginCipher v1 -> ("LoginCipher", encodeValue (jsonEncSub_LoadCipher_cipherType_LoginCipher v1))
468 NoteCipher v1 -> ("NoteCipher", encodeValue (Json.Encode.string v1))
520 NoteCipher v1 -> ("NoteCipher", encodeValue (Json.Encode.string v1))
469 in encodeSumTaggedObject "tag" "contents" keyval val
521 in encodeSumTaggedObject "tag" "contents" keyval val
470
522
471
523
472
524
473−type CipherType =
525+type alias Sub_LoadCipher =
474− CardType
526+ { cipherType: Sub_LoadCipher_cipherType
475− | IdentityType
476− | LoginType
477− | NoteType
478−
479−jsonDecCipherType : Json.Decode.Decoder ( CipherType )
480−jsonDecCipherType =
481− let jsonDecDictCipherType = Dict.fromList [("CardType", CardType), ("IdentityType", IdentityType), ("LoginType", LoginType), ("NoteType", NoteType)]
482− in decodeSumUnaries "CipherType" jsonDecDictCipherType
483−
484−jsonEncCipherType : CipherType -> Value
485−jsonEncCipherType val =
486− case val of
487− CardType -> Json.Encode.string "CardType"
488− IdentityType -> Json.Encode.string "IdentityType"
489− LoginType -> Json.Encode.string "LoginType"
490− NoteType -> Json.Encode.string "NoteType"
491−
492−
493−
494−type alias Cmd_ChooseSecondFactor =
495− { email: String
496− , factor: TwoFactorProviderType
497− , password: String
498− , requestFromServer: Bool
499− , server: String
500− }
501−
502−jsonDecCmd_ChooseSecondFactor : Json.Decode.Decoder ( Cmd_ChooseSecondFactor )
503−jsonDecCmd_ChooseSecondFactor =
504− Json.Decode.succeed (\pemail pfactor ppassword prequestFromServer pserver -> {email = pemail, factor = pfactor, password = ppassword, requestFromServer = prequestFromServer, server = pserver})
505− |> required "email" (Json.Decode.string)
506− |> required "factor" (jsonDecTwoFactorProviderType)
507− |> required "password" (Json.Decode.string)
508− |> required "requestFromServer" (Json.Decode.bool)
509− |> required "server" (Json.Decode.string)
510−
511−jsonEncCmd_ChooseSecondFactor : Cmd_ChooseSecondFactor -> Value
512−jsonEncCmd_ChooseSecondFactor val =
513− Json.Encode.object
514− [ ("email", Json.Encode.string val.email)
515− , ("factor", jsonEncTwoFactorProviderType val.factor)
516− , ("password", Json.Encode.string val.password)
517− , ("requestFromServer", Json.Encode.bool val.requestFromServer)
518− , ("server", Json.Encode.string val.server)
519− ]
520−
521−
522−
523−type alias Cmd_Login_secondFactor =
524− { provider: TwoFactorProviderType
525− , remember: Bool
526− , token: String
527− }
528−
529−jsonDecCmd_Login_secondFactor : Json.Decode.Decoder ( Cmd_Login_secondFactor )
530−jsonDecCmd_Login_secondFactor =
531− Json.Decode.succeed (\pprovider premember ptoken -> {provider = pprovider, remember = premember, token = ptoken})
532− |> required "provider" (jsonDecTwoFactorProviderType)
533− |> required "remember" (Json.Decode.bool)
534− |> required "token" (Json.Decode.string)
535−
536−jsonEncCmd_Login_secondFactor : Cmd_Login_secondFactor -> Value
537−jsonEncCmd_Login_secondFactor val =
538− Json.Encode.object
539− [ ("provider", jsonEncTwoFactorProviderType val.provider)
540− , ("remember", Json.Encode.bool val.remember)
541− , ("token", Json.Encode.string val.token)
542− ]
543−
544−
545−
546−type alias Cmd_Login_secondFactor_Maybe = (Maybe Cmd_Login_secondFactor)
547−
548−jsonDecCmd_Login_secondFactor_Maybe : Json.Decode.Decoder ( Cmd_Login_secondFactor_Maybe )
549−jsonDecCmd_Login_secondFactor_Maybe =
550− Json.Decode.maybe (jsonDecCmd_Login_secondFactor)
551−
552−jsonEncCmd_Login_secondFactor_Maybe : Cmd_Login_secondFactor_Maybe -> Value
553−jsonEncCmd_Login_secondFactor_Maybe val = (maybeEncode (jsonEncCmd_Login_secondFactor)) val
554−
555−
556−
557−type alias Cmd_Login =
558− { email: String
559− , password: String
560− , secondFactor: Cmd_Login_secondFactor_Maybe
561− , server: String
562− }
563−
564−jsonDecCmd_Login : Json.Decode.Decoder ( Cmd_Login )
565−jsonDecCmd_Login =
566− Json.Decode.succeed (\pemail ppassword psecondFactor pserver -> {email = pemail, password = ppassword, secondFactor = psecondFactor, server = pserver})
567− |> required "email" (Json.Decode.string)
568− |> required "password" (Json.Decode.string)
569− |> required "secondFactor" (jsonDecCmd_Login_secondFactor_Maybe)
570− |> required "server" (Json.Decode.string)
571−
572−jsonEncCmd_Login : Cmd_Login -> Value
573−jsonEncCmd_Login val =
574− Json.Encode.object
575− [ ("email", Json.Encode.string val.email)
576− , ("password", Json.Encode.string val.password)
577− , ("secondFactor", jsonEncCmd_Login_secondFactor_Maybe val.secondFactor)
578− , ("server", Json.Encode.string val.server)
579− ]
580−
581−
582−
583−type Cmd =
584− ChooseSecondFactor Cmd_ChooseSecondFactor
585− | Copy String
586− | CreateCipher FullCipher
587− | DeleteCipher FullCipher
588− | GeneratePassword PasswordGeneratorConfig
589− | Init
590− | Login Cmd_Login
591− | NeedCiphersList
592− | NeedEmail
593− | NeedsReset
594− | Open String
595− | RequestCipher String
596− | RequestTotp String
597− | SendMasterPassword String
598− | UpdateCipher FullCipher
599−
600−jsonDecCmd : Json.Decode.Decoder ( Cmd )
601−jsonDecCmd =
602− let jsonDecDictCmd = Dict.fromList
603− [ ("ChooseSecondFactor", Json.Decode.lazy (\_ -> Json.Decode.map ChooseSecondFactor (jsonDecCmd_ChooseSecondFactor)))
604− , ("Copy", Json.Decode.lazy (\_ -> Json.Decode.map Copy (Json.Decode.string)))
605− , ("CreateCipher", Json.Decode.lazy (\_ -> Json.Decode.map CreateCipher (jsonDecFullCipher)))
606− , ("DeleteCipher", Json.Decode.lazy (\_ -> Json.Decode.map DeleteCipher (jsonDecFullCipher)))
607− , ("GeneratePassword", Json.Decode.lazy (\_ -> Json.Decode.map GeneratePassword (jsonDecPasswordGeneratorConfig)))
608− , ("Init", Json.Decode.lazy (\_ -> Json.Decode.succeed Init))
609− , ("Login", Json.Decode.lazy (\_ -> Json.Decode.map Login (jsonDecCmd_Login)))
610− , ("NeedCiphersList", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedCiphersList))
611− , ("NeedEmail", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedEmail))
612− , ("NeedsReset", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedsReset))
613− , ("Open", Json.Decode.lazy (\_ -> Json.Decode.map Open (Json.Decode.string)))
614− , ("RequestCipher", Json.Decode.lazy (\_ -> Json.Decode.map RequestCipher (Json.Decode.string)))
615− , ("RequestTotp", Json.Decode.lazy (\_ -> Json.Decode.map RequestTotp (Json.Decode.string)))
616− , ("SendMasterPassword", Json.Decode.lazy (\_ -> Json.Decode.map SendMasterPassword (Json.Decode.string)))
617− , ("UpdateCipher", Json.Decode.lazy (\_ -> Json.Decode.map UpdateCipher (jsonDecFullCipher)))
618− ]
619− jsonDecObjectSetCmd = Set.fromList []
620− in decodeSumTaggedObject "Cmd" "tag" "contents" jsonDecDictCmd jsonDecObjectSetCmd
621−
622−jsonEncCmd : Cmd -> Value
623−jsonEncCmd val =
624− let keyval v = case v of
625− ChooseSecondFactor v1 -> ("ChooseSecondFactor", encodeValue (jsonEncCmd_ChooseSecondFactor v1))
626− Copy v1 -> ("Copy", encodeValue (Json.Encode.string v1))
627− CreateCipher v1 -> ("CreateCipher", encodeValue (jsonEncFullCipher v1))
628− DeleteCipher v1 -> ("DeleteCipher", encodeValue (jsonEncFullCipher v1))
629− GeneratePassword v1 -> ("GeneratePassword", encodeValue (jsonEncPasswordGeneratorConfig v1))
630− Init -> ("Init", encodeValue (Json.Encode.list identity []))
631− Login v1 -> ("Login", encodeValue (jsonEncCmd_Login v1))
632− NeedCiphersList -> ("NeedCiphersList", encodeValue (Json.Encode.list identity []))
633− NeedEmail -> ("NeedEmail", encodeValue (Json.Encode.list identity []))
634− NeedsReset -> ("NeedsReset", encodeValue (Json.Encode.list identity []))
635− Open v1 -> ("Open", encodeValue (Json.Encode.string v1))
636− RequestCipher v1 -> ("RequestCipher", encodeValue (Json.Encode.string v1))
637− RequestTotp v1 -> ("RequestTotp", encodeValue (Json.Encode.string v1))
638− SendMasterPassword v1 -> ("SendMasterPassword", encodeValue (Json.Encode.string v1))
639− UpdateCipher v1 -> ("UpdateCipher", encodeValue (jsonEncFullCipher v1))
640− in encodeSumTaggedObject "tag" "contents" keyval val
641−
642−
643−
644−type alias FullCipher_collectionIds_List = (List String)
645−
646−jsonDecFullCipher_collectionIds_List : Json.Decode.Decoder ( FullCipher_collectionIds_List )
647−jsonDecFullCipher_collectionIds_List =
648− Json.Decode.list (Json.Decode.string)
649−
650−jsonEncFullCipher_collectionIds_List : FullCipher_collectionIds_List -> Value
651−jsonEncFullCipher_collectionIds_List val = (Json.Encode.list Json.Encode.string) val
652−
653−
654−
655−type alias FullCipher =
656− { cipher: Cipher
657− , collectionIds: FullCipher_collectionIds_List
658− , favorite: Bool
659 , id: String
527 , id: String
660 , name: String
528 , name: String
661− , reprompt: Int
662 }
529 }
663
530
664−jsonDecFullCipher : Json.Decode.Decoder ( FullCipher )
531+jsonDecSub_LoadCipher : Json.Decode.Decoder ( Sub_LoadCipher )
665−jsonDecFullCipher =
532+jsonDecSub_LoadCipher =
666− Json.Decode.succeed (\pcipher pcollectionIds pfavorite pid pname preprompt -> {cipher = pcipher, collectionIds = pcollectionIds, favorite = pfavorite, id = pid, name = pname, reprompt = preprompt})
533+ Json.Decode.succeed (\pcipherType pid pname -> {cipherType = pcipherType, id = pid, name = pname})
667− |> required "cipher" (jsonDecCipher)
534+ |> required "cipherType" (jsonDecSub_LoadCipher_cipherType)
668− |> required "collectionIds" (jsonDecFullCipher_collectionIds_List)
669− |> required "favorite" (Json.Decode.bool)
670 |> required "id" (Json.Decode.string)
535 |> required "id" (Json.Decode.string)
671 |> required "name" (Json.Decode.string)
536 |> required "name" (Json.Decode.string)
672− |> required "reprompt" (Json.Decode.int)
673
537
674−jsonEncFullCipher : FullCipher -> Value
538+jsonEncSub_LoadCipher : Sub_LoadCipher -> Value
675−jsonEncFullCipher val =
539+jsonEncSub_LoadCipher val =
676 Json.Encode.object
540 Json.Encode.object
677− [ ("cipher", jsonEncCipher val.cipher)
541+ [ ("cipherType", jsonEncSub_LoadCipher_cipherType val.cipherType)
678− , ("collectionIds", jsonEncFullCipher_collectionIds_List val.collectionIds)
679− , ("favorite", Json.Encode.bool val.favorite)
680 , ("id", Json.Encode.string val.id)
542 , ("id", Json.Encode.string val.id)
681 , ("name", Json.Encode.string val.name)
543 , ("name", Json.Encode.string val.name)
682− , ("reprompt", Json.Encode.int val.reprompt)
683 ]
544 ]
684
545
685
546
686
547
687−type alias PasswordGeneratorConfig =
548+type Sub_LoadCiphers_cipherType =
688− { ambiguous: Bool
549+ CardType
689− , capitalize: Bool
550+ | IdentityType
690− , includeNumber: Bool
551+ | LoginType
691− , length: Int
552+ | NoteType
692− , lowercase: Bool
693− , minLowercase: Int
694− , minNumber: Int
695− , minSpecial: Int
696− , minUppercase: Int
697− , numWords: Int
698− , number: Bool
699− , special: Bool
700− , type_: String
701− , uppercase: Bool
702− , wordSeparator: String
703− }
704
553
705−jsonDecPasswordGeneratorConfig : Json.Decode.Decoder ( PasswordGeneratorConfig )
554+jsonDecSub_LoadCiphers_cipherType : Json.Decode.Decoder ( Sub_LoadCiphers_cipherType )
706−jsonDecPasswordGeneratorConfig =
555+jsonDecSub_LoadCiphers_cipherType =
707− Json.Decode.succeed (\pambiguous pcapitalize pincludeNumber plength plowercase pminLowercase pminNumber pminSpecial pminUppercase pnumWords pnumber pspecial ptype puppercase pwordSeparator -> {ambiguous = pambiguous, capitalize = pcapitalize, includeNumber = pincludeNumber, length = plength, lowercase = plowercase, minLowercase = pminLowercase, minNumber = pminNumber, minSpecial = pminSpecial, minUppercase = pminUppercase, numWords = pnumWords, number = pnumber, special = pspecial, type_ = ptype, uppercase = puppercase, wordSeparator = pwordSeparator})
556+ let jsonDecDictSub_LoadCiphers_cipherType = Dict.fromList [("CardType", CardType), ("IdentityType", IdentityType), ("LoginType", LoginType), ("NoteType", NoteType)]
708− |> required "ambiguous" (Json.Decode.bool)
557+ in decodeSumUnaries "Sub_LoadCiphers_cipherType" jsonDecDictSub_LoadCiphers_cipherType
709− |> required "capitalize" (Json.Decode.bool)
558+
710− |> required "includeNumber" (Json.Decode.bool)
559+jsonEncSub_LoadCiphers_cipherType : Sub_LoadCiphers_cipherType -> Value
711− |> required "length" (Json.Decode.int)
560+jsonEncSub_LoadCiphers_cipherType val =
712− |> required "lowercase" (Json.Decode.bool)
561+ case val of
713− |> required "minLowercase" (Json.Decode.int)
562+ CardType -> Json.Encode.string "CardType"
714− |> required "minNumber" (Json.Decode.int)
563+ IdentityType -> Json.Encode.string "IdentityType"
715− |> required "minSpecial" (Json.Decode.int)
564+ LoginType -> Json.Encode.string "LoginType"
716− |> required "minUppercase" (Json.Decode.int)
565+ NoteType -> Json.Encode.string "NoteType"
717− |> required "numWords" (Json.Decode.int)
718− |> required "number" (Json.Decode.bool)
719− |> required "special" (Json.Decode.bool)
720− |> required "type" (Json.Decode.string)
721− |> required "uppercase" (Json.Decode.bool)
722− |> required "wordSeparator" (Json.Decode.string)
723−
724−jsonEncPasswordGeneratorConfig : PasswordGeneratorConfig -> Value
725−jsonEncPasswordGeneratorConfig val =
726− Json.Encode.object
727− [ ("ambiguous", Json.Encode.bool val.ambiguous)
728− , ("capitalize", Json.Encode.bool val.capitalize)
729− , ("includeNumber", Json.Encode.bool val.includeNumber)
730− , ("length", Json.Encode.int val.length)
731− , ("lowercase", Json.Encode.bool val.lowercase)
732− , ("minLowercase", Json.Encode.int val.minLowercase)
733− , ("minNumber", Json.Encode.int val.minNumber)
734− , ("minSpecial", Json.Encode.int val.minSpecial)
735− , ("minUppercase", Json.Encode.int val.minUppercase)
736− , ("numWords", Json.Encode.int val.numWords)
737− , ("number", Json.Encode.bool val.number)
738− , ("special", Json.Encode.bool val.special)
739− , ("type", Json.Encode.string val.type_)
740− , ("uppercase", Json.Encode.bool val.uppercase)
741− , ("wordSeparator", Json.Encode.string val.wordSeparator)
742− ]
743
566
744
567
745
568
746type alias Sub_LoadCiphers =
569type alias Sub_LoadCiphers =
747− { cipherType: CipherType
570+ { cipherType: Sub_LoadCiphers_cipherType
748 , date: String
571 , date: String
749 , id: String
572 , id: String
750 , name: String
573 , name: String
@@ -753,7 +576,7 @@ type alias Sub_LoadCiphers =
753jsonDecSub_LoadCiphers : Json.Decode.Decoder ( Sub_LoadCiphers )
576jsonDecSub_LoadCiphers : Json.Decode.Decoder ( Sub_LoadCiphers )
754jsonDecSub_LoadCiphers =
577jsonDecSub_LoadCiphers =
755 Json.Decode.succeed (\pcipherType pdate pid pname -> {cipherType = pcipherType, date = pdate, id = pid, name = pname})
578 Json.Decode.succeed (\pcipherType pdate pid pname -> {cipherType = pcipherType, date = pdate, id = pid, name = pname})
756− |> required "cipherType" (jsonDecCipherType)
579+ |> required "cipherType" (jsonDecSub_LoadCiphers_cipherType)
757 |> required "date" (Json.Decode.string)
580 |> required "date" (Json.Decode.string)
758 |> required "id" (Json.Decode.string)
581 |> required "id" (Json.Decode.string)
759 |> required "name" (Json.Decode.string)
582 |> required "name" (Json.Decode.string)
@@ -761,7 +584,7 @@ jsonDecSub_LoadCiphers =
761jsonEncSub_LoadCiphers : Sub_LoadCiphers -> Value
584jsonEncSub_LoadCiphers : Sub_LoadCiphers -> Value
762jsonEncSub_LoadCiphers val =
585jsonEncSub_LoadCiphers val =
763 Json.Encode.object
586 Json.Encode.object
764− [ ("cipherType", jsonEncCipherType val.cipherType)
587+ [ ("cipherType", jsonEncSub_LoadCiphers_cipherType val.cipherType)
765 , ("date", Json.Encode.string val.date)
588 , ("date", Json.Encode.string val.date)
766 , ("id", Json.Encode.string val.id)
589 , ("id", Json.Encode.string val.id)
767 , ("name", Json.Encode.string val.name)
590 , ("name", Json.Encode.string val.name)
@@ -800,77 +623,27 @@ jsonEncSub_NeedsMasterPassword val =
800
623
801
624
802
625
803−type alias Sub_NeedsSecondFactor_List = (List TwoFactorProviderType)
804−
805−jsonDecSub_NeedsSecondFactor_List : Json.Decode.Decoder ( Sub_NeedsSecondFactor_List )
806−jsonDecSub_NeedsSecondFactor_List =
807− Json.Decode.list (jsonDecTwoFactorProviderType)
808−
809−jsonEncSub_NeedsSecondFactor_List : Sub_NeedsSecondFactor_List -> Value
810−jsonEncSub_NeedsSecondFactor_List val = (Json.Encode.list jsonEncTwoFactorProviderType) val
811−
812−
813−
814−type alias Sub_Totp =
815− { code: String
816− , interval: Int
817− , source: String
818− }
819−
820−jsonDecSub_Totp : Json.Decode.Decoder ( Sub_Totp )
821−jsonDecSub_Totp =
822− Json.Decode.succeed (\pcode pinterval psource -> {code = pcode, interval = pinterval, source = psource})
823− |> required "code" (Json.Decode.string)
824− |> required "interval" (Json.Decode.int)
825− |> required "source" (Json.Decode.string)
826−
827−jsonEncSub_Totp : Sub_Totp -> Value
828−jsonEncSub_Totp val =
829− Json.Encode.object
830− [ ("code", Json.Encode.string val.code)
831− , ("interval", Json.Encode.int val.interval)
832− , ("source", Json.Encode.string val.source)
833− ]
834−
835−
836−
837type Sub =
626type Sub =
838− CaptchaDone
839− | CipherChanged FullCipher
840− | CipherDeleted FullCipher
841− | Error String
627+ Error String
842− | GeneratedPassword String
843− | LoadCipher FullCipher
628+ | LoadCipher Sub_LoadCipher
844 | LoadCiphers Sub_LoadCiphers_List
629 | LoadCiphers Sub_LoadCiphers_List
845 | LoginSuccessful
630 | LoginSuccessful
846− | NeedsCaptcha String
847 | NeedsLogin
631 | NeedsLogin
848 | NeedsMasterPassword Sub_NeedsMasterPassword
632 | NeedsMasterPassword Sub_NeedsMasterPassword
849− | NeedsSecondFactor Sub_NeedsSecondFactor_List
850 | RecieveEmail String
633 | RecieveEmail String
851 | Reset
634 | Reset
852− | Totp Sub_Totp
853− | WrongPassword
854
635
855jsonDecSub : Json.Decode.Decoder ( Sub )
636jsonDecSub : Json.Decode.Decoder ( Sub )
856jsonDecSub =
637jsonDecSub =
857 let jsonDecDictSub = Dict.fromList
638 let jsonDecDictSub = Dict.fromList
858− [ ("CaptchaDone", Json.Decode.lazy (\_ -> Json.Decode.succeed CaptchaDone))
859− , ("CipherChanged", Json.Decode.lazy (\_ -> Json.Decode.map CipherChanged (jsonDecFullCipher)))
860− , ("CipherDeleted", Json.Decode.lazy (\_ -> Json.Decode.map CipherDeleted (jsonDecFullCipher)))
861− , ("Error", Json.Decode.lazy (\_ -> Json.Decode.map Error (Json.Decode.string)))
639+ [ ("Error", Json.Decode.lazy (\_ -> Json.Decode.map Error (Json.Decode.string)))
862− , ("GeneratedPassword", Json.Decode.lazy (\_ -> Json.Decode.map GeneratedPassword (Json.Decode.string)))
863− , ("LoadCipher", Json.Decode.lazy (\_ -> Json.Decode.map LoadCipher (jsonDecFullCipher)))
640+ , ("LoadCipher", Json.Decode.lazy (\_ -> Json.Decode.map LoadCipher (jsonDecSub_LoadCipher)))
864 , ("LoadCiphers", Json.Decode.lazy (\_ -> Json.Decode.map LoadCiphers (jsonDecSub_LoadCiphers_List)))
641 , ("LoadCiphers", Json.Decode.lazy (\_ -> Json.Decode.map LoadCiphers (jsonDecSub_LoadCiphers_List)))
865 , ("LoginSuccessful", Json.Decode.lazy (\_ -> Json.Decode.succeed LoginSuccessful))
642 , ("LoginSuccessful", Json.Decode.lazy (\_ -> Json.Decode.succeed LoginSuccessful))
866− , ("NeedsCaptcha", Json.Decode.lazy (\_ -> Json.Decode.map NeedsCaptcha (Json.Decode.string)))
867 , ("NeedsLogin", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedsLogin))
643 , ("NeedsLogin", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedsLogin))
868 , ("NeedsMasterPassword", Json.Decode.lazy (\_ -> Json.Decode.map NeedsMasterPassword (jsonDecSub_NeedsMasterPassword)))
644 , ("NeedsMasterPassword", Json.Decode.lazy (\_ -> Json.Decode.map NeedsMasterPassword (jsonDecSub_NeedsMasterPassword)))
869− , ("NeedsSecondFactor", Json.Decode.lazy (\_ -> Json.Decode.map NeedsSecondFactor (jsonDecSub_NeedsSecondFactor_List)))
870 , ("RecieveEmail", Json.Decode.lazy (\_ -> Json.Decode.map RecieveEmail (Json.Decode.string)))
645 , ("RecieveEmail", Json.Decode.lazy (\_ -> Json.Decode.map RecieveEmail (Json.Decode.string)))
871 , ("Reset", Json.Decode.lazy (\_ -> Json.Decode.succeed Reset))
646 , ("Reset", Json.Decode.lazy (\_ -> Json.Decode.succeed Reset))
872− , ("Totp", Json.Decode.lazy (\_ -> Json.Decode.map Totp (jsonDecSub_Totp)))
873− , ("WrongPassword", Json.Decode.lazy (\_ -> Json.Decode.succeed WrongPassword))
874 ]
647 ]
875 jsonDecObjectSetSub = Set.fromList []
648 jsonDecObjectSetSub = Set.fromList []
876 in decodeSumTaggedObject "Sub" "tag" "contents" jsonDecDictSub jsonDecObjectSetSub
649 in decodeSumTaggedObject "Sub" "tag" "contents" jsonDecDictSub jsonDecObjectSetSub
@@ -878,50 +651,13 @@ jsonDecSub =
878jsonEncSub : Sub -> Value
651jsonEncSub : Sub -> Value
879jsonEncSub val =
652jsonEncSub val =
880 let keyval v = case v of
653 let keyval v = case v of
881− CaptchaDone -> ("CaptchaDone", encodeValue (Json.Encode.list identity []))
882− CipherChanged v1 -> ("CipherChanged", encodeValue (jsonEncFullCipher v1))
883− CipherDeleted v1 -> ("CipherDeleted", encodeValue (jsonEncFullCipher v1))
884 Error v1 -> ("Error", encodeValue (Json.Encode.string v1))
654 Error v1 -> ("Error", encodeValue (Json.Encode.string v1))
885− GeneratedPassword v1 -> ("GeneratedPassword", encodeValue (Json.Encode.string v1))
886− LoadCipher v1 -> ("LoadCipher", encodeValue (jsonEncFullCipher v1))
655+ LoadCipher v1 -> ("LoadCipher", encodeValue (jsonEncSub_LoadCipher v1))
887 LoadCiphers v1 -> ("LoadCiphers", encodeValue (jsonEncSub_LoadCiphers_List v1))
656 LoadCiphers v1 -> ("LoadCiphers", encodeValue (jsonEncSub_LoadCiphers_List v1))
888 LoginSuccessful -> ("LoginSuccessful", encodeValue (Json.Encode.list identity []))
657 LoginSuccessful -> ("LoginSuccessful", encodeValue (Json.Encode.list identity []))
889− NeedsCaptcha v1 -> ("NeedsCaptcha", encodeValue (Json.Encode.string v1))
890 NeedsLogin -> ("NeedsLogin", encodeValue (Json.Encode.list identity []))
658 NeedsLogin -> ("NeedsLogin", encodeValue (Json.Encode.list identity []))
891 NeedsMasterPassword v1 -> ("NeedsMasterPassword", encodeValue (jsonEncSub_NeedsMasterPassword v1))
659 NeedsMasterPassword v1 -> ("NeedsMasterPassword", encodeValue (jsonEncSub_NeedsMasterPassword v1))
892− NeedsSecondFactor v1 -> ("NeedsSecondFactor", encodeValue (jsonEncSub_NeedsSecondFactor_List v1))
893 RecieveEmail v1 -> ("RecieveEmail", encodeValue (Json.Encode.string v1))
660 RecieveEmail v1 -> ("RecieveEmail", encodeValue (Json.Encode.string v1))
894 Reset -> ("Reset", encodeValue (Json.Encode.list identity []))
661 Reset -> ("Reset", encodeValue (Json.Encode.list identity []))
895− Totp v1 -> ("Totp", encodeValue (jsonEncSub_Totp v1))
896− WrongPassword -> ("WrongPassword", encodeValue (Json.Encode.list identity []))
897 in encodeSumTaggedObject "tag" "contents" keyval val
662 in encodeSumTaggedObject "tag" "contents" keyval val
898
663
899−
900−
901−type TwoFactorProviderType =
902− Authenticator
903− | Duo
904− | Email
905− | OrganizationDuo
906− | Remember
907− | U2f
908− | WebAuthn
909− | Yubikey
910−
911−jsonDecTwoFactorProviderType : Json.Decode.Decoder ( TwoFactorProviderType )
912−jsonDecTwoFactorProviderType =
913− let jsonDecDictTwoFactorProviderType = Dict.fromList [("Authenticator", Authenticator), ("Duo", Duo), ("Email", Email), ("OrganizationDuo", OrganizationDuo), ("Remember", Remember), ("U2f", U2f), ("WebAuthn", WebAuthn), ("Yubikey", Yubikey)]
914− in decodeSumUnaries "TwoFactorProviderType" jsonDecDictTwoFactorProviderType
915−
916−jsonEncTwoFactorProviderType : TwoFactorProviderType -> Value
917−jsonEncTwoFactorProviderType val =
918− case val of
919− Authenticator -> Json.Encode.string "Authenticator"
920− Duo -> Json.Encode.string "Duo"
921− Email -> Json.Encode.string "Email"
922− OrganizationDuo -> Json.Encode.string "OrganizationDuo"
923− Remember -> Json.Encode.string "Remember"
924− U2f -> Json.Encode.string "U2f"
925− WebAuthn -> Json.Encode.string "WebAuthn"
926− Yubikey -> Json.Encode.string "Yubikey"
927−
frontend/FFI.elm+1
@@ -2,6 +2,7 @@ port module FFI exposing (getBridge, sendBridge)
2
2
3import Bridge
3import Bridge
4import Json.Decode as D
4import Json.Decode as D
5+import Json.Encode as E
5
6
6
7
7port bridgeSub : (D.Value -> msg) -> Sub msg
8port bridgeSub : (D.Value -> msg) -> Sub msg
frontend/GlobalEvents.elmdeleted−9
@@ -1,9 +0,0 @@
1−module GlobalEvents exposing (..)
2−
3−import Bridge
4−
5−
6−type Event
7− = UpdateCipher Bridge.FullCipher
8− | GeneratedPassword String
9− | DecodedTotp Bridge.Sub_Totp
frontend/Logic/Cipher.elmdeleted−78
@@ -1,78 +0,0 @@
1−module Logic.Cipher exposing (normalizeCipher)
2−
3−import Bridge
4−
5−
6−normalizeCipher : Bridge.Cipher -> Bridge.Cipher
7−normalizeCipher x =
8− case x of
9− Bridge.CardCipher c ->
10− Bridge.CardCipher (normalizeCardCipher c)
11−
12− Bridge.IdentityCipher c ->
13− Bridge.IdentityCipher (normalizeIdentityCipher c)
14−
15− Bridge.LoginCipher c ->
16− Bridge.LoginCipher (normalizeLoginCipher c)
17−
18− Bridge.NoteCipher c ->
19− Bridge.NoteCipher c
20−
21−
22−normalizeCardCipher : Bridge.Cipher_CardCipher -> Bridge.Cipher_CardCipher
23−normalizeCardCipher { brand, cardholderName, code, expMonth, expYear, number } =
24− { brand = normalizeStringMaybe brand
25− , cardholderName = normalizeStringMaybe cardholderName
26− , code = normalizeStringMaybe code
27− , expMonth = normalizeStringMaybe expMonth
28− , expYear = normalizeStringMaybe expYear
29− , number = normalizeStringMaybe number
30− }
31−
32−
33−normalizeIdentityCipher : Bridge.Cipher_IdentityCipher -> Bridge.Cipher_IdentityCipher
34−normalizeIdentityCipher { address1, address2, address3, city, company, country, email, firstName, lastName, licenseNumber, middleName, passportNumber, phone, postalCode, ssn, state, title, username } =
35− { address1 = normalizeStringMaybe address1
36− , address2 = normalizeStringMaybe address2
37− , address3 = normalizeStringMaybe address3
38− , city = normalizeStringMaybe city
39− , company = normalizeStringMaybe company
40− , country = normalizeStringMaybe country
41− , email = normalizeStringMaybe email
42− , firstName = normalizeStringMaybe firstName
43− , lastName = normalizeStringMaybe lastName
44− , licenseNumber = normalizeStringMaybe licenseNumber
45− , middleName = normalizeStringMaybe middleName
46− , passportNumber = normalizeStringMaybe passportNumber
47− , phone = normalizeStringMaybe phone
48− , postalCode = normalizeStringMaybe postalCode
49− , ssn = normalizeStringMaybe ssn
50− , state = normalizeStringMaybe state
51− , title = normalizeStringMaybe title
52− , username = normalizeStringMaybe username
53− }
54−
55−
56−normalizeLoginCipher : Bridge.Cipher_LoginCipher -> Bridge.Cipher_LoginCipher
57−normalizeLoginCipher { password, totp, uris, username } =
58− { password = password
59− , uris = uris |> List.map String.trim |> List.filter String.isEmpty
60− , totp = normalizeStringMaybe totp
61− , username = username
62− }
63−
64−
65−normalizeStringMaybe : Maybe String -> Maybe String
66−normalizeStringMaybe =
67− Maybe.andThen
68− (\x ->
69− let
70− y =
71− String.trim x
72− in
73− if String.isEmpty y then
74− Nothing
75−
76− else
77− Just y
78− )
frontend/Logic/SecondFactor.elmdeleted−31
@@ -1,31 +0,0 @@
1−module Logic.SecondFactor exposing (secondFactorName)
2−
3−import Bridge
4−
5−
6−secondFactorName : Bridge.TwoFactorProviderType -> String
7−secondFactorName factor =
8− case factor of
9− Bridge.Authenticator ->
10− "Authenticator"
11−
12− Bridge.Duo ->
13− "Duo"
14−
15− Bridge.Email ->
16− "Email"
17−
18− Bridge.OrganizationDuo ->
19− "Organization Duo"
20−
21− Bridge.Remember ->
22− "Remember (IDK what this is)"
23−
24− Bridge.U2f ->
25− "U2f"
26−
27− Bridge.WebAuthn ->
28− "WebAuthn"
29−
30− Bridge.Yubikey ->
31− "Yubikey"
frontend/Main.elm+160−578
@@ -1,228 +1,129 @@
1−module Main exposing (main)
1+module Main exposing (..)
2
2
3import Bridge
3import Bridge
4import Browser
4import Browser
5import FFI exposing (getBridge, sendBridge)
5import FFI exposing (getBridge, sendBridge)
6−import GlobalEvents exposing (Event)
7import Html exposing (..)
6import Html exposing (..)
8import Html.Lazy as Lazy
7import Html.Lazy as Lazy
9import List.Nonempty as Nonempty exposing (Nonempty(..))
8import List.Nonempty as Nonempty exposing (Nonempty(..))
10import Notification
9import Notification
11−import Pages.Captcha as Captcha
12import Pages.Cipher as Cipher
10import Pages.Cipher as Cipher
13import Pages.Ciphers as Ciphers
11import Pages.Ciphers as Ciphers
14−import Pages.EditCipher as EditCipher exposing (Msg(..))
15import Pages.Loader exposing (loader)
12import Pages.Loader exposing (loader)
16import Pages.Login as Login
13import Pages.Login as Login
17import Pages.MasterPassword as MasterPassword
14import Pages.MasterPassword as MasterPassword
18import Pages.Navigation as Navigation exposing (TopButton(..))
15import Pages.Navigation as Navigation exposing (TopButton(..))
19−import Pages.SecondFactor as SecondFactor
20−import Pages.SecondFactorSelect as SecondFactorSelect
21−import Task
22−import Time
23−import Types exposing (CipherId)
24import Utils exposing (..)
16import Utils exposing (..)
25
17
26
18
27−notificationLingerSeconds : Int
28−notificationLingerSeconds =
29− 15
30−
31−
32type Msg
19type Msg
20+ = RecieveMessage String
33− = ShowLoginPage
21+ | ShowLoginPage
34− | ShowError String String
22+ | ShowError String
35− | ShowInfo String String
36 | CloseNotification
23 | CloseNotification
37− | SubmitLogin Bridge.Cmd_Login
24+ | SubmitLogin { email : String, password : String, server : String }
25+ | LoginMsg Login.Msg
26+ | CiphersMsg Ciphers.Msg
38 | LoadCiphers Bridge.Sub_LoadCiphers_List
27 | LoadCiphers Bridge.Sub_LoadCiphers_List
39− | LoginSuccessful
28+ | OpenCiphersScreen
40 | Reset
29 | Reset
41 | NeedsReset
30 | NeedsReset
31+ | MasterPasswordMsg MasterPassword.Msg
42 | SendMasterPassword { password : String }
32 | SendMasterPassword { password : String }
43 | ShowMasterPasswordPage { server : String, login : String }
33 | ShowMasterPasswordPage { server : String, login : String }
34+ | CipherMsg Cipher.Msg
44− | ShowCipherPage Bridge.FullCipher
35+ | ShowCipherPage Bridge.Sub_LoadCipher
45 | RequestCipher CipherId
36 | RequestCipher CipherId
46 | PopView
37 | PopView
47 | RecieveEmail String
38 | RecieveEmail String
48 | Copy String
39 | Copy String
49 | Open String
40 | Open String
50− | ShowCaptcha Captcha.HCaptchSiteKey
51− | ClearNotification { currentTime : Time.Posix }
52− | UpdateLastNotificatioTime Time.Posix
53− | EditCipher Bridge.FullCipher
54− | UpdateCipher Bridge.FullCipher
55− | CreateCipher Bridge.FullCipher
56− | FireGlobalEvent Event
57− | GeneratePassword Bridge.PasswordGeneratorConfig
58− | OpenNewCipherEditPage Bridge.CipherType
59− | WrongPassword
60− | DeleteCipher Bridge.FullCipher
61− | RequestTotp String
62− | ShowSecondFactorSelect (List Bridge.TwoFactorProviderType)
63− | SelectSecondFactor
64− { provider : Bridge.TwoFactorProviderType
65− , requestFromServer : Bool
66− }
67− | PageMsg PageMsg
68
41
69
42
70−type PageMsg
43+type alias CipherId =
71− = LoginMsg Login.Msg
44+ String
72− | CiphersMsg Ciphers.Msg
73− | MasterPasswordMsg MasterPassword.Msg
74− | CipherMsg Cipher.Msg
75− | EditCipherMsg EditCipher.Msg
76− | SecondFactorSelectMsg SecondFactorSelect.Msg
77− | SecondFactorMsg SecondFactor.Msg
78
45
79
46
80type alias Model =
47type alias Model =
81 { notifications : List Notification.Config
48 { notifications : List Notification.Config
82 , pageStack : Navigation.PageStack PageModel
49 , pageStack : Navigation.PageStack PageModel
83 , userEmail : Maybe String
50 , userEmail : Maybe String
84− , lastNotificationTime : Time.Posix
85 }
51 }
86
52
87
53
88−findLoginDetails :
89− List PageModel
90− ->
91− Maybe
92− { server : String
93− , email : String
94− , password : String
95− }
96−findLoginDetails xs =
97− case xs of
98− (LoginModel { server, email, password }) :: _ ->
99− Just
100− { server = server
101− , email = email
102− , password = password
103− }
104−
105− _ :: rest ->
106− findLoginDetails rest
107−
108− [] ->
109− Nothing
110−
111−
112−appendNotification : Notification.Config -> Model -> ( Model, Cmd Msg )
54+appendNotification : Notification.Config -> Model -> Model
113appendNotification cfg model =
55appendNotification cfg model =
114− ( { model | notifications = cfg :: model.notifications }, Task.perform UpdateLastNotificatioTime Time.now )
56+ { model | notifications = cfg :: model.notifications }
115
57
116
58
117type PageModel
59type PageModel
118− = LoginModel (Login.Model Msg)
60+ = LoginModel Login.Model
119 | LoadingPage
61 | LoadingPage
120− | CiphersModel (Ciphers.Model Msg)
62+ | CiphersModel Ciphers.Model
121− | EditCipherModel (EditCipher.Model Msg)
122− | MasterPasswordModel (MasterPassword.Model Msg)
63+ | MasterPasswordModel MasterPassword.Model
123− | CipherModel (Cipher.Model Msg)
64+ | CipherModel Cipher.Model
124− | CaptchaModel Captcha.Model
125− | SecondFactorSelectModel (SecondFactorSelect.Model Msg)
126− | SecondFactorModel (SecondFactor.Model Msg)
127
65
128
66
129showPage :
67showPage :
130 String
68 String
131 -> PageModel
69 -> PageModel
132 ->
70 ->
133− { title : List (Html Msg)
71+ { title : String
134 , body : List (Html Msg)
72 , body : List (Html Msg)
135 , topButton : Maybe (Navigation.TopButton Msg)
73 , topButton : Maybe (Navigation.TopButton Msg)
136 }
74 }
137showPage email page =
75showPage email page =
138− let
139− simpleBackButton =
140− BackButton { action = PopView, icon = Nothing }
141−
142− liftPageWith :
143− (pageMsg -> PageMsg)
144− ->
145− { title : List (Html pageMsg)
146− , body : List (Html pageMsg)
147− , topButton : Maybe (Navigation.TopButton Msg)
148− }
149− ->
150− { title : List (Html Msg)
151− , body : List (Html Msg)
152− , topButton : Maybe (Navigation.TopButton Msg)
153− }
154− liftPageWith lift { title, body, topButton } =
155− { title = title |> List.map (Html.map (lift >> PageMsg))
156− , body = body |> List.map (Html.map (lift >> PageMsg))
157− , topButton = topButton
158− }
159− in
160 case page of
76 case page of
161 LoginModel model ->
77 LoginModel model ->
162− liftPageWith LoginMsg
78+ let
79+ p =
80+ Login.page loginCallbacks LoginMsg
81+ in
163− { title = [ text Login.title ]
82+ { title = p.title model
164− , body = Login.view model
83+ , body = p.view model
165− , topButton = Nothing
84+ , topButton = Nothing
166− }
85+ }
167
86
168 CiphersModel model ->
87 CiphersModel model ->
169− liftPageWith CiphersMsg
88+ let
89+ p =
90+ Ciphers.page ciphersCallbacks CiphersMsg
91+ in
170− { title = Ciphers.title model
92+ { title = p.title model
171− , body = Ciphers.view model
93+ , body = p.view model
172− , topButton =
94+ , topButton =
173− Ciphers.menuConfig email model
95+ Ciphers.menuConfig email model
174− |> Navigation.mapMenuConfig (CiphersMsg >> PageMsg)
96+ |> Navigation.mapMenuConfig CiphersMsg
175− |> Navigation.MenuButton
97+ |> Navigation.MenuButton
176− |> Just
98+ |> Just
177− }
99+ }
178
100
179 LoadingPage ->
101 LoadingPage ->
180− { title = []
102+ { title = ""
181 , body = [ loader ]
103 , body = [ loader ]
182− , topButton = Just simpleBackButton
104+ , topButton = Just (BackButton PopView)
183 }
105 }
184
106
185 MasterPasswordModel model ->
107 MasterPasswordModel model ->
186− liftPageWith MasterPasswordMsg
108+ let
109+ p =
110+ MasterPassword.page masterPasswordCallbacks MasterPasswordMsg
111+ in
187− { title = [ text MasterPassword.title ]
112+ { title = p.title model
188− , body = MasterPassword.view model
113+ , body = p.view model
189− , topButton = Nothing
114+ , topButton = Nothing
190− }
115+ }
191
116
192 CipherModel model ->
117 CipherModel model ->
193− liftPageWith CipherMsg
118+ let
194− { title = Cipher.title model
119+ p =
195− , body = Cipher.view model
120+ Cipher.page cipherCallbacks CipherMsg
196− , topButton = Just simpleBackButton
121+ in
197− }
198−
199− CaptchaModel model ->
200− { title = [ text Captcha.title ]
122+ { title = p.title model
201− , body = Captcha.view model
123+ , body = p.view model
202− , topButton = Just simpleBackButton
124+ , topButton = Just (BackButton PopView)
203 }
125 }
204
126
205− EditCipherModel model ->
206− liftPageWith EditCipherMsg
207− { title = EditCipher.title model
208− , body = EditCipher.view model
209− , topButton = Just (BackButton { action = PopView, icon = Just "close" })
210− }
211−
212− SecondFactorSelectModel model ->
213− liftPageWith SecondFactorSelectMsg
214− { title = [ text SecondFactorSelect.title ]
215− , body = SecondFactorSelect.view model
216− , topButton = Just simpleBackButton
217− }
218−
219− SecondFactorModel model ->
220− liftPageWith SecondFactorMsg
221− { title = [ SecondFactor.title model |> text ]
222− , body = [ SecondFactor.view model ]
223− , topButton = Just simpleBackButton
224− }
225−
226
127
227main : Program () Model Msg
128main : Program () Model Msg
228main =
129main =
@@ -235,102 +136,33 @@ main =
235
136
236
137
237subscriptions : Model -> Sub Msg
138subscriptions : Model -> Sub Msg
238−subscriptions model =
139+subscriptions _ =
239− Sub.batch
140+ getBridge ShowError
240− ([ getBridge (ShowError "Something went wrong!")
241− (\msg ->
141+ (\msg ->
242− case msg of
142+ case msg of
243− Bridge.NeedsLogin ->
143+ Bridge.NeedsLogin ->
244− ShowLoginPage
144+ ShowLoginPage
245−
246− Bridge.Error err ->
247− ShowError "Something went wrong!" err
248−
249− Bridge.LoadCiphers ciphers ->
250− LoadCiphers ciphers
251−
252− Bridge.LoginSuccessful ->
253− LoginSuccessful
254−
255− Bridge.Reset ->
256− Reset
257−
258− Bridge.NeedsMasterPassword { server, login } ->
259− ShowMasterPasswordPage { server = server, login = login }
260−
261− Bridge.LoadCipher cipher ->
262− ShowCipherPage cipher
263−
264− Bridge.RecieveEmail email ->
265− RecieveEmail email
266−
267− Bridge.NeedsCaptcha uri ->
268− ShowCaptcha uri
269−
270− Bridge.CaptchaDone ->
271− PopView
272
145
273− Bridge.CipherChanged c ->
146+ Bridge.Error err ->
274− ShowInfo "Entry updated" ("The entry “" ++ c.name ++ "” has been successfully updated.")
147+ ShowError err
275
148
276− Bridge.GeneratedPassword password ->
149+ Bridge.LoadCiphers ciphers ->
277− GlobalEvents.GeneratedPassword password |> FireGlobalEvent
150+ LoadCiphers ciphers
278
151
279− Bridge.WrongPassword ->
152+ Bridge.LoginSuccessful ->
280− WrongPassword
153+ OpenCiphersScreen
281
154
282− Bridge.CipherDeleted c ->
155+ Bridge.Reset ->
283− ShowInfo "Entry deleted" ("The entry “" ++ c.name ++ "” has been successfully deleted.")
156+ Reset
284
157
285− Bridge.Totp totp ->
158+ Bridge.NeedsMasterPassword { server, login } ->
286− GlobalEvents.DecodedTotp totp |> FireGlobalEvent
159+ ShowMasterPasswordPage { server = server, login = login }
287
160
288− Bridge.NeedsSecondFactor secondFactors ->
161+ Bridge.LoadCipher cipher ->
289− case secondFactors of
162+ ShowCipherPage cipher
290− [ provider ] ->
291− SelectSecondFactor
292− { provider = provider
293− , requestFromServer = False
294− }
295
163
296− _ ->
164+ Bridge.RecieveEmail email ->
297− ShowSecondFactorSelect secondFactors
165+ RecieveEmail email
298− )
299− ]
300− ++ optional (List.isEmpty model.notifications |> not) (Time.every 1000 (\t -> ClearNotification { currentTime = t }))
301− ++ (model.pageStack
302− |> Nonempty.toList
303− |> List.map
304− (\x ->
305− case x of
306− LoginModel _ ->
307− Sub.none
308−
309− LoadingPage ->
310− Sub.none
311−
312− CiphersModel _ ->
313− Sub.none
314−
315− EditCipherModel _ ->
316− Sub.none
317−
318− MasterPasswordModel _ ->
319− Sub.none
320−
321− CipherModel m ->
322− Cipher.subscriptions m
323−
324− CaptchaModel _ ->
325− Sub.none
326−
327− SecondFactorSelectModel _ ->
328− Sub.none
329−
330− SecondFactorModel _ ->
331− Sub.none
332− )
333− )
334 )
166 )
335
167
336
168
@@ -339,7 +171,6 @@ init =
339 ( { notifications = []
171 ( { notifications = []
340 , pageStack = Nonempty.singleton LoadingPage
172 , pageStack = Nonempty.singleton LoadingPage
341 , userEmail = Nothing
173 , userEmail = Nothing
342− , lastNotificationTime = Time.millisToPosix 0
343 }
174 }
344 , FFI.sendBridge Bridge.Init
175 , FFI.sendBridge Bridge.Init
345 )
176 )
@@ -349,10 +180,7 @@ view : Model -> Html Msg
349view model =
180view model =
350 div []
181 div []
351 (maybeList (List.head model.notifications) (Lazy.lazy2 Notification.notification CloseNotification)
182 (maybeList (List.head model.notifications) (Lazy.lazy2 Notification.notification CloseNotification)
352− ++ [ Lazy.lazy2 Navigation.showNavigationView
353− model.pageStack
354− (showPage (Maybe.withDefault "" model.userEmail))
183+ ++ [ Lazy.lazy2 Navigation.showNavigationView model.pageStack (showPage (Maybe.withDefault "" model.userEmail)) ]
355− ]
356 )
184 )
357
185
358
186
@@ -364,6 +192,12 @@ mapHead f (Nonempty x xx) =
364doNotStoreInHistory : PageModel -> Bool
192doNotStoreInHistory : PageModel -> Bool
365doNotStoreInHistory page =
193doNotStoreInHistory page =
366 case page of
194 case page of
195+ LoginModel _ ->
196+ True
197+
198+ MasterPasswordModel _ ->
199+ True
200+
367 LoadingPage ->
201 LoadingPage ->
368 True
202 True
369
203
@@ -374,34 +208,49 @@ doNotStoreInHistory page =
374update : Msg -> Model -> ( Model, Cmd Msg )
208update : Msg -> Model -> ( Model, Cmd Msg )
375update msg model =
209update msg model =
376 let
210 let
377− updatePageStackHead : PageModel -> Model
211+ processPage : (pageModel -> PageModel) -> ( Result String pageModel, Cmd Msg ) -> ( Model, Cmd Msg )
378− updatePageStackHead mdl =
212+ processPage liftModel ( resultModel, cmd ) =
213+ case resultModel of
214+ Ok mdl ->
379− { model | pageStack = mapHead (always mdl) model.pageStack }
215+ ( { model | pageStack = mapHead (always (liftModel mdl)) model.pageStack }, cmd )
216+
217+ Err err ->
218+ ( appendNotification
219+ { title = "An error had occured"
220+ , message = err
221+ , severity = Notification.Error
222+ }
223+ model
224+ , cmd
225+ )
380
226
381 appendPageStack : PageModel -> Model
227 appendPageStack : PageModel -> Model
382 appendPageStack mdl =
228 appendPageStack mdl =
383 { model | pageStack = model.pageStack |> Nonempty.toList |> List.filter (doNotStoreInHistory >> not) |> Nonempty mdl }
229 { model | pageStack = model.pageStack |> Nonempty.toList |> List.filter (doNotStoreInHistory >> not) |> Nonempty mdl }
384
230
385− keepStackWith : PageModel -> Model
231+ currentPage =
386− keepStackWith mdl =
387− { model | pageStack = Nonempty.cons mdl model.pageStack }
232+ model.pageStack |> Nonempty.head
388 in
233 in
389 case msg of
234 case msg of
390− ShowError title err ->
235+ RecieveMessage x ->
391− appendNotification
236+ ( appendNotification
392− { title = title
237+ { title = "Got a message!"
393− , message = err
238+ , message = x
394− , severity = Notification.Error
239+ , severity = Notification.Info
395 }
240 }
396 model
241 model
242+ , Cmd.none
243+ )
397
244
398− ShowInfo title inf ->
245+ ShowError err ->
399− appendNotification
246+ ( appendNotification
400− { title = title
247+ { title = "Something went wrong"
401− , message = inf
248+ , message = err
402− , severity = Notification.Info
249+ , severity = Notification.Error
403 }
250 }
404 model
251 model
252+ , Cmd.none
253+ )
405
254
406 CloseNotification ->
255 CloseNotification ->
407 ( { model | notifications = tailEmpty model.notifications }
256 ( { model | notifications = tailEmpty model.notifications }
@@ -409,64 +258,43 @@ update msg model =
409 )
258 )
410
259
411 SubmitLogin data ->
260 SubmitLogin data ->
412− ( keepStackWith <| LoadingPage
261+ ( model
413 , FFI.sendBridge (Bridge.Login data)
262 , FFI.sendBridge (Bridge.Login data)
414 )
263 )
415
264
265+ LoginMsg imsg ->
266+ case currentPage of
267+ LoginModel page ->
268+ (Login.page loginCallbacks LoginMsg).update imsg page |> processPage LoginModel
269+
270+ _ ->
271+ ( model, Cmd.none )
272+
273+ CiphersMsg imsg ->
274+ case currentPage of
275+ CiphersModel page ->
276+ (Ciphers.page ciphersCallbacks CiphersMsg).update imsg page |> processPage CiphersModel
277+
278+ _ ->
279+ ( model, Cmd.none )
280+
416 ShowLoginPage ->
281 ShowLoginPage ->
417− ( Login.init loginCallbacks |> LoginModel |> appendPageStack
282+ (Login.page loginCallbacks LoginMsg).init ()
418− , Cmd.none
283+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| LoginModel pageModel)
419− )
420
284
421 LoadCiphers ciphers ->
285 LoadCiphers ciphers ->
422− let
286+ (Ciphers.page ciphersCallbacks CiphersMsg).init ciphers
423− ciphersShown =
287+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| CiphersModel pageModel)
424− model.pageStack
425− |> Nonempty.toList
426− |> List.any
427− (\x ->
428− case x of
429− CiphersModel _ ->
430− True
431−
432− _ ->
433− False
434− )
435− in
436− ( if ciphersShown then
437− { model
438− | pageStack =
439− model.pageStack
440− |> Nonempty.map
441− (\x ->
442− case x of
443− CiphersModel pageModel ->
444− CiphersModel (Ciphers.updateCiphers ciphers pageModel)
445−
446− other ->
447− other
448− )
449− }
450
288
451− else
289+ OpenCiphersScreen ->
452− appendPageStack <| CiphersModel (Ciphers.init ciphersCallbacks ciphers)
453− , Cmd.none
454− )
455−
456− LoginSuccessful ->
457− ( { model | pageStack = Nonempty.singleton LoadingPage }
458− , Cmd.batch [ sendBridge Bridge.NeedCiphersList, sendBridge Bridge.NeedEmail ]
290+ ( appendPageStack <| LoadingPage, Cmd.batch [ sendBridge Bridge.NeedCiphersList, sendBridge Bridge.NeedEmail ] )
459− )
460
291
461 Reset ->
292 Reset ->
462 init
293 init
463
294
464 ShowMasterPasswordPage { server, login } ->
295 ShowMasterPasswordPage { server, login } ->
465− ( MasterPassword.init masterPasswordCallbacks { server = server, login = login }
296+ (MasterPassword.page masterPasswordCallbacks MasterPasswordMsg).init { server = server, login = login }
466− |> MasterPasswordModel
297+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| MasterPasswordModel pageModel)
467− |> appendPageStack
468− , Cmd.none
469− )
470
298
471 NeedsReset ->
299 NeedsReset ->
472 ( appendPageStack <| LoadingPage, sendBridge Bridge.NeedsReset )
300 ( appendPageStack <| LoadingPage, sendBridge Bridge.NeedsReset )
@@ -474,8 +302,24 @@ update msg model =
474 SendMasterPassword { password } ->
302 SendMasterPassword { password } ->
475 ( appendPageStack <| LoadingPage, sendBridge (Bridge.SendMasterPassword password) )
303 ( appendPageStack <| LoadingPage, sendBridge (Bridge.SendMasterPassword password) )
476
304
305+ MasterPasswordMsg imsg ->
306+ case currentPage of
307+ MasterPasswordModel page ->
308+ (MasterPassword.page masterPasswordCallbacks MasterPasswordMsg).update imsg page |> processPage MasterPasswordModel
309+
310+ _ ->
311+ ( model, Cmd.none )
312+
313+ CipherMsg imsg ->
314+ case currentPage of
315+ CipherModel page ->
316+ (Cipher.page cipherCallbacks CipherMsg).update imsg page |> processPage CipherModel
317+
318+ _ ->
319+ ( model, Cmd.none )
320+
477 ShowCipherPage cipher ->
321 ShowCipherPage cipher ->
478− Cipher.init cipherCallbacks cipher
322+ (Cipher.page cipherCallbacks CipherMsg).init cipher
479 |> Tuple.mapFirst (\pageModel -> appendPageStack <| CipherModel pageModel)
323 |> Tuple.mapFirst (\pageModel -> appendPageStack <| CipherModel pageModel)
480
324
481 RequestCipher id ->
325 RequestCipher id ->
@@ -495,274 +339,20 @@ update msg model =
495 Open uri ->
339 Open uri ->
496 ( model, FFI.sendBridge (Bridge.Open uri) )
340 ( model, FFI.sendBridge (Bridge.Open uri) )
497
341
498− ShowCaptcha uri ->
499− ( Captcha.init uri |> CaptchaModel |> appendPageStack, Cmd.none )
500−
501− ClearNotification { currentTime } ->
502− if Time.posixToMillis model.lastNotificationTime + notificationLingerSeconds * 1000 > Time.posixToMillis currentTime then
503− ( model, Cmd.none )
504−
505− else
506− ( { model | notifications = List.tail model.notifications |> Maybe.withDefault [] }
507− , Task.perform UpdateLastNotificatioTime Time.now
508− )
509−
510− UpdateLastNotificatioTime time ->
511− ( { model | lastNotificationTime = time }, Cmd.none )
512−
513− EditCipher cipher ->
514− EditCipher.init { fullCipher = cipher, callbacks = editCipherCallbacks }
515− |> Tuple.mapFirst (\pageModel -> keepStackWith <| EditCipherModel pageModel)
516−
517− UpdateCipher cipher ->
518− ( model
519− , Cmd.batch
520− [ Bridge.UpdateCipher cipher |> sendBridge
521− , cipher |> GlobalEvents.UpdateCipher |> FireGlobalEvent |> pureCmd
522− , PopView |> pureCmd
523− ]
524− )
525−
526− CreateCipher cipher ->
527− ( model
528− , Cmd.batch
529− [ Bridge.CreateCipher cipher |> sendBridge
530− , PopView |> pureCmd
531− ]
532− )
533−
534− FireGlobalEvent ev ->
535− ( { model
536− | pageStack =
537− model.pageStack
538− |> Nonempty.map
539− (\page ->
540− case page of
541− LoadingPage ->
542− LoadingPage
543−
544− LoginModel m ->
545− LoginModel m
546−
547− CiphersModel m ->
548− Ciphers.event m ev |> CiphersModel
549−
550− MasterPasswordModel m ->
551− MasterPasswordModel m
552−
553− CipherModel m ->
554− Cipher.event m ev |> CipherModel
555−
556− EditCipherModel m ->
557− EditCipher.event m ev |> EditCipherModel
558−
559− CaptchaModel m ->
560− CaptchaModel m
561−
562− SecondFactorSelectModel m ->
563− SecondFactorSelectModel m
564−
565− SecondFactorModel m ->
566− SecondFactorModel m
567− )
568− }
569− , Cmd.none
570− )
571−
572− GeneratePassword cfg ->
573− ( model, FFI.sendBridge (Bridge.GeneratePassword cfg) )
574−
575− OpenNewCipherEditPage t ->
576− EditCipher.init
577− { callbacks = createCipherCallbacks
578− , fullCipher =
579− { reprompt = 0
580− , favorite = False
581− , id = ""
582− , name = ""
583− , collectionIds = []
584− , cipher =
585− case t of
586− Bridge.LoginType ->
587− Bridge.LoginCipher
588− { uris = []
589− , username = Nothing
590− , password = Nothing
591− , totp = Nothing
592− }
593−
594− Bridge.NoteType ->
595− Bridge.NoteCipher ""
596−
597− Bridge.CardType ->
598− Bridge.CardCipher
599− { cardholderName = Nothing
600− , brand = Nothing
601− , number = Nothing
602− , expMonth = Nothing
603− , expYear = Nothing
604− , code = Nothing
605− }
606−
607− Bridge.IdentityType ->
608− Bridge.IdentityCipher
609− { title = Nothing
610− , firstName = Nothing
611− , middleName = Nothing
612− , lastName = Nothing
613− , address1 = Nothing
614− , address2 = Nothing
615− , address3 = Nothing
616− , city = Nothing
617− , state = Nothing
618− , postalCode = Nothing
619− , country = Nothing
620− , company = Nothing
621− , email = Nothing
622− , phone = Nothing
623− , ssn = Nothing
624− , username = Nothing
625− , passportNumber = Nothing
626− , licenseNumber = Nothing
627− }
628− }
629− }
630− |> Tuple.mapFirst (\pageModel -> keepStackWith <| EditCipherModel pageModel)
631−
632− WrongPassword ->
633− ( model
634− , Cmd.batch
635− [ pureCmd PopView
636− , pureCmd (ShowError "Login failed" "The login details you provided are not valid. Please try again.")
637− ]
638− )
639−
640− DeleteCipher cipher ->
641− ( model
642− , Cmd.batch
643− [ pureCmd PopView
644− , pureCmd PopView
645− , FFI.sendBridge (Bridge.DeleteCipher cipher)
646− ]
647− )
648−
649− RequestTotp totp ->
650− ( model, FFI.sendBridge (Bridge.RequestTotp totp) )
651−
652− ShowSecondFactorSelect secondFactors ->
653− ( SecondFactorSelect.init secondFactorSelectCallbacks secondFactors
654− |> SecondFactorSelectModel
655− |> appendPageStack
656− , Cmd.none
657− )
658−
659− SelectSecondFactor { provider, requestFromServer } ->
660− case Nonempty.toList model.pageStack |> findLoginDetails of
661− Just { email, password, server } ->
662− ( SecondFactor.init
663− { provider = provider
664− , callbacks =
665− { submit =
666− \{ token, remember } ->
667− SubmitLogin
668− { email = email
669− , password = password
670− , server = server
671− , secondFactor =
672− Just
673− { provider = provider
674− , token = token
675− , remember = remember
676− }
677− }
678− }
679− }
680− |> SecondFactorModel
681− |> appendPageStack
682− , Bridge.ChooseSecondFactor
683− { factor = provider
684− , email = email
685− , password = password
686− , server = server
687− , requestFromServer = requestFromServer
688− }
689− |> FFI.sendBridge
690− )
691−
692− Nothing ->
693− ( model, Cmd.none )
694−
695− PageMsg pageMsg ->
696− case ( pageMsg, model.pageStack |> Nonempty.head ) of
697− ( SecondFactorMsg imsg, SecondFactorModel m ) ->
698− SecondFactor.update m imsg
699− |> Tuple.mapBoth
700− (SecondFactorModel >> updatePageStackHead)
701− (Maybe.map pureCmd >> Maybe.withDefault Cmd.none)
702−
703− ( LoginMsg imsg, LoginModel page ) ->
704− Login.update imsg page
705− |> Tuple.mapFirst (LoginModel >> updatePageStackHead)
706−
707− ( CiphersMsg imsg, CiphersModel page ) ->
708− Ciphers.update imsg page
709− |> Tuple.mapFirst (CiphersModel >> updatePageStackHead)
710−
711− ( MasterPasswordMsg imsg, MasterPasswordModel page ) ->
712− MasterPassword.update imsg page
713− |> Tuple.mapFirst (MasterPasswordModel >> updatePageStackHead)
714−
715− ( CipherMsg imsg, CipherModel page ) ->
716− Cipher.update imsg page
717− |> Tuple.mapFirst (CipherModel >> updatePageStackHead)
718−
719− ( EditCipherMsg imsg, EditCipherModel page ) ->
720− EditCipher.update imsg page
721− |> Tuple.mapFirst (EditCipherModel >> updatePageStackHead)
722−
723− ( SecondFactorSelectMsg imsg, SecondFactorSelectModel m ) ->
724− SecondFactorSelect.update imsg m
725− |> Tuple.mapFirst (SecondFactorSelectModel >> updatePageStackHead)
726−
727− _ ->
728− ( model, Cmd.none )
729−
730
342
731loginCallbacks : Login.Callbacks Msg
343loginCallbacks : Login.Callbacks Msg
732loginCallbacks =
344loginCallbacks =
733− { submit =
734− \{ email, server, password } ->
735− SubmitLogin
345+ { submit = SubmitLogin }
736− { email = email
737− , password = password
738− , server = server
739− , secondFactor = Nothing
740− }
741− }
742
346
743
347
744ciphersCallbacks : Ciphers.Callbacks Msg
348ciphersCallbacks : Ciphers.Callbacks Msg
745ciphersCallbacks =
349ciphersCallbacks =
746− { selected = RequestCipher
350+ { selected = RequestCipher, logOut = NeedsReset }
747− , logOut = NeedsReset
748− , createNewCipher = OpenNewCipherEditPage
749− , lift = CiphersMsg >> PageMsg
750− }
751
351
752
352
753cipherCallbacks : Cipher.Callbacks Msg
353cipherCallbacks : Cipher.Callbacks Msg
754cipherCallbacks =
354cipherCallbacks =
755− { copy = Copy, open = Open, edit = EditCipher, needTotp = RequestTotp }
355+ { copy = Copy, open = Open }
756−
757−
758−editCipherCallbacks : EditCipher.Callbacks Msg
759−editCipherCallbacks =
760− { save = UpdateCipher, generatePassword = GeneratePassword, delete = Just DeleteCipher }
761−
762−
763−createCipherCallbacks : EditCipher.Callbacks Msg
764−createCipherCallbacks =
765− { save = CreateCipher, generatePassword = GeneratePassword, delete = Nothing }
766
356
767
357
768masterPasswordCallbacks : MasterPassword.Callbacks Msg
358masterPasswordCallbacks : MasterPassword.Callbacks Msg
@@ -770,11 +360,3 @@ masterPasswordCallbacks =
770 { submit = SendMasterPassword
360 { submit = SendMasterPassword
771 , reset = NeedsReset
361 , reset = NeedsReset
772 }
362 }
773−
774−
775−secondFactorSelectCallbacks : SecondFactorSelect.Callbacks Msg
776−secondFactorSelectCallbacks =
777− { selectFactor =
778− \provider ->
779− SelectSecondFactor { provider = provider, requestFromServer = True }
780− }
frontend/Modal.elmdeleted−33
@@ -1,33 +0,0 @@
1−module Modal exposing (..)
2−
3−import Html exposing (..)
4−import Html.Attributes as Attr
5−import Html.Events as Ev
6−
7−
8−type alias ModelConfig msg =
9− { title : String
10− , body : List (Html msg)
11− , close : msg
12− , footer : List (Html msg)
13− }
14−
15−
16−modal : ModelConfig msg -> Html msg
17−modal cfg =
18− div
19− [ Attr.class "p-modal" ]
20− [ section
21− [ Attr.class "p-modal__dialog"
22− ]
23− (header
24− [ Attr.class "p-modal__header"
25− ]
26− [ h2 [ Attr.class "p-modal__title" ] [ text cfg.title ]
27− , button [ Attr.class "p-modal__close", Ev.onClick cfg.close ] [ text "Close" ]
28− ]
29− :: cfg.body
30− ++ [ footer [ Attr.class "p-modal__footer" ] cfg.footer
31− ]
32− )
33− ]
frontend/Page.elm+13−23
@@ -1,32 +1,22 @@
1module Page exposing (..)
1module Page exposing (..)
2
2
3−import Browser
4import Html exposing (..)
3import Html exposing (..)
5import Html.Events exposing (..)
4import Html.Events exposing (..)
6
5
7
6
8−page :
7+type alias Env =
9− { init : model
8+ {}
10− , view : model -> List (Html msg)
9+
11− , update : msg -> model -> ( model, Cmd (Maybe msg) )
12− }
13− -> Program () model (Maybe msg)
14−page { init, view, update } =
15− Browser.element
16− { subscriptions = always Sub.none
17− , init = \_ -> ( init, Cmd.none )
18− , view = view >> Html.div [] >> Html.map Just
19− , update =
20− \mmsg model ->
21− case mmsg of
22− Nothing ->
23− ( model, Cmd.none )
24
10
25− Just msg ->
11+type alias Page init model imsg emsg =
26− update msg model
12+ (imsg -> emsg)
27− }
13+ -> InitializedPage init model imsg emsg
28
14
29
15
30−noUpdate : a -> model -> ( model, Cmd msg )
16+type alias InitializedPage init model imsg emsg =
31−noUpdate _ model =
17+ { init : init -> ( model, Cmd emsg )
32− ( model, Cmd.none )
18+ , view : model -> List (Html emsg)
19+ , update : imsg -> model -> ( Result String model, Cmd emsg )
20+ , subscriptions : model -> Sub emsg
21+ , title : model -> String
22+ }
frontend/Pages/Captcha.elmdeleted−45
@@ -1,45 +0,0 @@
1−module Pages.Captcha exposing (HCaptchSiteKey, Model, init, main, title, view)
2−
3−import Html exposing (..)
4−import Html.Attributes as Attr
5−import Page exposing (..)
6−import Utils exposing (..)
7−
8−
9−main : Program () Model (Maybe (Maybe ()))
10−main =
11− page
12− { init = init "10000000-ffff-ffff-ffff-000000000001"
13− , view = view
14− , update = noUpdate
15− }
16−
17−
18−type alias HCaptchSiteKey =
19− String
20−
21−
22−type alias Model =
23− { siteKey : HCaptchSiteKey
24− }
25−
26−
27−title : String
28−title =
29− "Captcha"
30−
31−
32−init : HCaptchSiteKey -> Model
33−init siteKey =
34− { siteKey = siteKey }
35−
36−
37−view : Model -> List (Html msg)
38−view { siteKey } =
39− [ iframe
40− [ Attr.src ("https://iko.soy/warden/hcaptcha.html?" ++ siteKey)
41− , Attr.style "width" "100%"
42− , Attr.style "height" "80vh"
43− ]
44− []
45− ]
frontend/Pages/Cipher.elm+31−126
@@ -1,31 +1,17 @@
1−module Pages.Cipher exposing
1+module Pages.Cipher exposing (..)
2− ( Callbacks
3− , Model
4− , Msg
5− , event
6− , init
7− , subscriptions
8− , title
9− , update
10− , view
11− )
12
2
13import Bridge
3import Bridge
14−import GlobalEvents
15import Html exposing (..)
4import Html exposing (..)
16import Html.Attributes as Attr
5import Html.Attributes as Attr
17import Html.Events as Ev
6import Html.Events as Ev
18import Page exposing (..)
7import Page exposing (..)
19−import Time
20import Utils exposing (..)
8import Utils exposing (..)
21
9
22
10
23−type alias Model emsg =
11+type alias Model =
24− { cipher : Bridge.FullCipher
12+ { cipher : Bridge.Sub_LoadCipher
25 , passwordHidden : Bool
13 , passwordHidden : Bool
26 , cvvHidden : Bool
14 , cvvHidden : Bool
27− , decodedTotp : Maybe { code : String, interval : Int }
28− , callbacks : Callbacks emsg
29 }
15 }
30
16
31
17
@@ -34,107 +20,51 @@ type Msg
34 | ToggleCVVVisiblity
20 | ToggleCVVVisiblity
35 | Copy String
21 | Copy String
36 | Open String
22 | Open String
37− | Edit Bridge.FullCipher
38
23
39
24
40type alias Callbacks msg =
25type alias Callbacks msg =
41− { copy : String -> msg
26+ { copy : String -> msg, open : String -> msg }
42− , open : String -> msg
43− , edit : Bridge.FullCipher -> msg
44− , needTotp : String -> msg
45− }
46−
47−
48−event : Model emsg -> GlobalEvents.Event -> Model emsg
49−event model ev =
50− case ev of
51− GlobalEvents.UpdateCipher c ->
52− { model
53− | cipher =
54− if c.id == model.cipher.id then
55− c
56−
57− else
58− model.cipher
59− }
60
27
61− GlobalEvents.DecodedTotp { source, code, interval } ->
62− case model.cipher.cipher of
63− Bridge.LoginCipher { totp } ->
64− if totp == Just source then
65− { model | decodedTotp = Just { code = code, interval = interval } }
66
28
67− else
29+page : Callbacks emsg -> Page Bridge.Sub_LoadCipher Model Msg emsg
68− model
30+page callbacks liftMsg =
69−
31+ { init = \cipher -> Tuple.mapSecond (Cmd.map liftMsg) (init cipher)
70− _ ->
32+ , view = \model -> view model |> List.map (Html.map liftMsg)
71− model
33+ , update = \msg model -> update callbacks liftMsg msg model
72−
34+ , subscriptions = \model -> subscriptions model |> Sub.map liftMsg
73− _ ->
74− model
75−
76−
77−title : Model emsg -> List (Html Msg)
78−title { cipher } =
79− [ text cipher.name
35+ , title = \{ cipher } -> cipher.name
80− , span [ Attr.class "u-float-right" ] [ iconButton "edit" (Edit cipher) ]
36+ }
81− ]
82
37
83
38
84−init : Callbacks emsg -> Bridge.FullCipher -> ( Model emsg, Cmd emsg )
39+init : Bridge.Sub_LoadCipher -> ( Model, Cmd Msg )
85−init callbacks cipher =
40+init cipher =
86 ( { cipher = cipher
41 ( { cipher = cipher
87 , passwordHidden = True
42 , passwordHidden = True
88 , cvvHidden = True
43 , cvvHidden = True
89− , decodedTotp = Nothing
90− , callbacks = callbacks
91 }
44 }
92− , case cipher.cipher of
93− Bridge.LoginCipher { totp } ->
94− case totp of
95− Just x ->
96− callbacks.needTotp x |> pureCmd
97−
98− Nothing ->
99− Cmd.none
100−
101− _ ->
102− Cmd.none
45+ , Cmd.none
103 )
46 )
104
47
105
48
106−update : Msg -> Model emsg -> ( Model emsg, Cmd emsg )
49+update : Callbacks emsg -> (Msg -> emsg) -> Msg -> Model -> ( Result String Model, Cmd emsg )
107−update msg model =
50+update { copy, open } _ msg model =
108 case msg of
51 case msg of
109 TogglePasswordVisiblity ->
52 TogglePasswordVisiblity ->
110− ( { model | passwordHidden = not model.passwordHidden }, Cmd.none )
53+ ( Ok { model | passwordHidden = not model.passwordHidden }, Cmd.none )
111
54
112 ToggleCVVVisiblity ->
55 ToggleCVVVisiblity ->
113− ( { model | cvvHidden = not model.cvvHidden }, Cmd.none )
56+ ( Ok { model | cvvHidden = not model.cvvHidden }, Cmd.none )
114
57
115 Copy text ->
58 Copy text ->
116− ( model, model.callbacks.copy text |> pureCmd )
59+ ( Ok model, copy text |> pureCmd )
117
60
118 Open uri ->
61 Open uri ->
119− ( model, model.callbacks.open uri |> pureCmd )
62+ ( Ok model, open uri |> pureCmd )
120−
121− Edit cipher ->
122− ( model, model.callbacks.edit cipher |> pureCmd )
123−
124−
125−subscriptions : Model msg -> Sub msg
126−subscriptions { cipher, callbacks } =
127− case cipher.cipher of
128− Bridge.LoginCipher { totp } ->
129− case totp of
130− Just x ->
131− Time.every 1000 (always (callbacks.needTotp x))
132
63
133− Nothing ->
134− Sub.none
135
64
136− _ ->
65+subscriptions : Model -> Sub Msg
66+subscriptions _ =
137− Sub.none
67+ Sub.none
138
68
139
69
140row : { name : String, value : String, nameIcon : String, icons : List ( String, msg ) } -> Html msg
70row : { name : String, value : String, nameIcon : String, icons : List ( String, msg ) } -> Html msg
@@ -147,10 +77,10 @@ row { name, value, nameIcon, icons } =
147 ]
77 ]
148
78
149
79
150−view : Model emsg -> List (Html Msg)
80+view : Model -> List (Html Msg)
151−view { passwordHidden, cipher, cvvHidden, decodedTotp } =
81+view { passwordHidden, cipher, cvvHidden } =
152− (case cipher.cipher of
82+ (case cipher.cipherType of
153− Bridge.LoginCipher { username, password, uris, totp } ->
83+ Bridge.LoginCipher { username, password, uris } ->
154 maybeList username
84 maybeList username
155 (\x ->
85 (\x ->
156 row
86 row
@@ -170,41 +100,16 @@ view { passwordHidden, cipher, cvvHidden, decodedTotp } =
170 , icons = [ ( hiddenButtonIcon passwordHidden, TogglePasswordVisiblity ), ( "copy", Copy x ) ]
100 , icons = [ ( hiddenButtonIcon passwordHidden, TogglePasswordVisiblity ), ( "copy", Copy x ) ]
171 }
101 }
172 )
102 )
173− ++ maybeList totp
174− (\_ ->
175− row
176− { name = "One-time password"
177− , value =
178− case decodedTotp of
179− Nothing ->
180− "Loading..."
181−
182− Just { code } ->
183− code
184− , nameIcon = "revisions"
185− , icons =
186− case decodedTotp of
187− Nothing ->
188− []
189−
190− Just { code } ->
191− [ ( "copy", Copy code ) ]
192− }
193− )
194 ++ (uris
103 ++ (uris
195 |> List.map
104 |> List.map
196 (\uri ->
105 (\uri ->
197 row
106 row
198− { name = "URL"
199− , value = uri
200− , nameIcon = "get-link"
201− , icons = [ ( "external-link", Open uri ), ( "copy", Copy uri ) ]
107+ { name = "URL", value = uri, nameIcon = "get-link", icons = [ ( "external-link", Open uri ), ( "copy", Copy uri ) ] }
202− }
203 )
108 )
204 )
109 )
205
110
206 Bridge.NoteCipher contents ->
111 Bridge.NoteCipher contents ->
207− [ row { name = "Note", value = contents, nameIcon = "switcher-environments", icons = [] }
112+ [ row { name = "Note", value = contents, nameIcon = "edit", icons = [] }
208 ]
113 ]
209
114
210 Bridge.CardCipher { number, code, cardholderName, expMonth, expYear } ->
115 Bridge.CardCipher { number, code, cardholderName, expMonth, expYear } ->
@@ -274,7 +179,7 @@ view { passwordHidden, cipher, cvvHidden, decodedTotp } =
274 ++ maybeList ssn
179 ++ maybeList ssn
275 (\x ->
180 (\x ->
276 row
181 row
277− { name = "Social security number"
182+ { name = "Socia security number"
278 , value = x
183 , value = x
279 , nameIcon = ""
184 , nameIcon = ""
280 , icons = [ ( "copy", Copy x ) ]
185 , icons = [ ( "copy", Copy x ) ]
frontend/Pages/Ciphers.elm+59−149
@@ -1,18 +1,6 @@
1−module Pages.Ciphers exposing
1+module Pages.Ciphers exposing (Callbacks, Model, Msg, menuConfig, page)
2− ( Callbacks
3− , Model
4− , Msg
5− , event
6− , init
7− , menuConfig
8− , title
9− , update
10− , updateCiphers
11− , view
12− )
13
2
14import Bridge
3import Bridge
15−import GlobalEvents
16import Html exposing (..)
4import Html exposing (..)
17import Html.Attributes as Attr
5import Html.Attributes as Attr
18import Html.Events as Ev
6import Html.Events as Ev
@@ -25,26 +13,19 @@ import Search
25import Utils exposing (..)
13import Utils exposing (..)
26
14
27
15
28−type alias Model emsg =
16+type alias Model =
29 { ciphers : Bridge.Sub_LoadCiphers_List
17 { ciphers : Bridge.Sub_LoadCiphers_List
30 , search : String
18 , search : String
31 , menuVisible : Bool
19 , menuVisible : Bool
32 , ciphersListFilter : CiphersFilter
20 , ciphersListFilter : CiphersFilter
33 , scroll : InfiniteScroll.Model Msg
21 , scroll : InfiniteScroll.Model Msg
34 , sublist : { end : Int }
22 , sublist : { end : Int }
35− , cipherSelectDropdownVisivble : Bool
36− , callbacks : Callbacks emsg
37 }
23 }
38
24
39
25
40−updateCiphers : Bridge.Sub_LoadCiphers_List -> Model emsg -> Model emsg
41−updateCiphers ciphers model =
42− { model | ciphers = ciphers }
43−
44−
45type CiphersFilter
26type CiphersFilter
46 = AllCiphers
27 = AllCiphers
47− | SpecificCiphers Bridge.CipherType
28+ | SpecificCiphers Bridge.Sub_LoadCiphers_cipherType
48
29
49
30
50applyCipherFilter : CiphersFilter -> Bridge.Sub_LoadCiphers_List -> Bridge.Sub_LoadCiphers_List
31applyCipherFilter : CiphersFilter -> Bridge.Sub_LoadCiphers_List -> Bridge.Sub_LoadCiphers_List
@@ -57,7 +38,7 @@ applyCipherFilter filter list =
57 list |> List.filter (.cipherType >> (==) t)
38 list |> List.filter (.cipherType >> (==) t)
58
39
59
40
60−menuConfig : String -> Model emsg -> Navigation.MenuConfig Msg
41+menuConfig : String -> Model -> Navigation.MenuConfig Msg
61menuConfig email { ciphersListFilter, menuVisible } =
42menuConfig email { ciphersListFilter, menuVisible } =
62 { title = email
43 { title = email
63 , items =
44 , items =
@@ -82,7 +63,7 @@ menuConfig email { ciphersListFilter, menuVisible } =
82 , current = ciphersListFilter == SpecificCiphers Bridge.CardType
63 , current = ciphersListFilter == SpecificCiphers Bridge.CardType
83 }
64 }
84 , { icon = "user"
65 , { icon = "user"
85− , name = "Contacts"
66+ , name = "Identities"
86 , trigger = UpdateFilter (SpecificCiphers Bridge.IdentityType)
67 , trigger = UpdateFilter (SpecificCiphers Bridge.IdentityType)
87 , current = ciphersListFilter == SpecificCiphers Bridge.IdentityType
68 , current = ciphersListFilter == SpecificCiphers Bridge.IdentityType
88 }
69 }
@@ -101,137 +82,72 @@ type Msg
101 | LogOut
82 | LogOut
102 | LoadMore InfiniteScroll.Direction
83 | LoadMore InfiniteScroll.Direction
103 | InfiniteScrollMsg InfiniteScroll.Msg
84 | InfiniteScrollMsg InfiniteScroll.Msg
104− | CreateNewCipher Bridge.CipherType
105− | ToggleSelectCipherTypeVisible
106− | SelectCipher String
107
85
108
86
109type alias Callbacks msg =
87type alias Callbacks msg =
110 { selected : String -> msg
88 { selected : String -> msg
111 , logOut : msg
89 , logOut : msg
112− , createNewCipher : Bridge.CipherType -> msg
113− , lift : Msg -> msg
114 }
90 }
115
91
116
92
117−event : Model emsg -> GlobalEvents.Event -> Model emsg
93+page : Callbacks emsg -> Page Bridge.Sub_LoadCiphers_List Model Msg emsg
118−event model ev =
94+page callbacks liftMsg =
119− case ev of
95+ { init = \ciphers -> Tuple.mapSecond (Cmd.map liftMsg) (init ciphers)
120− GlobalEvents.UpdateCipher c ->
96+ , view = view callbacks liftMsg
121− { model
97+ , update = \msg model -> update callbacks liftMsg msg model
122− | ciphers =
98+ , subscriptions = \model -> subscriptions model |> Sub.map liftMsg
123− model.ciphers
99+ , title =
124− |> List.map
100+ \{ ciphersListFilter } ->
125− (\cipher ->
101+ case ciphersListFilter of
126− if cipher.id == c.id then
102+ AllCiphers ->
127− { cipher | name = c.name }
103+ "All items"
128−
129− else
130− cipher
131− )
132− }
133−
134− _ ->
135− model
136
104
105+ SpecificCiphers cipherType ->
106+ case cipherType of
107+ Bridge.CardType ->
108+ "Cards"
137
109
138−title : Model emsg -> List (Html Msg)
110+ Bridge.IdentityType ->
139−title { ciphersListFilter, cipherSelectDropdownVisivble } =
111+ "Identities"
140− [ text
141− (case ciphersListFilter of
142− AllCiphers ->
143− "All items"
144
112
145− SpecificCiphers cipherType ->
146− case cipherType of
147− Bridge.CardType ->
113+ Bridge.LoginType ->
148− "Cards"
114+ "Passwords"
149
115
150− Bridge.IdentityType ->
151− "Contacts"
152−
153− Bridge.LoginType ->
154− "Passwords"
155−
156− Bridge.NoteType ->
116+ Bridge.NoteType ->
157− "Notes"
117+ "Notes"
158− )
118+ }
159− , span [ Attr.class "u-float-right" ]
160− [ span [ Attr.class "p-contextual-menu" ]
161− ([ span [] [ iconButton "plus" ToggleSelectCipherTypeVisible ]
162− ]
163− ++ optionals cipherSelectDropdownVisivble
164− [ div
165− [ Attr.class "overlay"
166− , Ev.onClick ToggleSelectCipherTypeVisible
167− ]
168− []
169− , span
170− [ Attr.class "p-contextual-menu__dropdown"
171− , Attr.attribute "aria-hidden" "false"
172− ]
173− (let
174− create t =
175− CreateNewCipher t
176− in
177− [ button
178− [ Attr.class "p-contextual-menu__link"
179− , Ev.onClick (create Bridge.LoginType)
180− ]
181− [ text "Login" ]
182− , button
183− [ Attr.class "p-contextual-menu__link"
184− , Ev.onClick (create Bridge.CardType)
185− ]
186− [ text "Card" ]
187− , button
188− [ Attr.class "p-contextual-menu__link"
189− , Ev.onClick (create Bridge.NoteType)
190− ]
191− [ text "Note" ]
192− , button
193− [ Attr.class "p-contextual-menu__link"
194− , Ev.onClick (create Bridge.IdentityType)
195− ]
196− [ text "Contact" ]
197− ]
198− )
199− ]
200− )
201− ]
202− ]
203
119
204
120
205−init : Callbacks emsg -> Bridge.Sub_LoadCiphers_List -> Model emsg
121+init : Bridge.Sub_LoadCiphers_List -> ( Model, Cmd Msg )
206−init callbacks ciphers =
122+init ciphers =
207− { ciphers = ciphers
123+ ( { ciphers = ciphers
208− , search = ""
124+ , search = ""
209− , menuVisible = False
125+ , menuVisible = False
210− , ciphersListFilter = AllCiphers
126+ , ciphersListFilter = AllCiphers
211− , scroll = InfiniteScroll.init (LoadMore >> pureCmd)
127+ , scroll = InfiniteScroll.init (LoadMore >> pureCmd)
212− , sublist = { end = 20 }
128+ , sublist = { end = 20 }
213− , cipherSelectDropdownVisivble = False
129+ }
214− , callbacks = callbacks
130+ , Cmd.none
215− }
131+ )
216
132
217
133
218−update : Msg -> Model emsg -> ( Model emsg, Cmd emsg )
134+update : Callbacks emsg -> (Msg -> emsg) -> Msg -> Model -> ( Result String Model, Cmd emsg )
219−update msg model =
135+update { logOut } liftMsg msg model =
220 case msg of
136 case msg of
221 Noop ->
137 Noop ->
222− ( model, Cmd.none )
138+ ( Ok model, Cmd.none )
223
139
224 UpdateSearch s ->
140 UpdateSearch s ->
225− ( { model | search = s }, Cmd.none )
141+ ( Ok { model | search = s }, Cmd.none )
226
142
227 ToggleMenu ->
143 ToggleMenu ->
228− ( { model | menuVisible = not model.menuVisible }, Cmd.none )
144+ ( Ok { model | menuVisible = not model.menuVisible }, Cmd.none )
229
145
230 UpdateFilter filter ->
146 UpdateFilter filter ->
231− ( { model | ciphersListFilter = filter, menuVisible = False }, Cmd.none )
147+ ( Ok { model | ciphersListFilter = filter, menuVisible = False }, Cmd.none )
232
148
233 LogOut ->
149 LogOut ->
234− ( model, pureCmd model.callbacks.logOut )
150+ ( Ok model, pureCmd logOut )
235
151
236 LoadMore direction ->
152 LoadMore direction ->
237 let
153 let
@@ -243,54 +159,48 @@ update msg model =
243 InfiniteScroll.Bottom ->
159 InfiniteScroll.Bottom ->
244 { end = min (model.sublist.end + 10) (List.length model.ciphers) }
160 { end = min (model.sublist.end + 10) (List.length model.ciphers) }
245 in
161 in
246− ( { model | sublist = newSublist, scroll = InfiniteScroll.stopLoading model.scroll }, Cmd.none )
162+ ( Ok { model | sublist = newSublist, scroll = InfiniteScroll.stopLoading model.scroll }, Cmd.none )
247
163
248 InfiniteScrollMsg msg_ ->
164 InfiniteScrollMsg msg_ ->
249 let
165 let
250 ( scroll, cmd ) =
166 ( scroll, cmd ) =
251 InfiniteScroll.update InfiniteScrollMsg msg_ model.scroll
167 InfiniteScroll.update InfiniteScrollMsg msg_ model.scroll
252 in
168 in
253− ( { model | scroll = scroll }, Cmd.map model.callbacks.lift cmd )
169+ ( Ok { model | scroll = scroll }, Cmd.map liftMsg cmd )
254−
255− CreateNewCipher t ->
256− ( { model | cipherSelectDropdownVisivble = False }, pureCmd (model.callbacks.createNewCipher t) )
257
170
258− ToggleSelectCipherTypeVisible ->
259− ( { model | cipherSelectDropdownVisivble = not model.cipherSelectDropdownVisivble }
260− , Cmd.none
261− )
262
171
263− SelectCipher id ->
172+subscriptions : Model -> Sub Msg
264− ( model, model.callbacks.selected id |> pureCmd )
173+subscriptions _ =
174+ Sub.none
265
175
266
176
267−view : Model emsg -> List (Html Msg)
177+view : Callbacks emsg -> (Msg -> emsg) -> Model -> List (Html emsg)
268−view { ciphers, search, ciphersListFilter, sublist } =
178+view { selected } liftMsg { ciphers, search, ciphersListFilter, sublist } =
269 [ input
179 [ input
270 [ Attr.type_ "search"
180 [ Attr.type_ "search"
271 , Attr.value search
181 , Attr.value search
272− , Ev.onInput UpdateSearch
182+ , Ev.onInput (liftMsg << UpdateSearch)
273 , Attr.placeholder "Search"
183 , Attr.placeholder "Search"
274 , Attr.attribute "autocomplete" "off"
184 , Attr.attribute "autocomplete" "off"
275 ]
185 ]
276 []
186 []
277 , ciphers
187 , ciphers
278 |> applyCipherFilter ciphersListFilter
188 |> applyCipherFilter ciphersListFilter
279− |> Search.searchList search .name (List.take sublist.end >> Lazy.lazy showCiphers)
189+ |> Search.searchList search .name (List.take sublist.end >> Lazy.lazy3 showCiphers liftMsg selected)
280 ]
190 ]
281
191
282
192
283−showCiphers : Bridge.Sub_LoadCiphers_List -> Html Msg
193+showCiphers : (Msg -> msg) -> (String -> msg) -> Bridge.Sub_LoadCiphers_List -> Html msg
284−showCiphers ciphers =
194+showCiphers liftMsg selected ciphers =
285− Keyed.ul [ Attr.class "p-list--divided", InfiniteScroll.infiniteScroll InfiniteScrollMsg, Attr.class "ciphers-list no-scroll-bar" ]
195+ Keyed.ul [ Attr.class "p-list--divided", InfiniteScroll.infiniteScroll (InfiniteScrollMsg >> liftMsg), Attr.class "ciphers-list no-scroll-bar" ]
286 (ciphers
196 (ciphers
287 |> List.map
197 |> List.map
288 (\{ name, date, id } ->
198 (\{ name, date, id } ->
289 ( id
199 ( id
290− , li [ Attr.class "p-list__item cipher-row", Ev.onClick (SelectCipher id) ]
200+ , li [ Attr.class "p-list__item cipher-row", Ev.onClick (selected id) ]
291 [ div [ Attr.class "cipher-row-container" ]
201 [ div [ Attr.class "cipher-row-container" ]
292 [ p [] [ text name ]
202 [ p [] [ text name ]
293− , p [ Attr.class "p-text--small u-align-text--right u-text--muted hide-in-test" ] [ text date ]
203+ , p [ Attr.class "p-text--small u-align-text--right u-text--muted" ] [ text date ]
294 ]
204 ]
295 ]
205 ]
296 )
206 )
frontend/Pages/EditCipher.elmdeleted−475
@@ -1,475 +0,0 @@
1−module Pages.EditCipher exposing (Callbacks, Model, Msg, event, init, title, update, view)
2−
3−import Bridge
4−import GlobalEvents
5−import Html exposing (..)
6−import Html.Attributes as Attr
7−import Html.Events as Ev
8−import Logic.Cipher exposing (normalizeCipher)
9−import Modal exposing (modal)
10−import Page exposing (..)
11−import Pages.MasterPassword exposing (Msg)
12−import Pages.PasswordGenerator as PasswordGenerator
13−import Utils exposing (..)
14−
15−
16−type alias Model msg =
17− { fullCipher : Bridge.FullCipher
18− , passwordGenerator : Maybe PasswordGenerator.Model
19− , callbacks : Callbacks msg
20− }
21−
22−
23−type Msg
24− = EditCipher Bridge.FullCipher
25− | PasswordGeneratorMsg PasswordGenerator.Msg
26− | OpenGeneratePasword
27− | CloseGeneratePassword
28− | GeneratePassword Bridge.PasswordGeneratorConfig
29− | Delete
30− | Save
31−
32−
33−type alias Callbacks msg =
34− { save : Bridge.FullCipher -> msg
35− , generatePassword : Bridge.PasswordGeneratorConfig -> msg
36− , delete : Maybe (Bridge.FullCipher -> msg)
37− }
38−
39−
40−title : Model msg -> List (Html Msg)
41−title { fullCipher } =
42− [ text fullCipher.name
43− , span [ Attr.class "u-float-right" ]
44− [ iconButton "task-outstanding" Save
45− ]
46− ]
47−
48−
49−event : Model msg -> GlobalEvents.Event -> Model msg
50−event model ev =
51− case ev of
52− GlobalEvents.UpdateCipher c ->
53− { model
54− | fullCipher =
55− if c.id == model.fullCipher.id then
56− c
57−
58− else
59− model.fullCipher
60− }
61−
62− GlobalEvents.GeneratedPassword password ->
63− let
64− fullCipher =
65− model.fullCipher
66− in
67− { model
68− | passwordGenerator = Nothing
69− , fullCipher =
70− { fullCipher
71− | cipher =
72− case fullCipher.cipher of
73− Bridge.LoginCipher c ->
74− Bridge.LoginCipher
75− { c | password = Just password }
76−
77− c ->
78− c
79− }
80− }
81−
82− _ ->
83− model
84−
85−
86−init : { fullCipher : Bridge.FullCipher, callbacks : Callbacks emsg } -> ( Model emsg, Cmd emsg )
87−init { fullCipher, callbacks } =
88− ( { fullCipher = fullCipher
89− , passwordGenerator = Nothing
90− , callbacks = callbacks
91− }
92− , Cmd.none
93− )
94−
95−
96−update : Msg -> Model emsg -> ( Model emsg, Cmd emsg )
97−update msg model =
98− case msg of
99− EditCipher fullCipher ->
100− ( { model | fullCipher = fullCipher }, Cmd.none )
101−
102− PasswordGeneratorMsg m ->
103− ( { model | passwordGenerator = Maybe.map (PasswordGenerator.update m) model.passwordGenerator }
104− , Cmd.none
105− )
106−
107− OpenGeneratePasword ->
108− ( { model | passwordGenerator = Just PasswordGenerator.init }
109− , Cmd.none
110− )
111−
112− CloseGeneratePassword ->
113− ( { model | passwordGenerator = Nothing }, Cmd.none )
114−
115− GeneratePassword cfg ->
116− ( model, pureCmd (model.callbacks.generatePassword cfg) )
117−
118− Delete ->
119− ( model
120− , Maybe.withDefault Cmd.none
121− (Maybe.map (\f -> f model.fullCipher |> pureCmd) model.callbacks.delete)
122− )
123−
124− Save ->
125− let
126− { fullCipher } =
127− model
128− in
129− ( model
130− , model.callbacks.save { fullCipher | cipher = normalizeCipher fullCipher.cipher } |> pureCmd
131− )
132−
133−
134−heading : String -> String -> Html msg
135−heading icons name =
136− span [ Attr.class "u-text--muted" ] [ i [ Attr.class ("p-icon--" ++ icons) ] [], text (" " ++ name) ]
137−
138−
139−row : { name : String, nameIcon : String, attrs : List (Html.Attribute msg) } -> Html msg
140−row { name, nameIcon, attrs } =
141− p []
142− [ heading nameIcon name
143− , br [] []
144− , input attrs []
145− ]
146−
147−
148−view : Model emsg -> List (Html Msg)
149−view { fullCipher, passwordGenerator, callbacks } =
150− maybeList passwordGenerator
151− (\x ->
152− modal
153− { title = "Password generator"
154− , close = CloseGeneratePassword
155− , footer =
156− [ button
157− [ Attr.class "p-button--positive u-no-margin"
158− , Ev.onClick <| GeneratePassword x.passwordConfig
159− ]
160− [ text "Generate password" ]
161− ]
162− , body =
163− PasswordGenerator.view x |> List.map (Html.map PasswordGeneratorMsg)
164− }
165− )
166− ++ [ row
167− { name = "Entry name"
168− , nameIcon = ""
169− , attrs =
170− [ Attr.type_ "text"
171− , Attr.value fullCipher.name
172− , Ev.onInput (\x -> { fullCipher | name = x } |> EditCipher)
173− , Attr.attribute "autocomplete" "off"
174− ]
175− }
176− ]
177− ++ (case fullCipher.cipher of
178− Bridge.LoginCipher cipher ->
179− let
180− { username, password, uris, totp } =
181− cipher
182−
183− edit c =
184− { fullCipher | cipher = Bridge.LoginCipher c } |> EditCipher
185− in
186− [ row
187− { name = "Username"
188− , nameIcon = "user"
189− , attrs =
190− [ Attr.type_ "text"
191− , Attr.value (Maybe.withDefault "" username)
192− , Ev.onInput (\x -> edit { cipher | username = Just x })
193− , Attr.attribute "autocomplete" "username"
194− ]
195− }
196− , p []
197− [ heading "security" "Password"
198− , br [] []
199− , input
200− [ Attr.type_ "text"
201− , Attr.value (Maybe.withDefault "" password)
202− , Ev.onInput (\x -> edit { cipher | password = Just x })
203− , Attr.attribute "autocomplete" "new-password"
204− , Attr.style "width" "calc(100% - 3.5rem)"
205− ]
206− []
207− , iconButton "restart" OpenGeneratePasword
208− ]
209− , row
210− { name = "One-time password"
211− , nameIcon = "revisions"
212− , attrs =
213− [ Attr.type_ "text"
214− , Attr.value (Maybe.withDefault "" totp)
215− , Ev.onInput (\x -> edit { cipher | totp = Just x })
216− , Attr.attribute "autocomplete" "off"
217− ]
218− }
219− ]
220− ++ (uris
221− |> List.indexedMap
222− (\i uri ->
223− row
224− { name = "URL"
225− , nameIcon = "get-link"
226− , attrs =
227− [ Attr.type_ "url"
228− , Attr.value uri
229− , Ev.onInput (\x -> edit { cipher | uris = replace i x uris })
230− ]
231− }
232− )
233− )
234− ++ [ row
235− { name = "URL"
236− , nameIcon = "get-link"
237− , attrs =
238− [ Attr.type_ "url"
239− , Ev.onInput (\x -> edit { cipher | uris = uris ++ [ x ] })
240− ]
241− }
242− ]
243−
244− Bridge.NoteCipher contents ->
245− [ p []
246− [ heading "switcher-environments" "Note"
247− , br [] []
248− , textarea
249− [ Attr.spellcheck True
250− , Attr.style "height" "65vh"
251− , Attr.value contents
252− , Ev.onInput (\x -> EditCipher { fullCipher | cipher = Bridge.NoteCipher x })
253− ]
254− []
255− ]
256− ]
257−
258− Bridge.CardCipher cipher ->
259− let
260− { number, code, cardholderName, expMonth, expYear } =
261− cipher
262−
263− edit c =
264− { fullCipher | cipher = Bridge.CardCipher c } |> EditCipher
265− in
266− [ row
267− { name = "Card number"
268− , nameIcon = "containers"
269− , attrs =
270− [ Attr.attribute "autocomplete" "cc-number"
271− , Attr.type_ "text"
272− , Attr.value (Maybe.withDefault "" number)
273− , Ev.onInput (\x -> edit { cipher | number = Just x })
274− ]
275− }
276− , p []
277− [ heading "timed-out" "Expiration date"
278− , br [] []
279− , input
280− [ Attr.attribute "autocomplete" "cc-exp-month"
281− , Attr.type_ "text"
282− , Attr.value (Maybe.withDefault "" expMonth)
283− , Ev.onInput (\x -> edit { cipher | expMonth = Just x })
284− , Attr.style "width" "30%"
285− , Attr.style "min-width" "initial"
286− , Attr.class "u-align--right"
287− ]
288− []
289− , text " / "
290− , input
291− [ Attr.attribute "autocomplete" "cc-exp-year"
292− , Attr.type_ "text"
293− , Attr.value (Maybe.withDefault "" expYear)
294− , Ev.onInput (\x -> edit { cipher | expYear = Just x })
295− , Attr.style "width" "30%"
296− , Attr.style "min-width" "initial"
297− ]
298− []
299− ]
300− , row
301− { name = "CVV"
302− , nameIcon = "security"
303− , attrs =
304− [ Attr.attribute "autocomplete" "cc-csc"
305− , Attr.type_ "text"
306− , Attr.value (Maybe.withDefault "" code)
307− , Ev.onInput (\x -> edit { cipher | code = Just x })
308− ]
309− }
310− , row
311− { name = "Cardholder name"
312− , nameIcon = "user"
313− , attrs =
314− [ Attr.attribute "autocomplete" "cc-name"
315− , Attr.type_ "text"
316− , Attr.value (Maybe.withDefault "" cardholderName)
317− , Ev.onInput (\x -> edit { cipher | cardholderName = Just x })
318− ]
319− }
320− ]
321−
322− Bridge.IdentityCipher cipher ->
323− let
324− { address1, address2, address3, company, email, firstName, lastName, licenseNumber, middleName, passportNumber, phone, ssn, username } =
325− cipher
326−
327− edit c =
328− { fullCipher | cipher = Bridge.IdentityCipher c } |> EditCipher
329− in
330− [ row
331− { name = "First name"
332− , nameIcon = ""
333− , attrs =
334− [ Attr.attribute "autocomplete" "given-name"
335− , Attr.type_ "text"
336− , Attr.value (Maybe.withDefault "" firstName)
337− , Ev.onInput (\x -> edit { cipher | firstName = Just x })
338− ]
339− }
340− , row
341− { name = "Middle name"
342− , nameIcon = ""
343− , attrs =
344− [ Attr.attribute "autocomplete" "additional-name"
345− , Attr.type_ "text"
346− , Attr.value (Maybe.withDefault "" middleName)
347− , Ev.onInput (\x -> edit { cipher | middleName = Just x })
348− ]
349− }
350− , row
351− { name = "Last name"
352− , nameIcon = ""
353− , attrs =
354− [ Attr.attribute "autocomplete" "family-name"
355− , Attr.type_ "text"
356− , Attr.value (Maybe.withDefault "" lastName)
357− , Ev.onInput (\x -> edit { cipher | lastName = Just x })
358− ]
359− }
360− , row
361− { name = "Username"
362− , nameIcon = ""
363− , attrs =
364− [ Attr.attribute "autocomplete" "username"
365− , Attr.type_ "text"
366− , Attr.value (Maybe.withDefault "" username)
367− , Ev.onInput (\x -> edit { cipher | username = Just x })
368− ]
369− }
370− , row
371− { name = "Company"
372− , nameIcon = ""
373− , attrs =
374− [ Attr.attribute "autocomplete" "organization"
375− , Attr.type_ "text"
376− , Attr.value (Maybe.withDefault "" company)
377− , Ev.onInput (\x -> edit { cipher | company = Just x })
378− ]
379− }
380− , row
381− { name = "Social security number"
382− , nameIcon = ""
383− , attrs =
384− [ Attr.attribute "autocomplete" "off"
385− , Attr.type_ "number"
386− , Attr.value (Maybe.withDefault "" ssn)
387− , Ev.onInput (\x -> edit { cipher | ssn = Just x })
388− ]
389− }
390− , row
391− { name = "Passport number"
392− , nameIcon = ""
393− , attrs =
394− [ Attr.attribute "autocomplete" "off"
395− , Attr.type_ "number"
396− , Attr.value (Maybe.withDefault "" passportNumber)
397− , Ev.onInput (\x -> edit { cipher | passportNumber = Just x })
398− ]
399− }
400− , row
401− { name = "License Number"
402− , nameIcon = ""
403− , attrs =
404− [ Attr.attribute "autocomplete" "off"
405− , Attr.type_ "number"
406− , Attr.value (Maybe.withDefault "" licenseNumber)
407− , Ev.onInput (\x -> edit { cipher | licenseNumber = Just x })
408− ]
409− }
410− , row
411− { name = "Email"
412− , nameIcon = ""
413− , attrs =
414− [ Attr.attribute "autocomplete" "email"
415− , Attr.type_ "email"
416− , Attr.value (Maybe.withDefault "" email)
417− , Ev.onInput (\x -> edit { cipher | email = Just x })
418− ]
419− }
420− , row
421− { name = "Phone number"
422− , nameIcon = ""
423− , attrs =
424− [ Attr.attribute "autocomplete" "tel"
425− , Attr.type_ "tel"
426− , Attr.value (Maybe.withDefault "" phone)
427− , Ev.onInput (\x -> edit { cipher | phone = Just x })
428− ]
429− }
430− , row
431− { name = "Address line 1"
432− , nameIcon = ""
433− , attrs =
434− [ Attr.attribute "autocomplete" "address-line1"
435− , Attr.type_ "text"
436− , Attr.value (Maybe.withDefault "" address1)
437− , Ev.onInput (\x -> edit { cipher | address1 = Just x })
438− ]
439− }
440− , row
441− { name = "Address line 2"
442− , nameIcon = ""
443− , attrs =
444− [ Attr.attribute "autocomplete" "address-line2"
445− , Attr.type_ "text"
446− , Attr.value (Maybe.withDefault "" address2)
447− , Ev.onInput (\x -> edit { cipher | address2 = Just x })
448− ]
449− }
450− , row
451− { name = "Address line 3"
452− , nameIcon = ""
453− , attrs =
454− [ Attr.attribute "autocomplete" "address-line3"
455− , Attr.type_ "text"
456− , Attr.value (Maybe.withDefault "" address3)
457− , Ev.onInput (\x -> edit { cipher | address3 = Just x })
458− ]
459− }
460− ]
461− )
462− ++ optional (callbacks.delete /= Nothing)
463− (button
464− [ Attr.style "width" "100%"
465− , Attr.class "p-button--negative"
466− , Ev.onClick Delete
467− ]
468− [ text "Delete" ]
469− )
470−
471−
472−iconButton : String -> msg -> Html msg
473−iconButton name msg =
474− button [ Attr.class "p-button is-inline is-dense has-icon", Ev.onClick msg ]
475− [ i [ Attr.class ("p-icon--" ++ name) ] [] ]
frontend/Pages/Login.elm+33−33
@@ -1,4 +1,4 @@
1−module Pages.Login exposing (Callbacks, Model, Msg, init, title, update, view)
1+module Pages.Login exposing (Callbacks, Model, Msg, page)
2
2
3import Html exposing (..)
3import Html exposing (..)
4import Html.Attributes as Attr
4import Html.Attributes as Attr
@@ -7,11 +7,10 @@ import Page exposing (..)
7import Utils exposing (..)
7import Utils exposing (..)
8
8
9
9
10−type alias Model emsg =
10+type alias Model =
11 { server : String
11 { server : String
12 , email : String
12 , email : String
13 , password : String
13 , password : String
14− , callbacks : Callbacks emsg
15 }
14 }
16
15
17
16
@@ -27,45 +26,48 @@ type alias Callbacks emsg =
27 }
26 }
28
27
29
28
30−title : String
29+page : Callbacks emsg -> Page () Model Msg emsg
31−title =
30+page callbacks liftMsg =
31+ { init = \() -> Tuple.mapSecond (Cmd.map liftMsg) init
32+ , view = \model -> view model |> List.map (Html.map liftMsg)
33+ , update = \msg model -> update callbacks liftMsg msg model
34+ , subscriptions = \model -> subscriptions model |> Sub.map liftMsg
32− "Log into bitwarden"
35+ , title = always "Log into bitwarden"
36+ }
33
37
34
38
35−init : Callbacks emsg -> Model emsg
39+init : ( Model, Cmd Msg )
36−init callbacks =
40+init =
37− { server = "https://vault.bitwarden.com"
41+ ( { server = "https://bitwarden.iko.soy"
38− , email = ""
42+ , email = "mail@iko.soy"
39− , password = ""
43+ , password = ""
40− , callbacks = callbacks
41− }
44+ }
45+ , Cmd.none
46+ )
42
47
43
48
44−update : Msg -> Model emsg -> ( Model emsg, Cmd emsg )
49+update : Callbacks emsg -> (Msg -> emsg) -> Msg -> Model -> ( Result String Model, Cmd emsg )
45−update msg model =
50+update { submit } liftMsg msg model =
46 case msg of
51 case msg of
47 UpdateEmail email ->
52 UpdateEmail email ->
48− ( { model | email = email }, Cmd.none )
53+ ( Ok { model | email = email }, Cmd.none )
49
54
50 UpdateServer server ->
55 UpdateServer server ->
51− ( { model | server = server }, Cmd.none )
56+ ( Ok { model | server = server }, Cmd.none )
52
57
53 UpdatePassword password ->
58 UpdatePassword password ->
54− ( { model | password = password }, Cmd.none )
59+ ( Ok { model | password = password }, Cmd.none )
55
60
56 Submit ->
61 Submit ->
57− ( model
58− , pureCmd
62+ ( Ok model, pureCmd (submit model) )
59− (model.callbacks.submit
63+
60− { email = model.email
64+
61− , password = model.password
65+subscriptions : Model -> Sub Msg
62− , server = model.server
66+subscriptions model =
63− }
67+ Sub.none
64− )
68+
65− )
69+
66−
67−
68−view : Model emsg -> List (Html Msg)
70+view : Model -> List (Html Msg)
69view model =
71view model =
70 [ form [ Ev.onSubmit Submit ]
72 [ form [ Ev.onSubmit Submit ]
71 [ label [] [ text "Server" ]
73 [ label [] [ text "Server" ]
@@ -74,7 +76,6 @@ view model =
74 , Attr.value model.server
76 , Attr.value model.server
75 , Ev.onInput UpdateServer
77 , Ev.onInput UpdateServer
76 , Attr.attribute "autocomplete" "url"
78 , Attr.attribute "autocomplete" "url"
77− , Attr.required True
78 ]
79 ]
79 []
80 []
80 , label [] [ text "Email" ]
81 , label [] [ text "Email" ]
@@ -83,7 +84,6 @@ view model =
83 , Attr.value model.email
84 , Attr.value model.email
84 , Ev.onInput UpdateEmail
85 , Ev.onInput UpdateEmail
85 , Attr.attribute "autocomplete" "email"
86 , Attr.attribute "autocomplete" "email"
86− , Attr.required True
87 ]
87 ]
88 []
88 []
89 , label [] [ text "Password" ]
89 , label [] [ text "Password" ]
@@ -92,9 +92,9 @@ view model =
92 , Attr.value model.password
92 , Attr.value model.password
93 , Ev.onInput UpdatePassword
93 , Ev.onInput UpdatePassword
94 , Attr.attribute "autocomplete" "current-password"
94 , Attr.attribute "autocomplete" "current-password"
95− , Attr.required True
96 ]
95 ]
97 []
96 []
97+ , iframe [ Attr.src "https://iko.soy/warden/hcaptcha.html" ] []
98 , alignRight [ button [ Attr.type_ "submit" ] [ text "Log in" ] ]
98 , alignRight [ button [ Attr.type_ "submit" ] [ text "Log in" ] ]
99 ]
99 ]
100 ]
100 ]
frontend/Pages/MasterPassword.elm+30−21
@@ -1,4 +1,4 @@
1−module Pages.MasterPassword exposing (Callbacks, Model, Msg, init, title, update, view)
1+module Pages.MasterPassword exposing (..)
2
2
3import Html exposing (..)
3import Html exposing (..)
4import Html.Attributes as Attr
4import Html.Attributes as Attr
@@ -7,11 +7,10 @@ import Page exposing (..)
7import Utils exposing (..)
7import Utils exposing (..)
8
8
9
9
10−type alias Model emsg =
10+type alias Model =
11 { server : String
11 { server : String
12 , email : String
12 , email : String
13 , password : String
13 , password : String
14− , callbacks : Callbacks emsg
15 }
14 }
16
15
17
16
@@ -27,34 +26,45 @@ type alias Callbacks emsg =
27 }
26 }
28
27
29
28
30−title : String
29+page : Callbacks emsg -> Page { server : String, login : String } Model Msg emsg
31−title =
30+page callbacks liftMsg =
31+ { init = \cfg -> Tuple.mapSecond (Cmd.map liftMsg) (init cfg)
32+ , view = \model -> view model |> List.map (Html.map liftMsg)
33+ , update = \msg model -> update callbacks liftMsg msg model
34+ , subscriptions = \model -> subscriptions model |> Sub.map liftMsg
32− "Enter master password"
35+ , title = always "Enter master password"
36+ }
33
37
34
38
35−init : Callbacks emsg -> { server : String, login : String } -> Model emsg
39+init : { server : String, login : String } -> ( Model, Cmd Msg )
36−init callbacks { server, login } =
40+init { server, login } =
37− { server = server
41+ ( { server = server
38− , email = login
42+ , email = login
39− , password = ""
43+ , password = ""
40− , callbacks = callbacks
44+ }
41− }
45+ , Cmd.none
46+ )
42
47
43
48
44−update : Msg -> Model emsg -> ( Model emsg, Cmd emsg )
49+update : Callbacks emsg -> (Msg -> emsg) -> Msg -> Model -> ( Result String Model, Cmd emsg )
45−update msg model =
50+update { submit, reset } _ msg model =
46 case msg of
51 case msg of
47 UpdatePassword password ->
52 UpdatePassword password ->
48− ( { model | password = password }, Cmd.none )
53+ ( Ok { model | password = password }, Cmd.none )
49
54
50 Submit ->
55 Submit ->
51− ( model, pureCmd (model.callbacks.submit { password = model.password }) )
56+ ( Ok model, pureCmd (submit { password = model.password }) )
52
57
53 Reset ->
58 Reset ->
54− ( model, pureCmd model.callbacks.reset )
59+ ( Ok model, pureCmd reset )
60+
61+
62+subscriptions : Model -> Sub Msg
63+subscriptions _ =
64+ Sub.none
55
65
56
66
57−view : Model emsg -> List (Html Msg)
67+view : Model -> List (Html Msg)
58view model =
68view model =
59 [ alignRight [ button [ Attr.class "p-button--negative", Ev.onClick Reset ] [ text "Log out" ] ]
69 [ alignRight [ button [ Attr.class "p-button--negative", Ev.onClick Reset ] [ text "Log out" ] ]
60 , table [ Attr.class "p-table--mobile-card u-no-margin" ]
70 , table [ Attr.class "p-table--mobile-card u-no-margin" ]
@@ -73,8 +83,7 @@ view model =
73 [ Attr.type_ "password"
83 [ Attr.type_ "password"
74 , Attr.value model.password
84 , Attr.value model.password
75 , Ev.onInput UpdatePassword
85 , Ev.onInput UpdatePassword
76− , Attr.attribute "autocomplete" "new-password"
86+ , Attr.attribute "autocomplete" "current-password"
77− , Attr.required True
78 ]
87 ]
79 []
88 []
80 , alignRight [ button [ Attr.type_ "submit" ] [ text "Log in" ] ]
89 , alignRight [ button [ Attr.type_ "submit" ] [ text "Log in" ] ]
frontend/Pages/Navigation.elm+10−20
@@ -18,13 +18,13 @@ import Utils exposing (..)
18
18
19
19
20type TopButton msg
20type TopButton msg
21− = BackButton { action : msg, icon : Maybe String }
21+ = BackButton msg
22 | MenuButton (MenuConfig msg)
22 | MenuButton (MenuConfig msg)
23
23
24
24
25type alias Config msg =
25type alias Config msg =
26 { topButton : Maybe (TopButton msg)
26 { topButton : Maybe (TopButton msg)
27− , title : List (Html msg)
27+ , title : String
28 }
28 }
29
29
30
30
@@ -40,30 +40,23 @@ navigation { topButton, title } =
40 )
40 )
41 ++ [ nav [ Attr.class "p-tabs p-tabs__list no-scroll-bar" ]
41 ++ [ nav [ Attr.class "p-tabs p-tabs__list no-scroll-bar" ]
42 [ h3 []
42 [ h3 []
43− ([ case topButton of
43+ [ case topButton of
44 Nothing ->
44 Nothing ->
45 button
45 button
46 [ Attr.class "p-button--base is-inline u-no-margin", Attr.style "visibility" "hidden" ]
46 [ Attr.class "p-button--base is-inline u-no-margin", Attr.style "visibility" "hidden" ]
47 []
47 []
48
48
49− Just (BackButton { action, icon }) ->
49+ Just (BackButton msg) ->
50 button
50 button
51− [ Attr.class "p-button--base is-inline u-no-margin", Ev.onClick action ]
51+ [ Attr.class "p-button--base is-inline u-no-margin", Ev.onClick msg ]
52− [ case icon of
53− Nothing ->
54− i [ Attr.class "p-icon--chevron-up ninety-counter" ] []
52+ [ i [ Attr.class "p-icon--chevron-up ninety-counter" ] [] ]
55−
56− Just iconName ->
57− i [ Attr.class ("p-icon--" ++ iconName) ] []
58− ]
59
53
60 Just (MenuButton cfg) ->
54 Just (MenuButton cfg) ->
61 button
55 button
62 [ Attr.class "p-button--base is-inline u-no-margin", Ev.onClick cfg.toggle ]
56 [ Attr.class "p-button--base is-inline u-no-margin", Ev.onClick cfg.toggle ]
63 [ i [ Attr.class "p-icon--menu" ] [] ]
57 [ i [ Attr.class "p-icon--menu" ] [] ]
64− ]
65− ++ title
58+ , text title
66− )
59+ ]
67 ]
60 ]
68 ]
61 ]
69 )
62 )
@@ -142,10 +135,7 @@ pushView model stack =
142
135
143popView : PageStack model -> PageStack model
136popView : PageStack model -> PageStack model
144popView stack =
137popView stack =
145− stack
146− |> Nonempty.tail
147− |> Nonempty.fromList
148− |> Maybe.withDefault stack
138+ Nonempty.tail stack |> Nonempty.fromList |> Maybe.withDefault stack
149
139
150
140
151showNavigationView :
141showNavigationView :
@@ -153,7 +143,7 @@ showNavigationView :
153 ->
143 ->
154 (model
144 (model
155 ->
145 ->
156− { title : List (Html msg)
146+ { title : String
157 , body : List (Html msg)
147 , body : List (Html msg)
158 , topButton : Maybe (TopButton msg)
148 , topButton : Maybe (TopButton msg)
159 }
149 }
frontend/Pages/PasswordGenerator.elmdeleted−158
@@ -1,158 +0,0 @@
1−module Pages.PasswordGenerator exposing (Model, Msg, init, update, view)
2−
3−import Bridge
4−import Html exposing (..)
5−import Html.Attributes as Attr
6−import Html.Events as Ev
7−import Switch exposing (switch)
8−
9−
10−type Msg
11− = Noop
12− | UpdateNumberCount Int
13− | ToggleNumber Bool
14− | ToggleAmbiguousCharacters Bool
15− | ToggleCapitals Bool
16− | UpdateNumberOfCapitals Int
17− | UpdateLength Int
18− | ToggleSpecialCharacters Bool
19− | UpdateSpecialCharactersCount Int
20−
21−
22−type alias Model =
23− { passwordConfig : Bridge.PasswordGeneratorConfig
24− }
25−
26−
27−update : Msg -> Model -> Model
28−update msg { passwordConfig } =
29− case msg of
30− Noop ->
31− { passwordConfig = passwordConfig }
32−
33− UpdateNumberCount count ->
34− { passwordConfig = { passwordConfig | minNumber = count } }
35−
36− ToggleNumber enabled ->
37− { passwordConfig = { passwordConfig | includeNumber = enabled } }
38−
39− ToggleAmbiguousCharacters enabled ->
40− { passwordConfig = { passwordConfig | ambiguous = enabled } }
41−
42− ToggleCapitals enabled ->
43− { passwordConfig = { passwordConfig | capitalize = enabled } }
44−
45− UpdateNumberOfCapitals count ->
46− { passwordConfig = { passwordConfig | minUppercase = count } }
47−
48− UpdateLength count ->
49− { passwordConfig = { passwordConfig | length = count } }
50−
51− ToggleSpecialCharacters enabled ->
52− { passwordConfig = { passwordConfig | special = enabled } }
53−
54− UpdateSpecialCharactersCount count ->
55− { passwordConfig = { passwordConfig | minSpecial = count } }
56−
57−
58−init : Model
59−init =
60− { passwordConfig =
61− { ambiguous = True
62− , capitalize = True
63− , includeNumber = True
64− , length = 16
65− , lowercase = True
66− , minLowercase = 1
67− , minNumber = 1
68− , minSpecial = 1
69− , minUppercase = 1
70− , numWords = 1
71− , number = True
72− , special = True
73− , type_ = "password"
74− , uppercase = True
75− , wordSeparator = "-"
76− }
77− }
78−
79−
80−view : Model -> List (Html Msg)
81−view { passwordConfig } =
82− [ passwordGeneratorGroup
83− [ switch
84− { trigger = always Noop
85− , label = "Length"
86− , value = True
87− , hidden = True
88− }
89− , input
90− [ Attr.type_ "number"
91− , Attr.class "is-dense"
92− , Attr.value (String.fromInt passwordConfig.length)
93− , Ev.onInput (String.toInt >> Maybe.withDefault 1 >> UpdateLength)
94− , Attr.min "6"
95− ]
96− []
97− ]
98− , switchRow
99− { label = "Numbers"
100− , enabled = passwordConfig.includeNumber
101− , toggle = ToggleNumber
102− , trigger = UpdateNumberCount
103− , value = passwordConfig.minNumber
104− }
105− , switchRow
106− { label = "Uppercase Characters"
107− , enabled = passwordConfig.capitalize
108− , toggle = ToggleCapitals
109− , trigger = UpdateNumberOfCapitals
110− , value = passwordConfig.minUppercase
111− }
112− , switchRow
113− { label = "Special Characters"
114− , enabled = passwordConfig.special
115− , toggle = ToggleSpecialCharacters
116− , trigger = UpdateSpecialCharactersCount
117− , value = passwordConfig.minSpecial
118− }
119− , switch
120− { trigger = ToggleAmbiguousCharacters
121− , label = "Ambiguous Characters"
122− , value = passwordConfig.ambiguous
123− , hidden = False
124− }
125− ]
126−
127−
128−switchRow :
129− { toggle : Bool -> Msg
130− , label : String
131− , enabled : Bool
132− , value : Int
133− , trigger : Int -> Msg
134− }
135− -> Html Msg
136−switchRow { toggle, label, enabled, value, trigger } =
137− passwordGeneratorGroup
138− [ switch
139− { trigger = toggle
140− , label = label
141− , value = enabled
142− , hidden = False
143− }
144− , input
145− [ Attr.type_ "number"
146− , Attr.class "is-dense"
147− , Attr.value (String.fromInt value)
148− , Ev.onInput (String.toInt >> Maybe.withDefault 1 >> trigger)
149− , Attr.min "1"
150− , Attr.disabled (not enabled)
151− ]
152− []
153− ]
154−
155−
156−passwordGeneratorGroup : List (Html msg) -> Html msg
157−passwordGeneratorGroup =
158− div [ Attr.class "password-generator-group" ]
frontend/Pages/SecondFactor.elmdeleted−91
@@ -1,91 +0,0 @@
1−module Pages.SecondFactor exposing
2− ( Callbacks
3− , Model
4− , Msg
5− , init
6− , title
7− , update
8− , view
9− )
10−
11−import Bridge
12−import Html exposing (..)
13−import Html.Attributes as Attr
14−import Html.Events as Ev
15−import Logic.SecondFactor exposing (secondFactorName)
16−import Utils exposing (..)
17−
18−
19−type alias Callbacks msg =
20− { submit : { token : String, remember : Bool } -> msg
21− }
22−
23−
24−type Msg
25− = Submit
26− | UpdateValue String
27− | UpdateRemember Bool
28−
29−
30−type alias Model msg =
31− { token : String
32− , remember : Bool
33− , factorType : Bridge.TwoFactorProviderType
34− , callbacks : Callbacks msg
35− }
36−
37−
38−init :
39− { provider : Bridge.TwoFactorProviderType
40− , callbacks : Callbacks msg
41− }
42− -> Model msg
43−init { provider, callbacks } =
44− { token = ""
45− , remember = True
46− , factorType = provider
47− , callbacks = callbacks
48− }
49−
50−
51−title : Model msg -> String
52−title { factorType } =
53− secondFactorName factorType
54−
55−
56−update : Model emsg -> Msg -> ( Model emsg, Maybe emsg )
57−update model msg =
58− case msg of
59− Submit ->
60− ( model, model.callbacks.submit { token = model.token, remember = model.remember } |> Just )
61−
62− UpdateValue token ->
63− ( { model | token = token }, Nothing )
64−
65− UpdateRemember remember ->
66− ( { model | remember = remember }, Nothing )
67−
68−
69−view : Model emsg -> Html Msg
70−view { factorType, token, remember } =
71− form [ Ev.onSubmit Submit ]
72− [ label [] [ secondFactorName factorType ++ " code" |> text ]
73− , input
74− [ Attr.type_ "number"
75− , Attr.value token
76− , Attr.required True
77− , Ev.onInput UpdateValue
78− , Attr.attribute "autocomplete" "one-time-code"
79− ]
80− []
81− , label []
82− [ input
83− [ Attr.type_ "checkbox"
84− , Attr.checked remember
85− , Ev.onCheck UpdateRemember
86− ]
87− []
88− , text "Remember this device"
89− ]
90− , alignRight [ button [ Attr.type_ "submit" ] [ text "Submit" ] ]
91− ]
frontend/Pages/SecondFactorSelect.elmdeleted−164
@@ -1,164 +0,0 @@
1−module Pages.SecondFactorSelect exposing
2− ( Callbacks
3− , Model
4− , Msg
5− , init
6− , main
7− , title
8− , update
9− , view
10− )
11−
12−import Bridge
13−import Element as El
14−import Element.Font as Font
15−import Element.Input as Input
16−import Html
17−import Html.Attributes as Attr
18−import Logic.SecondFactor exposing (secondFactorName)
19−import Page exposing (..)
20−import Utils exposing (..)
21−
22−
23−main : Program () (Model (Maybe Msg)) (Maybe Msg)
24−main =
25− Page.page
26− { init =
27− init { selectFactor = always Nothing }
28− [ Bridge.Duo
29− , Bridge.Email
30− ]
31− , view = view
32− , update = update
33− }
34−
35−
36−type alias Model emsg =
37− { availableFactors : List Bridge.TwoFactorProviderType
38− , callbacks : Callbacks emsg
39− }
40−
41−
42−type Msg
43− = SelectFactor Bridge.TwoFactorProviderType
44−
45−
46−type alias Callbacks emsg =
47− { selectFactor : Bridge.TwoFactorProviderType -> emsg
48− }
49−
50−
51−title : String
52−title =
53− "Second factor"
54−
55−
56−init : Callbacks emsg -> List Bridge.TwoFactorProviderType -> Model emsg
57−init callbacks providers =
58− { availableFactors = providers
59− , callbacks = callbacks
60− }
61−
62−
63−update : Msg -> Model emsg -> ( Model emsg, Cmd emsg )
64−update msg model =
65− case msg of
66− SelectFactor factor ->
67− ( model, model.callbacks.selectFactor factor |> pureCmd )
68−
69−
70−view : Model emsg -> List (Html.Html Msg)
71−view { availableFactors } =
72− let
73− ( supportedProviders, unsupportedProviders ) =
74− List.partition providerIsSupported availableFactors
75− in
76− [ El.layout [ El.padding 8 ]
77− (El.column
78− [ El.width El.fill
79− , El.spacing 8
80− ]
81− ([ if List.isEmpty supportedProviders then
82− El.column []
83− [ El.paragraph []
84− [ El.text "Unfortunately, your account has no compatible 2FA providers."
85− ]
86− , El.el
87− [ El.height (El.px 16)
88− ]
89− El.none
90− ]
91−
92− else
93− El.column [ El.centerX ]
94− (supportedProviders
95− |> List.map
96− (\factor ->
97− Input.button [ El.centerX ]
98− { label =
99− Html.button [ Attr.class "p-button" ] [ secondFactorName factor |> Html.text ]
100− |> El.html
101− , onPress = SelectFactor factor |> Just
102− }
103− )
104− )
105− ]
106− ++ (if List.isEmpty unsupportedProviders |> not then
107− [ Html.div
108− [ Attr.class "p-notification--information"
109− ]
110− [ Html.div [ Attr.class "p-notification__content" ]
111− [ Html.h5 [ Attr.class "p-notification__title" ]
112− [ Html.text "The following 2FA providers are not supported"
113− ]
114− , Html.p [ Attr.class "notification__message" ]
115− [ Html.ul []
116− (List.map
117− (secondFactorName >> Html.text >> List.singleton >> Html.li [])
118− unsupportedProviders
119− )
120− ]
121− ]
122− ]
123− |> El.html
124− |> List.singleton
125− |> El.paragraph
126− [ Font.size 16
127− , El.width El.fill
128− ]
129− ]
130−
131− else
132− []
133− )
134− )
135− )
136− ]
137−
138−
139−providerIsSupported : Bridge.TwoFactorProviderType -> Bool
140−providerIsSupported provider =
141− case provider of
142− Bridge.Authenticator ->
143− True
144−
145− Bridge.Duo ->
146− False
147−
148− Bridge.Email ->
149− True
150−
151− Bridge.OrganizationDuo ->
152− False
153−
154− Bridge.Remember ->
155− False
156−
157− Bridge.U2f ->
158− False
159−
160− Bridge.WebAuthn ->
161− False
162−
163− Bridge.Yubikey ->
164− False
frontend/Switch.elmdeleted−35
@@ -1,35 +0,0 @@
1−module Switch exposing (..)
2−
3−import Html exposing (..)
4−import Html.Attributes as Attr
5−import Html.Events as Ev
6−import Utils exposing (..)
7−
8−
9−type alias SwitchConfig msg =
10− { trigger : Bool -> msg
11− , label : String
12− , value : Bool
13− , hidden : Bool
14− }
15−
16−
17−switch : SwitchConfig msg -> Html msg
18−switch cfg =
19− label
20− [ Attr.class "p-switch"
21− ]
22− [ input
23− [ Attr.type_ "checkbox"
24− , Attr.class "p-switch__input"
25− , Ev.onCheck cfg.trigger
26− , Attr.checked cfg.value
27− ]
28− []
29− , span
30− (Attr.class "p-switch__slider"
31− :: optional cfg.hidden (Attr.style "visibility" "hidden")
32− )
33− []
34− , span [ Attr.class "p-switch__label" ] [ text cfg.label ]
35− ]
frontend/Types.elmdeleted−5
@@ -1,5 +0,0 @@
1−module Types exposing (..)
2−
3−
4−type alias CipherId =
5− String
frontend/Utils.elm−65
@@ -2,7 +2,6 @@ module Utils exposing (..)
2
2
3import Html exposing (..)
3import Html exposing (..)
4import Html.Attributes as Attr
4import Html.Attributes as Attr
5−import Html.Events as Ev
6import Task
5import Task
7
6
8
7
@@ -87,67 +86,3 @@ tailEmpty x =
87unwords : List String -> String
86unwords : List String -> String
88unwords =
87unwords =
89 String.join " "
88 String.join " "
90−
91−
92−zip : List a -> List b -> List ( a, b )
93−zip =
94− List.map2 (\a b -> ( a, b ))
95−
96−
97−mapIndex : (a -> a) -> Int -> List a -> List a
98−mapIndex f i xs =
99− case ( i, xs ) of
100− ( _, [] ) ->
101− []
102−
103− ( 0, x :: xx ) ->
104− f x :: xx
105−
106− ( j, x :: xx ) ->
107− x :: mapIndex f (j - 1) xx
108−
109−
110−replace : Int -> a -> List a -> List a
111−replace i a xs =
112− case ( i, xs ) of
113− ( 0, _ :: xx ) ->
114− a :: xx
115−
116− ( j, x :: xx ) ->
117− x :: replace (j - 1) a xx
118−
119− ( _, [] ) ->
120− []
121−
122−
123−index : Int -> List a -> Maybe a
124−index i xs =
125− case ( i, xs ) of
126− ( 0, x :: _ ) ->
127− Just x
128−
129− ( j, _ :: xx ) ->
130− index (j - 1) xx
131−
132− ( _, [] ) ->
133− Nothing
134−
135−
136−spanList : (a -> Bool) -> List a -> ( List a, List a )
137−spanList f aa =
138− case aa of
139− [] ->
140− ( aa, aa )
141−
142− a :: rest ->
143− if f a then
144− spanList f rest |> Tuple.mapFirst ((::) a)
145−
146− else
147− ( [], aa )
148−
149−
150−iconButton : String -> msg -> Html msg
151−iconButton name msg =
152− button [ Attr.class "p-button is-inline is-dense has-icon", Ev.onClick msg ]
153− [ i [ Attr.class ("p-icon--" ++ name) ] [] ]
hcaptcha.html+1−11
@@ -16,18 +16,8 @@
16 console.log(token);
16 console.log(token);
17 window.parent.postMessage({ "hCaptchaToken": token }, "*");
17 window.parent.postMessage({ "hCaptchaToken": token }, "*");
18 }
18 }
19−
20− const sitekey = location.search.replace("?", "")
21− console.log(sitekey)
22−
23− const div = document.createElement("div");
24− div.setAttribute("class", "h-captcha");
25− div.setAttribute("data-sitekey", sitekey);
26− div.setAttribute("data-callback", "processSuccess");
27−
28− document.body.append(div)
29−
30 </script>
19 </script>
20+ <div class="h-captcha" data-sitekey="bc38c8a2-5311-4e8c-9dfc-49e99f6df417" data-callback="processSuccess"></div>
31</body>
21</body>
32
22
33</html>
23</html>
img/donate.pngdeleted

Binary file not shown.

index.html+2−2
@@ -5,9 +5,9 @@
5 <meta charset="UTF-8">
5 <meta charset="UTF-8">
6 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <meta http-equiv="X-UA-Compatible" content="IE=edge">
7 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
7 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
8− <link rel="stylesheet" href="vanilla/dist/style.css">
8+ <link rel="stylesheet" href="vanilla/style.css">
9 <link rel="stylesheet" href="style.css">
9 <link rel="stylesheet" href="style.css">
10− <title>Warden</title>
10+ <title>Test.</title>
11 <script src="elm.js"></script>
11 <script src="elm.js"></script>
12</head>
12</head>
13
13
manifest.json+6−6
@@ -1,15 +1,15 @@
1{
1{
2 "name": "soy.iko.warden",
2 "name": "soy.iko.warden",
3− "description": "A simple Bitwarden client",
3+ "description": "A simple bitwarden client",
4 "architecture": "@CLICK_ARCH@",
4 "architecture": "@CLICK_ARCH@",
5 "title": "Warden",
5 "title": "Warden",
6 "hooks": {
6 "hooks": {
7− "warden": {
7+ "appname": {
8− "apparmor": "warden.apparmor",
8+ "apparmor": "appname.apparmor",
9− "desktop": "warden.desktop"
9+ "desktop": "appname.desktop"
10 }
10 }
11 },
11 },
12− "version": "1.2.4",
12+ "version": "1.0.0",
13− "maintainer": "Ilia Kostiuchenko <mail@iko.soy>",
13+ "maintainer": "Ilia Kostiuchenko <email@iko.soy>",
14 "framework": "@CLICK_FRAMEWORK@"
14 "framework": "@CLICK_FRAMEWORK@"
15}
15}
package-lock.jsondeleted−959
@@ -1,959 +0,0 @@
1−{
2− "name": "warden",
3− "lockfileVersion": 3,
4− "requires": true,
5− "packages": {
6− "": {
7− "devDependencies": {
8− "cssnano": "^5.1.15"
9− }
10− },
11− "node_modules/@trysound/sax": {
12− "version": "0.2.0",
13− "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
14− "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
15− "dev": true,
16− "engines": {
17− "node": ">=10.13.0"
18− }
19− },
20− "node_modules/boolbase": {
21− "version": "1.0.0",
22− "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
23− "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
24− "dev": true
25− },
26− "node_modules/browserslist": {
27− "version": "4.21.5",
28− "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
29− "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
30− "dev": true,
31− "funding": [
32− {
33− "type": "opencollective",
34− "url": "https://opencollective.com/browserslist"
35− },
36− {
37− "type": "tidelift",
38− "url": "https://tidelift.com/funding/github/npm/browserslist"
39− }
40− ],
41− "dependencies": {
42− "caniuse-lite": "^1.0.30001449",
43− "electron-to-chromium": "^1.4.284",
44− "node-releases": "^2.0.8",
45− "update-browserslist-db": "^1.0.10"
46− },
47− "bin": {
48− "browserslist": "cli.js"
49− },
50− "engines": {
51− "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
52− }
53− },
54− "node_modules/caniuse-api": {
55− "version": "3.0.0",
56− "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
57− "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
58− "dev": true,
59− "dependencies": {
60− "browserslist": "^4.0.0",
61− "caniuse-lite": "^1.0.0",
62− "lodash.memoize": "^4.1.2",
63− "lodash.uniq": "^4.5.0"
64− }
65− },
66− "node_modules/caniuse-lite": {
67− "version": "1.0.30001457",
68− "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz",
69− "integrity": "sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==",
70− "dev": true,
71− "funding": [
72− {
73− "type": "opencollective",
74− "url": "https://opencollective.com/browserslist"
75− },
76− {
77− "type": "tidelift",
78− "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
79− }
80− ]
81− },
82− "node_modules/colord": {
83− "version": "2.9.3",
84− "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
85− "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
86− "dev": true
87− },
88− "node_modules/commander": {
89− "version": "7.2.0",
90− "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
91− "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
92− "dev": true,
93− "engines": {
94− "node": ">= 10"
95− }
96− },
97− "node_modules/css-declaration-sorter": {
98− "version": "6.3.1",
99− "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz",
100− "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==",
101− "dev": true,
102− "engines": {
103− "node": "^10 || ^12 || >=14"
104− },
105− "peerDependencies": {
106− "postcss": "^8.0.9"
107− }
108− },
109− "node_modules/css-select": {
110− "version": "4.3.0",
111− "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
112− "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
113− "dev": true,
114− "dependencies": {
115− "boolbase": "^1.0.0",
116− "css-what": "^6.0.1",
117− "domhandler": "^4.3.1",
118− "domutils": "^2.8.0",
119− "nth-check": "^2.0.1"
120− },
121− "funding": {
122− "url": "https://github.com/sponsors/fb55"
123− }
124− },
125− "node_modules/css-tree": {
126− "version": "1.1.3",
127− "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
128− "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
129− "dev": true,
130− "dependencies": {
131− "mdn-data": "2.0.14",
132− "source-map": "^0.6.1"
133− },
134− "engines": {
135− "node": ">=8.0.0"
136− }
137− },
138− "node_modules/css-what": {
139− "version": "6.1.0",
140− "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
141− "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
142− "dev": true,
143− "engines": {
144− "node": ">= 6"
145− },
146− "funding": {
147− "url": "https://github.com/sponsors/fb55"
148− }
149− },
150− "node_modules/cssesc": {
151− "version": "3.0.0",
152− "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
153− "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
154− "dev": true,
155− "bin": {
156− "cssesc": "bin/cssesc"
157− },
158− "engines": {
159− "node": ">=4"
160− }
161− },
162− "node_modules/cssnano": {
163− "version": "5.1.15",
164− "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz",
165− "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==",
166− "dev": true,
167− "dependencies": {
168− "cssnano-preset-default": "^5.2.14",
169− "lilconfig": "^2.0.3",
170− "yaml": "^1.10.2"
171− },
172− "engines": {
173− "node": "^10 || ^12 || >=14.0"
174− },
175− "funding": {
176− "type": "opencollective",
177− "url": "https://opencollective.com/cssnano"
178− },
179− "peerDependencies": {
180− "postcss": "^8.2.15"
181− }
182− },
183− "node_modules/cssnano-preset-default": {
184− "version": "5.2.14",
185− "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz",
186− "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==",
187− "dev": true,
188− "dependencies": {
189− "css-declaration-sorter": "^6.3.1",
190− "cssnano-utils": "^3.1.0",
191− "postcss-calc": "^8.2.3",
192− "postcss-colormin": "^5.3.1",
193− "postcss-convert-values": "^5.1.3",
194− "postcss-discard-comments": "^5.1.2",
195− "postcss-discard-duplicates": "^5.1.0",
196− "postcss-discard-empty": "^5.1.1",
197− "postcss-discard-overridden": "^5.1.0",
198− "postcss-merge-longhand": "^5.1.7",
199− "postcss-merge-rules": "^5.1.4",
200− "postcss-minify-font-values": "^5.1.0",
201− "postcss-minify-gradients": "^5.1.1",
202− "postcss-minify-params": "^5.1.4",
203− "postcss-minify-selectors": "^5.2.1",
204− "postcss-normalize-charset": "^5.1.0",
205− "postcss-normalize-display-values": "^5.1.0",
206− "postcss-normalize-positions": "^5.1.1",
207− "postcss-normalize-repeat-style": "^5.1.1",
208− "postcss-normalize-string": "^5.1.0",
209− "postcss-normalize-timing-functions": "^5.1.0",
210− "postcss-normalize-unicode": "^5.1.1",
211− "postcss-normalize-url": "^5.1.0",
212− "postcss-normalize-whitespace": "^5.1.1",
213− "postcss-ordered-values": "^5.1.3",
214− "postcss-reduce-initial": "^5.1.2",
215− "postcss-reduce-transforms": "^5.1.0",
216− "postcss-svgo": "^5.1.0",
217− "postcss-unique-selectors": "^5.1.1"
218− },
219− "engines": {
220− "node": "^10 || ^12 || >=14.0"
221− },
222− "peerDependencies": {
223− "postcss": "^8.2.15"
224− }
225− },
226− "node_modules/cssnano-utils": {
227− "version": "3.1.0",
228− "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
229− "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
230− "dev": true,
231− "engines": {
232− "node": "^10 || ^12 || >=14.0"
233− },
234− "peerDependencies": {
235− "postcss": "^8.2.15"
236− }
237− },
238− "node_modules/csso": {
239− "version": "4.2.0",
240− "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz",
241− "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
242− "dev": true,
243− "dependencies": {
244− "css-tree": "^1.1.2"
245− },
246− "engines": {
247− "node": ">=8.0.0"
248− }
249− },
250− "node_modules/dom-serializer": {
251− "version": "1.4.1",
252− "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
253− "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
254− "dev": true,
255− "dependencies": {
256− "domelementtype": "^2.0.1",
257− "domhandler": "^4.2.0",
258− "entities": "^2.0.0"
259− },
260− "funding": {
261− "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
262− }
263− },
264− "node_modules/domelementtype": {
265− "version": "2.3.0",
266− "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
267− "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
268− "dev": true,
269− "funding": [
270− {
271− "type": "github",
272− "url": "https://github.com/sponsors/fb55"
273− }
274− ]
275− },
276− "node_modules/domhandler": {
277− "version": "4.3.1",
278− "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
279− "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
280− "dev": true,
281− "dependencies": {
282− "domelementtype": "^2.2.0"
283− },
284− "engines": {
285− "node": ">= 4"
286− },
287− "funding": {
288− "url": "https://github.com/fb55/domhandler?sponsor=1"
289− }
290− },
291− "node_modules/domutils": {
292− "version": "2.8.0",
293− "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
294− "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
295− "dev": true,
296− "dependencies": {
297− "dom-serializer": "^1.0.1",
298− "domelementtype": "^2.2.0",
299− "domhandler": "^4.2.0"
300− },
301− "funding": {
302− "url": "https://github.com/fb55/domutils?sponsor=1"
303− }
304− },
305− "node_modules/electron-to-chromium": {
306− "version": "1.4.302",
307− "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.302.tgz",
308− "integrity": "sha512-Uk7C+7aPBryUR1Fwvk9VmipBcN9fVsqBO57jV2ZjTm+IZ6BMNqu7EDVEg2HxCNufk6QcWlFsBkhQyQroB2VWKw==",
309− "dev": true
310− },
311− "node_modules/entities": {
312− "version": "2.2.0",
313− "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
314− "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
315− "dev": true,
316− "funding": {
317− "url": "https://github.com/fb55/entities?sponsor=1"
318− }
319− },
320− "node_modules/escalade": {
321− "version": "3.1.1",
322− "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
323− "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
324− "dev": true,
325− "engines": {
326− "node": ">=6"
327− }
328− },
329− "node_modules/lilconfig": {
330− "version": "2.0.6",
331− "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz",
332− "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==",
333− "dev": true,
334− "engines": {
335− "node": ">=10"
336− }
337− },
338− "node_modules/lodash.memoize": {
339− "version": "4.1.2",
340− "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
341− "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
342− "dev": true
343− },
344− "node_modules/lodash.uniq": {
345− "version": "4.5.0",
346− "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
347− "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
348− "dev": true
349− },
350− "node_modules/mdn-data": {
351− "version": "2.0.14",
352− "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
353− "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
354− "dev": true
355− },
356− "node_modules/nanoid": {
357− "version": "3.3.4",
358− "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
359− "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
360− "dev": true,
361− "peer": true,
362− "bin": {
363− "nanoid": "bin/nanoid.cjs"
364− },
365− "engines": {
366− "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
367− }
368− },
369− "node_modules/node-releases": {
370− "version": "2.0.10",
371− "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
372− "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==",
373− "dev": true
374− },
375− "node_modules/normalize-url": {
376− "version": "6.1.0",
377− "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
378− "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
379− "dev": true,
380− "engines": {
381− "node": ">=10"
382− },
383− "funding": {
384− "url": "https://github.com/sponsors/sindresorhus"
385− }
386− },
387− "node_modules/nth-check": {
388− "version": "2.1.1",
389− "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
390− "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
391− "dev": true,
392− "dependencies": {
393− "boolbase": "^1.0.0"
394− },
395− "funding": {
396− "url": "https://github.com/fb55/nth-check?sponsor=1"
397− }
398− },
399− "node_modules/picocolors": {
400− "version": "1.0.0",
401− "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
402− "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
403− "dev": true
404− },
405− "node_modules/postcss": {
406− "version": "8.4.21",
407− "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
408− "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
409− "dev": true,
410− "funding": [
411− {
412− "type": "opencollective",
413− "url": "https://opencollective.com/postcss/"
414− },
415− {
416− "type": "tidelift",
417− "url": "https://tidelift.com/funding/github/npm/postcss"
418− }
419− ],
420− "peer": true,
421− "dependencies": {
422− "nanoid": "^3.3.4",
423− "picocolors": "^1.0.0",
424− "source-map-js": "^1.0.2"
425− },
426− "engines": {
427− "node": "^10 || ^12 || >=14"
428− }
429− },
430− "node_modules/postcss-calc": {
431− "version": "8.2.4",
432− "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz",
433− "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==",
434− "dev": true,
435− "dependencies": {
436− "postcss-selector-parser": "^6.0.9",
437− "postcss-value-parser": "^4.2.0"
438− },
439− "peerDependencies": {
440− "postcss": "^8.2.2"
441− }
442− },
443− "node_modules/postcss-colormin": {
444− "version": "5.3.1",
445− "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz",
446− "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==",
447− "dev": true,
448− "dependencies": {
449− "browserslist": "^4.21.4",
450− "caniuse-api": "^3.0.0",
451− "colord": "^2.9.1",
452− "postcss-value-parser": "^4.2.0"
453− },
454− "engines": {
455− "node": "^10 || ^12 || >=14.0"
456− },
457− "peerDependencies": {
458− "postcss": "^8.2.15"
459− }
460− },
461− "node_modules/postcss-convert-values": {
462− "version": "5.1.3",
463− "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz",
464− "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==",
465− "dev": true,
466− "dependencies": {
467− "browserslist": "^4.21.4",
468− "postcss-value-parser": "^4.2.0"
469− },
470− "engines": {
471− "node": "^10 || ^12 || >=14.0"
472− },
473− "peerDependencies": {
474− "postcss": "^8.2.15"
475− }
476− },
477− "node_modules/postcss-discard-comments": {
478− "version": "5.1.2",
479− "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz",
480− "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==",
481− "dev": true,
482− "engines": {
483− "node": "^10 || ^12 || >=14.0"
484− },
485− "peerDependencies": {
486− "postcss": "^8.2.15"
487− }
488− },
489− "node_modules/postcss-discard-duplicates": {
490− "version": "5.1.0",
491− "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz",
492− "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==",
493− "dev": true,
494− "engines": {
495− "node": "^10 || ^12 || >=14.0"
496− },
497− "peerDependencies": {
498− "postcss": "^8.2.15"
499− }
500− },
501− "node_modules/postcss-discard-empty": {
502− "version": "5.1.1",
503− "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz",
504− "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==",
505− "dev": true,
506− "engines": {
507− "node": "^10 || ^12 || >=14.0"
508− },
509− "peerDependencies": {
510− "postcss": "^8.2.15"
511− }
512− },
513− "node_modules/postcss-discard-overridden": {
514− "version": "5.1.0",
515− "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz",
516− "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==",
517− "dev": true,
518− "engines": {
519− "node": "^10 || ^12 || >=14.0"
520− },
521− "peerDependencies": {
522− "postcss": "^8.2.15"
523− }
524− },
525− "node_modules/postcss-merge-longhand": {
526− "version": "5.1.7",
527− "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz",
528− "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==",
529− "dev": true,
530− "dependencies": {
531− "postcss-value-parser": "^4.2.0",
532− "stylehacks": "^5.1.1"
533− },
534− "engines": {
535− "node": "^10 || ^12 || >=14.0"
536− },
537− "peerDependencies": {
538− "postcss": "^8.2.15"
539− }
540− },
541− "node_modules/postcss-merge-rules": {
542− "version": "5.1.4",
543− "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz",
544− "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==",
545− "dev": true,
546− "dependencies": {
547− "browserslist": "^4.21.4",
548− "caniuse-api": "^3.0.0",
549− "cssnano-utils": "^3.1.0",
550− "postcss-selector-parser": "^6.0.5"
551− },
552− "engines": {
553− "node": "^10 || ^12 || >=14.0"
554− },
555− "peerDependencies": {
556− "postcss": "^8.2.15"
557− }
558− },
559− "node_modules/postcss-minify-font-values": {
560− "version": "5.1.0",
561− "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz",
562− "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==",
563− "dev": true,
564− "dependencies": {
565− "postcss-value-parser": "^4.2.0"
566− },
567− "engines": {
568− "node": "^10 || ^12 || >=14.0"
569− },
570− "peerDependencies": {
571− "postcss": "^8.2.15"
572− }
573− },
574− "node_modules/postcss-minify-gradients": {
575− "version": "5.1.1",
576− "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz",
577− "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==",
578− "dev": true,
579− "dependencies": {
580− "colord": "^2.9.1",
581− "cssnano-utils": "^3.1.0",
582− "postcss-value-parser": "^4.2.0"
583− },
584− "engines": {
585− "node": "^10 || ^12 || >=14.0"
586− },
587− "peerDependencies": {
588− "postcss": "^8.2.15"
589− }
590− },
591− "node_modules/postcss-minify-params": {
592− "version": "5.1.4",
593− "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz",
594− "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==",
595− "dev": true,
596− "dependencies": {
597− "browserslist": "^4.21.4",
598− "cssnano-utils": "^3.1.0",
599− "postcss-value-parser": "^4.2.0"
600− },
601− "engines": {
602− "node": "^10 || ^12 || >=14.0"
603− },
604− "peerDependencies": {
605− "postcss": "^8.2.15"
606− }
607− },
608− "node_modules/postcss-minify-selectors": {
609− "version": "5.2.1",
610− "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz",
611− "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==",
612− "dev": true,
613− "dependencies": {
614− "postcss-selector-parser": "^6.0.5"
615− },
616− "engines": {
617− "node": "^10 || ^12 || >=14.0"
618− },
619− "peerDependencies": {
620− "postcss": "^8.2.15"
621− }
622− },
623− "node_modules/postcss-normalize-charset": {
624− "version": "5.1.0",
625− "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
626− "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==",
627− "dev": true,
628− "engines": {
629− "node": "^10 || ^12 || >=14.0"
630− },
631− "peerDependencies": {
632− "postcss": "^8.2.15"
633− }
634− },
635− "node_modules/postcss-normalize-display-values": {
636− "version": "5.1.0",
637− "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz",
638− "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==",
639− "dev": true,
640− "dependencies": {
641− "postcss-value-parser": "^4.2.0"
642− },
643− "engines": {
644− "node": "^10 || ^12 || >=14.0"
645− },
646− "peerDependencies": {
647− "postcss": "^8.2.15"
648− }
649− },
650− "node_modules/postcss-normalize-positions": {
651− "version": "5.1.1",
652− "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz",
653− "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==",
654− "dev": true,
655− "dependencies": {
656− "postcss-value-parser": "^4.2.0"
657− },
658− "engines": {
659− "node": "^10 || ^12 || >=14.0"
660− },
661− "peerDependencies": {
662− "postcss": "^8.2.15"
663− }
664− },
665− "node_modules/postcss-normalize-repeat-style": {
666− "version": "5.1.1",
667− "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz",
668− "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==",
669− "dev": true,
670− "dependencies": {
671− "postcss-value-parser": "^4.2.0"
672− },
673− "engines": {
674− "node": "^10 || ^12 || >=14.0"
675− },
676− "peerDependencies": {
677− "postcss": "^8.2.15"
678− }
679− },
680− "node_modules/postcss-normalize-string": {
681− "version": "5.1.0",
682− "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz",
683− "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==",
684− "dev": true,
685− "dependencies": {
686− "postcss-value-parser": "^4.2.0"
687− },
688− "engines": {
689− "node": "^10 || ^12 || >=14.0"
690− },
691− "peerDependencies": {
692− "postcss": "^8.2.15"
693− }
694− },
695− "node_modules/postcss-normalize-timing-functions": {
696− "version": "5.1.0",
697− "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz",
698− "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==",
699− "dev": true,
700− "dependencies": {
701− "postcss-value-parser": "^4.2.0"
702− },
703− "engines": {
704− "node": "^10 || ^12 || >=14.0"
705− },
706− "peerDependencies": {
707− "postcss": "^8.2.15"
708− }
709− },
710− "node_modules/postcss-normalize-unicode": {
711− "version": "5.1.1",
712− "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz",
713− "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==",
714− "dev": true,
715− "dependencies": {
716− "browserslist": "^4.21.4",
717− "postcss-value-parser": "^4.2.0"
718− },
719− "engines": {
720− "node": "^10 || ^12 || >=14.0"
721− },
722− "peerDependencies": {
723− "postcss": "^8.2.15"
724− }
725− },
726− "node_modules/postcss-normalize-url": {
727− "version": "5.1.0",
728− "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz",
729− "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==",
730− "dev": true,
731− "dependencies": {
732− "normalize-url": "^6.0.1",
733− "postcss-value-parser": "^4.2.0"
734− },
735− "engines": {
736− "node": "^10 || ^12 || >=14.0"
737− },
738− "peerDependencies": {
739− "postcss": "^8.2.15"
740− }
741− },
742− "node_modules/postcss-normalize-whitespace": {
743− "version": "5.1.1",
744− "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz",
745− "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==",
746− "dev": true,
747− "dependencies": {
748− "postcss-value-parser": "^4.2.0"
749− },
750− "engines": {
751− "node": "^10 || ^12 || >=14.0"
752− },
753− "peerDependencies": {
754− "postcss": "^8.2.15"
755− }
756− },
757− "node_modules/postcss-ordered-values": {
758− "version": "5.1.3",
759− "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz",
760− "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==",
761− "dev": true,
762− "dependencies": {
763− "cssnano-utils": "^3.1.0",
764− "postcss-value-parser": "^4.2.0"
765− },
766− "engines": {
767− "node": "^10 || ^12 || >=14.0"
768− },
769− "peerDependencies": {
770− "postcss": "^8.2.15"
771− }
772− },
773− "node_modules/postcss-reduce-initial": {
774− "version": "5.1.2",
775− "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz",
776− "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==",
777− "dev": true,
778− "dependencies": {
779− "browserslist": "^4.21.4",
780− "caniuse-api": "^3.0.0"
781− },
782− "engines": {
783− "node": "^10 || ^12 || >=14.0"
784− },
785− "peerDependencies": {
786− "postcss": "^8.2.15"
787− }
788− },
789− "node_modules/postcss-reduce-transforms": {
790− "version": "5.1.0",
791− "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz",
792− "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==",
793− "dev": true,
794− "dependencies": {
795− "postcss-value-parser": "^4.2.0"
796− },
797− "engines": {
798− "node": "^10 || ^12 || >=14.0"
799− },
800− "peerDependencies": {
801− "postcss": "^8.2.15"
802− }
803− },
804− "node_modules/postcss-selector-parser": {
805− "version": "6.0.11",
806− "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz",
807− "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==",
808− "dev": true,
809− "dependencies": {
810− "cssesc": "^3.0.0",
811− "util-deprecate": "^1.0.2"
812− },
813− "engines": {
814− "node": ">=4"
815− }
816− },
817− "node_modules/postcss-svgo": {
818− "version": "5.1.0",
819− "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz",
820− "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==",
821− "dev": true,
822− "dependencies": {
823− "postcss-value-parser": "^4.2.0",
824− "svgo": "^2.7.0"
825− },
826− "engines": {
827− "node": "^10 || ^12 || >=14.0"
828− },
829− "peerDependencies": {
830− "postcss": "^8.2.15"
831− }
832− },
833− "node_modules/postcss-unique-selectors": {
834− "version": "5.1.1",
835− "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz",
836− "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==",
837− "dev": true,
838− "dependencies": {
839− "postcss-selector-parser": "^6.0.5"
840− },
841− "engines": {
842− "node": "^10 || ^12 || >=14.0"
843− },
844− "peerDependencies": {
845− "postcss": "^8.2.15"
846− }
847− },
848− "node_modules/postcss-value-parser": {
849− "version": "4.2.0",
850− "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
851− "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
852− "dev": true
853− },
854− "node_modules/source-map": {
855− "version": "0.6.1",
856− "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
857− "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
858− "dev": true,
859− "engines": {
860− "node": ">=0.10.0"
861− }
862− },
863− "node_modules/source-map-js": {
864− "version": "1.0.2",
865− "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
866− "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
867− "dev": true,
868− "peer": true,
869− "engines": {
870− "node": ">=0.10.0"
871− }
872− },
873− "node_modules/stable": {
874− "version": "0.1.8",
875− "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
876− "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
877− "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility",
878− "dev": true
879− },
880− "node_modules/stylehacks": {
881− "version": "5.1.1",
882− "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz",
883− "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==",
884− "dev": true,
885− "dependencies": {
886− "browserslist": "^4.21.4",
887− "postcss-selector-parser": "^6.0.4"
888− },
889− "engines": {
890− "node": "^10 || ^12 || >=14.0"
891− },
892− "peerDependencies": {
893− "postcss": "^8.2.15"
894− }
895− },
896− "node_modules/svgo": {
897− "version": "2.8.0",
898− "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
899− "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==",
900− "dev": true,
901− "dependencies": {
902− "@trysound/sax": "0.2.0",
903− "commander": "^7.2.0",
904− "css-select": "^4.1.3",
905− "css-tree": "^1.1.3",
906− "csso": "^4.2.0",
907− "picocolors": "^1.0.0",
908− "stable": "^0.1.8"
909− },
910− "bin": {
911− "svgo": "bin/svgo"
912− },
913− "engines": {
914− "node": ">=10.13.0"
915− }
916− },
917− "node_modules/update-browserslist-db": {
918− "version": "1.0.10",
919− "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
920− "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
921− "dev": true,
922− "funding": [
923− {
924− "type": "opencollective",
925− "url": "https://opencollective.com/browserslist"
926− },
927− {
928− "type": "tidelift",
929− "url": "https://tidelift.com/funding/github/npm/browserslist"
930− }
931− ],
932− "dependencies": {
933− "escalade": "^3.1.1",
934− "picocolors": "^1.0.0"
935− },
936− "bin": {
937− "browserslist-lint": "cli.js"
938− },
939− "peerDependencies": {
940− "browserslist": ">= 4.21.0"
941− }
942− },
943− "node_modules/util-deprecate": {
944− "version": "1.0.2",
945− "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
946− "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
947− "dev": true
948− },
949− "node_modules/yaml": {
950− "version": "1.10.2",
951− "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
952− "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
953− "dev": true,
954− "engines": {
955− "node": ">= 6"
956− }
957− }
958− }
959−}
packages.dhall+6−20
@@ -99,10 +99,11 @@ in upstream
99-------------------------------
99-------------------------------
100-}
100-}
101let upstream =
101let upstream =
102− https://github.com/purescript/package-sets/releases/download/psc-0.15.4-20220808/packages.dhall
102+ https://github.com/purescript/package-sets/releases/download/psc-0.15.2-20220706/packages.dhall
103− sha256:60eee64b04ca0013fae3e02a69fc3b176105c6baa2f31865c67cd5f881a412fd
103+ sha256:7a24ebdbacb2bfa27b2fc6ce3da96f048093d64e54369965a2a7b5d9892b6031
104
104
105in upstream
105in upstream
106+ with el = ./el/spago.dhall as Location
106 with argonaut-aeson-generic =
107 with argonaut-aeson-generic =
107 { dependencies =
108 { dependencies =
108 [ "argonaut-codecs"
109 [ "argonaut-codecs"
@@ -125,7 +126,7 @@ in upstream
125 ]
126 ]
126 , repo =
127 , repo =
127 "https://github.com/ilyakooo0/purescript-argonaut-aeson-generic.git"
128 "https://github.com/ilyakooo0/purescript-argonaut-aeson-generic.git"
128− , version = "3e388500811ef4b6718fc776789f3be050ad7b57"
129+ , version = "purescript-0.14"
129 }
130 }
130 with untagged-union =
131 with untagged-union =
131 { dependencies =
132 { dependencies =
@@ -142,21 +143,6 @@ in upstream
142 , "tuples"
143 , "tuples"
143 , "unsafe-coerce"
144 , "unsafe-coerce"
144 ]
145 ]
145− , repo = "https://github.com/rowtype-yoga/purescript-untagged-union.git"
146+ , repo = "https://github.com/ilyakooo0/purescript-untagged-union.git"
146− , version = "6c5bccef38696a16e86ba9a65cf778b4462c4a66"
147+ , version = "ps-15"
147− }
148− with literals =
149− { repo = "https://github.com/ilyakooo0/purescript-literals.git"
150− , version = "6875fb28026595cfb780318305a77e79b098bb01"
151− , dependencies =
152− [ "assert"
153− , "effect"
154− , "integers"
155− , "maybe"
156− , "numbers"
157− , "partial"
158− , "prelude"
159− , "typelevel-prelude"
160− , "unsafe-coerce"
161− ]
162 }
148 }
registry.datdeleted

Binary file not shown.

scratchpad/password_generator.htmldeleted−74
@@ -1,74 +0,0 @@
1−<!DOCTYPE html>
2−<html lang="en">
3−
4−<head>
5− <meta charset="UTF-8">
6− <meta http-equiv="X-UA-Compatible" content="IE=edge">
7− <meta name="viewport" content="width=device-width, initial-scale=1.0">
8− <link rel="stylesheet" href="../vanilla/dist/style.css">
9− <link rel="stylesheet" href="../style.css">
10− <title>Password generator</title>
11−
12− <style>
13− body {
14− margin: 10px;
15− }
16−
17− </style>
18−
19−</head>
20−
21−<body>
22−
23− <div class="select-second-factor-container">
24− <button class="p-button">Hello</button>
25− <button class="p-button">Bar</button>
26− <button class="p-button">Bar</button>
27− <button class="p-button">Bardi</button>
28− <button class="p-button">Wolrd</button>
29− </div>
30−
31− <div class="password-generator-group">
32− <p>Password length</p>
33− <input type="number" class="p-slider__input">
34− </div>
35−
36−
37− <div class="password-generator-group">
38− <label class="p-switch">
39− <input type="checkbox" class="p-switch__input">
40− <span class="p-switch__slider"></span>
41− <span class="p-switch__label">Numbers</span>
42− </label>
43− <input type="number" class="p-slider__input">
44− </div>
45−
46− <form action="">
47− <label><input type="checkbox" name="" id="">Hahahah</label>
48− <input type="checkbox">
49−
50− </form>
51−
52−
53−
54− <input type="range" min="0" max="100" value="50" step="1">
55− <input type="range" min="0" max="100" value="50" step="1"
56− style="background-image: -webkit-gradient(linear, 0% 0%, 100% 0%, color-stop(0.5, rgb(0, 102, 204)), color-stop(0.5, rgb(217, 217, 217)));">
57− <h1>h</h1>
58− <div class="p-slider__wrapper">
59− <input type="range" min="0" max="100" value="50" step="1" id="slider4" disabled=""
60− aria-label="Example of a disabled slider, range 0 to 100">
61− <input class="p-slider__input" type="text" maxlength="3" id="slider4-input" disabled="" tabindex="0">
62− </div>
63− <div class="p-slider__wrapper">
64− <input type="range" min="0" max="100" value="50" step="1" id="slider3" aria-label="Example slider, range 0 to 100">
65− <input class="p-slider__input" type="number" maxlength="3" id="slider3-input" tabindex="0">
66− </div>
67−
68− <form>
69− <input type="range" min="0" max="100" value="50" step="1">
70− </form>
71−
72−</body>
73−
74−</html>
screenshots/1.pngdeleted

Binary file not shown.

screenshots/2.pngdeleted

Binary file not shown.

screenshots/3.pngdeleted

Binary file not shown.

screenshots/4.pngdeleted

Binary file not shown.

screenshots/5.pngdeleted

Binary file not shown.

spago-packages.nixdeleted−1102
@@ -1,1102 +0,0 @@
1−# This file was generated by Spago2Nix
2−
3−{ pkgs ? import <nixpkgs> {} }:
4−
5−let
6− inputs = {
7−
8− "aff" = pkgs.stdenv.mkDerivation {
9− name = "aff";
10− version = "v7.0.0";
11− src = pkgs.fetchgit {
12− url = "https://github.com/purescript-contrib/purescript-aff.git";
13− rev = "2d44d9f9d0d6a416a4103fba2fb39e5160f80e36";
14− sha256 = "1d38l16s8hvfqq5w40w21j5089svdiggkraw3rwrl6ml7lijjqx4";
15− };
16− phases = "installPhase";
17− installPhase = "ln -s $src $out";
18− };
19−
20− "aff-promise" = pkgs.stdenv.mkDerivation {
21− name = "aff-promise";
22− version = "v4.0.0";
23− src = pkgs.fetchgit {
24− url = "https://github.com/nwolverson/purescript-aff-promise.git";
25− rev = "3aa74e68e3e4c3e38d821375703e0b2f49d831eb";
26− sha256 = "10gv3b05dxnlmr9zmigqs1hz4xqrx7da30aqh12kqg3zrg49k9cc";
27− };
28− phases = "installPhase";
29− installPhase = "ln -s $src $out";
30− };
31−
32− "argonaut" = pkgs.stdenv.mkDerivation {
33− name = "argonaut";
34− version = "v9.0.0";
35− src = pkgs.fetchgit {
36− url = "https://github.com/purescript-contrib/purescript-argonaut.git";
37− rev = "7505a47f2edb0c9cacaac4f11dcedf4723a3e9c8";
38− sha256 = "18yxhlrwri6q858krz1klyq29fx8nvfm16c04wm2rn91mgyasn6x";
39− };
40− phases = "installPhase";
41− installPhase = "ln -s $src $out";
42− };
43−
44− "argonaut-aeson-generic" = pkgs.stdenv.mkDerivation {
45− name = "argonaut-aeson-generic";
46− version = "3e388500811ef4b6718fc776789f3be050ad7b57";
47− src = pkgs.fetchgit {
48− url = "https://github.com/ilyakooo0/purescript-argonaut-aeson-generic.git";
49− rev = "3e388500811ef4b6718fc776789f3be050ad7b57";
50− sha256 = "0yhcxxz5lpgwxxsx93kmr884rk5nrvgy7lmpaixazqps2a2q0fhc";
51− };
52− phases = "installPhase";
53− installPhase = "ln -s $src $out";
54− };
55−
56− "argonaut-codecs" = pkgs.stdenv.mkDerivation {
57− name = "argonaut-codecs";
58− version = "v9.0.0";
59− src = pkgs.fetchgit {
60− url = "https://github.com/purescript-contrib/purescript-argonaut-codecs.git";
61− rev = "176a5dddae28fda9a2ff31ed4bf1efcc148513a4";
62− sha256 = "08ys445222syysxh24la8bc8l20lwwqi4vdfa3ph2a60l1lx3kp8";
63− };
64− phases = "installPhase";
65− installPhase = "ln -s $src $out";
66− };
67−
68− "argonaut-core" = pkgs.stdenv.mkDerivation {
69− name = "argonaut-core";
70− version = "v7.0.0";
71− src = pkgs.fetchgit {
72− url = "https://github.com/purescript-contrib/purescript-argonaut-core.git";
73− rev = "68da81dd80ec36d3b013eff46dc067a972c22e5d";
74− sha256 = "0hxl17ddbflkk0hchjgk5xj6j9fwp3b182w4g073p0dwscdl4f08";
75− };
76− phases = "installPhase";
77− installPhase = "ln -s $src $out";
78− };
79−
80− "argonaut-generic" = pkgs.stdenv.mkDerivation {
81− name = "argonaut-generic";
82− version = "v8.0.0";
83− src = pkgs.fetchgit {
84− url = "https://github.com/purescript-contrib/purescript-argonaut-generic.git";
85− rev = "2df4080f036762df91a24b22842e389395ef0bdd";
86− sha256 = "0f3bkmv37nk89vscvivdr971sjydqiw7lwk9hfdfms05id8jdjkw";
87− };
88− phases = "installPhase";
89− installPhase = "ln -s $src $out";
90− };
91−
92− "argonaut-traversals" = pkgs.stdenv.mkDerivation {
93− name = "argonaut-traversals";
94− version = "v10.0.0";
95− src = pkgs.fetchgit {
96− url = "https://github.com/purescript-contrib/purescript-argonaut-traversals.git";
97− rev = "8d2403d8d57afb568933dbb36063d5670ce770a0";
98− sha256 = "0v965bcl1hdp1hacbzxcm35kxxclixj0kpsdm816gs7m548z6l43";
99− };
100− phases = "installPhase";
101− installPhase = "ln -s $src $out";
102− };
103−
104− "arraybuffer" = pkgs.stdenv.mkDerivation {
105− name = "arraybuffer";
106− version = "v13.0.0";
107− src = pkgs.fetchgit {
108− url = "https://github.com/purescript-contrib/purescript-arraybuffer.git";
109− rev = "3b5ba3040f060057e864805546a50f319853517d";
110− sha256 = "0cfi15r95zd7ikvs8v3pf2i3rzxjqxk7209j96d8qs6jzqlypbwd";
111− };
112− phases = "installPhase";
113− installPhase = "ln -s $src $out";
114− };
115−
116− "arraybuffer-types" = pkgs.stdenv.mkDerivation {
117− name = "arraybuffer-types";
118− version = "v3.0.2";
119− src = pkgs.fetchgit {
120− url = "https://github.com/purescript-contrib/purescript-arraybuffer-types.git";
121− rev = "9b0b7a0f9ee034e039f3d3a2a9c3f74eb7c9264a";
122− sha256 = "1q3111jk6jj64bxy86lc7ik6q5mgdz87bc086wj5rm57dmlivlxx";
123− };
124− phases = "installPhase";
125− installPhase = "ln -s $src $out";
126− };
127−
128− "arrays" = pkgs.stdenv.mkDerivation {
129− name = "arrays";
130− version = "v7.0.0";
131− src = pkgs.fetchgit {
132− url = "https://github.com/purescript/purescript-arrays.git";
133− rev = "d20bae2f76db6cf29b7b75e26e82b8a54c32295e";
134− sha256 = "1ciz796yrdfnqiskjjhh6r3bn9mks1dm5zin7kwzh1nfy1i4w9pz";
135− };
136− phases = "installPhase";
137− installPhase = "ln -s $src $out";
138− };
139−
140− "assert" = pkgs.stdenv.mkDerivation {
141− name = "assert";
142− version = "v6.0.0";
143− src = pkgs.fetchgit {
144− url = "https://github.com/purescript/purescript-assert.git";
145− rev = "27c0edb57d2ee497eb5fab664f5601c35b613eda";
146− sha256 = "02qpcsijil64qq4kcikv2ynxl85zkryvv0vmzjm6752956ymzi0j";
147− };
148− phases = "installPhase";
149− installPhase = "ln -s $src $out";
150− };
151−
152− "avar" = pkgs.stdenv.mkDerivation {
153− name = "avar";
154− version = "v5.0.0";
155− src = pkgs.fetchgit {
156− url = "https://github.com/purescript-contrib/purescript-avar.git";
157− rev = "d00f5784d9cc8f079babd62740f5c52b87e5caa5";
158− sha256 = "132g0ccmjr8328xpaycww8b5wmx1vi3li4irxxqcjk5wi47i8c9h";
159− };
160− phases = "installPhase";
161− installPhase = "ln -s $src $out";
162− };
163−
164− "bifunctors" = pkgs.stdenv.mkDerivation {
165− name = "bifunctors";
166− version = "v6.0.0";
167− src = pkgs.fetchgit {
168− url = "https://github.com/purescript/purescript-bifunctors.git";
169− rev = "16ba2fb6dd7f05528ebd9e2f9ca3a068b325e5b3";
170− sha256 = "1qz5aaiq5w4g1rhjb63z47h6nqhw8hw23x1zw5alam047pq4vfkg";
171− };
172− phases = "installPhase";
173− installPhase = "ln -s $src $out";
174− };
175−
176− "catenable-lists" = pkgs.stdenv.mkDerivation {
177− name = "catenable-lists";
178− version = "v7.0.0";
179− src = pkgs.fetchgit {
180− url = "https://github.com/purescript/purescript-catenable-lists.git";
181− rev = "09abe1f4888bc00841ad2b59e56a9e7ce7ebd4ab";
182− sha256 = "0fn6caspdnb0nrlj31sy7d5hxrhndfz7a2b9wfkxf5bv5vpjyawb";
183− };
184− phases = "installPhase";
185− installPhase = "ln -s $src $out";
186− };
187−
188− "console" = pkgs.stdenv.mkDerivation {
189− name = "console";
190− version = "v6.0.0";
191− src = pkgs.fetchgit {
192− url = "https://github.com/purescript/purescript-console.git";
193− rev = "3b83d7b792d03872afeea5e62b4f686ab0f09842";
194− sha256 = "0fr5l1myhscp910mybp04cg6g8f2hy3ikjfc8fkqlb2dm2cqzdfs";
195− };
196− phases = "installPhase";
197− installPhase = "ln -s $src $out";
198− };
199−
200− "const" = pkgs.stdenv.mkDerivation {
201− name = "const";
202− version = "v6.0.0";
203− src = pkgs.fetchgit {
204− url = "https://github.com/purescript/purescript-const.git";
205− rev = "ab9570cf2b6e67f7e441178211db1231cfd75c37";
206− sha256 = "0mcpwqqf5bcwxlzk53smvsjjz1ymlnq0ypphg6sc83ibw70g64f6";
207− };
208− phases = "installPhase";
209− installPhase = "ln -s $src $out";
210− };
211−
212− "contravariant" = pkgs.stdenv.mkDerivation {
213− name = "contravariant";
214− version = "v6.0.0";
215− src = pkgs.fetchgit {
216− url = "https://github.com/purescript/purescript-contravariant.git";
217− rev = "9ad3e105b8855bcc25f4e0893c784789d05a58de";
218− sha256 = "1xkd3rfs8v20w7mj6sj6dmhfb2vb1zpmjv245xj1rahk3g16qm7m";
219− };
220− phases = "installPhase";
221− installPhase = "ln -s $src $out";
222− };
223−
224− "control" = pkgs.stdenv.mkDerivation {
225− name = "control";
226− version = "v6.0.0";
227− src = pkgs.fetchgit {
228− url = "https://github.com/purescript/purescript-control.git";
229− rev = "a6033808790879a17b2729e73747a9ed3fb2264e";
230− sha256 = "05sdgywprwpav62d2bvlb80yd39brxhnmhhl1f116mm9hw5clqia";
231− };
232− phases = "installPhase";
233− installPhase = "ln -s $src $out";
234− };
235−
236− "datetime" = pkgs.stdenv.mkDerivation {
237− name = "datetime";
238− version = "v6.0.0";
239− src = pkgs.fetchgit {
240− url = "https://github.com/purescript/purescript-datetime.git";
241− rev = "a6a0cf1b0324964ad1854bc3377ed8766ba90e6f";
242− sha256 = "1idjljxy8rjlw3wiypk1c9cc1fc4g9kf7drzdy6a0yjdg7504gad";
243− };
244− phases = "installPhase";
245− installPhase = "ln -s $src $out";
246− };
247−
248− "datetime-parsing" = pkgs.stdenv.mkDerivation {
249− name = "datetime-parsing";
250− version = "v0.2.0";
251− src = pkgs.fetchgit {
252− url = "https://github.com/flounders/purescript-datetime-parsing.git";
253− rev = "aa7d336c2681501dbe343adcbbf8f2ee51b23932";
254− sha256 = "1w0lfs64qz1hs7zijyzpvqlp2z06wmbz4jp8cjsnw9yj46jsy8nh";
255− };
256− phases = "installPhase";
257− installPhase = "ln -s $src $out";
258− };
259−
260− "distributive" = pkgs.stdenv.mkDerivation {
261− name = "distributive";
262− version = "v6.0.0";
263− src = pkgs.fetchgit {
264− url = "https://github.com/purescript/purescript-distributive.git";
265− rev = "6005e513642e855ebf6f884d24a35c2803ca252a";
266− sha256 = "0x6cfsx9ff66kvw9l10pxd5vv16r91mmfxrfc68w1xfdfi81lhdx";
267− };
268− phases = "installPhase";
269− installPhase = "ln -s $src $out";
270− };
271−
272− "effect" = pkgs.stdenv.mkDerivation {
273− name = "effect";
274− version = "v4.0.0";
275− src = pkgs.fetchgit {
276− url = "https://github.com/purescript/purescript-effect.git";
277− rev = "a192ddb923027d426d6ea3d8deb030c9aa7c7dda";
278− sha256 = "0aa10lc6h9mlf4xf3g3ziig7v6kxdqvbh20kma8ay59w0b1bhmj1";
279− };
280− phases = "installPhase";
281− installPhase = "ln -s $src $out";
282− };
283−
284− "either" = pkgs.stdenv.mkDerivation {
285− name = "either";
286− version = "v6.1.0";
287− src = pkgs.fetchgit {
288− url = "https://github.com/purescript/purescript-either.git";
289− rev = "af655a04ed2fd694b6688af39ee20d7907ad0763";
290− sha256 = "05zps4klvgmvlm06f4hrycssm8q0pysbqnjsrk26lfvmid6mmg63";
291− };
292− phases = "installPhase";
293− installPhase = "ln -s $src $out";
294− };
295−
296− "enums" = pkgs.stdenv.mkDerivation {
297− name = "enums";
298− version = "v6.0.0";
299− src = pkgs.fetchgit {
300− url = "https://github.com/purescript/purescript-enums.git";
301− rev = "bae47961d401f9acf88da38f32e87403e5f0cf2f";
302− sha256 = "08sl5q07hv6v2008dcpg4mxiqwk9z0fhq67k0bgkxvlbsmar7khg";
303− };
304− phases = "installPhase";
305− installPhase = "ln -s $src $out";
306− };
307−
308− "exceptions" = pkgs.stdenv.mkDerivation {
309− name = "exceptions";
310− version = "v6.0.0";
311− src = pkgs.fetchgit {
312− url = "https://github.com/purescript/purescript-exceptions.git";
313− rev = "afab3c07c820bb49b6c5be50049db46a964a6161";
314− sha256 = "04xrbrcjwsv8gj465ygrlqhv1majxmr6m242iazg6apxlr89hgvg";
315− };
316− phases = "installPhase";
317− installPhase = "ln -s $src $out";
318− };
319−
320− "exists" = pkgs.stdenv.mkDerivation {
321− name = "exists";
322− version = "v6.0.0";
323− src = pkgs.fetchgit {
324− url = "https://github.com/purescript/purescript-exists.git";
325− rev = "f765b4ace7869c27b9c05949e18c843881f9173b";
326− sha256 = "0xnxi8fsmi15wrpq5d99gg94glk8a45hpx7pf4pmxg5r6rn1vjvx";
327− };
328− phases = "installPhase";
329− installPhase = "ln -s $src $out";
330− };
331−
332− "float32" = pkgs.stdenv.mkDerivation {
333− name = "float32";
334− version = "v2.0.0";
335− src = pkgs.fetchgit {
336− url = "https://github.com/purescript-contrib/purescript-float32.git";
337− rev = "3b70984d823c12c1b84a45a9b3d45199a4fcc67d";
338− sha256 = "0a1lvga6bbhbb8g3crp3fr0kmpkzjmffhfq71ig6flin13xijgys";
339− };
340− phases = "installPhase";
341− installPhase = "ln -s $src $out";
342− };
343−
344− "foldable-traversable" = pkgs.stdenv.mkDerivation {
345− name = "foldable-traversable";
346− version = "v6.0.0";
347− src = pkgs.fetchgit {
348− url = "https://github.com/purescript/purescript-foldable-traversable.git";
349− rev = "b3926f870532d287ea59e2d5cd3873b81ef2a93a";
350− sha256 = "0xg8qvyc6r9wqgy7wnw1rjqljl4wpgdrkxsm5x9rsagj2k5brxip";
351− };
352− phases = "installPhase";
353− installPhase = "ln -s $src $out";
354− };
355−
356− "foreign" = pkgs.stdenv.mkDerivation {
357− name = "foreign";
358− version = "v7.0.0";
359− src = pkgs.fetchgit {
360− url = "https://github.com/purescript/purescript-foreign.git";
361− rev = "2dd222d1ec7363fa0a0a7adb0d8eaf81bb7006dd";
362− sha256 = "0ycjaal8b2rsg3zl3b7acv166vjfdvziiza3fs8nhfw0rx0xmm1m";
363− };
364− phases = "installPhase";
365− installPhase = "ln -s $src $out";
366− };
367−
368− "foreign-object" = pkgs.stdenv.mkDerivation {
369− name = "foreign-object";
370− version = "v4.0.0";
371− src = pkgs.fetchgit {
372− url = "https://github.com/purescript/purescript-foreign-object.git";
373− rev = "28a635827a9a6c251df73f68874070d51fe9f756";
374− sha256 = "0ql0vgndcb5dqaqz81mvrqkrl5c2rlgxpydgdiiaxmmfxvxwi439";
375− };
376− phases = "installPhase";
377− installPhase = "ln -s $src $out";
378− };
379−
380− "free" = pkgs.stdenv.mkDerivation {
381− name = "free";
382− version = "v7.0.0";
383− src = pkgs.fetchgit {
384− url = "https://github.com/purescript/purescript-free.git";
385− rev = "e2d8fa8023a864363857834e11393483bced5e38";
386− sha256 = "0gyy0k297m26gw76w7kx8k1zjczlqbqb3nmh2h4gb3r84gl05g6r";
387− };
388− phases = "installPhase";
389− installPhase = "ln -s $src $out";
390− };
391−
392− "functions" = pkgs.stdenv.mkDerivation {
393− name = "functions";
394− version = "v6.0.0";
395− src = pkgs.fetchgit {
396− url = "https://github.com/purescript/purescript-functions.git";
397− rev = "f626f20580483977c5b27a01aac6471e28aff367";
398− sha256 = "1bsf2y8hx103a92yrc6m05q2dv51ckag1srd7q5n9vaf2k9byrj9";
399− };
400− phases = "installPhase";
401− installPhase = "ln -s $src $out";
402− };
403−
404− "functors" = pkgs.stdenv.mkDerivation {
405− name = "functors";
406− version = "v5.0.0";
407− src = pkgs.fetchgit {
408− url = "https://github.com/purescript/purescript-functors.git";
409− rev = "022ffd7a2a7ec12080314f3d217b400674a247b4";
410− sha256 = "1pnw3r1nk0rx8mrw3ajjml40zvx9v26qrqwj77pz7hpwxigxfbff";
411− };
412− phases = "installPhase";
413− installPhase = "ln -s $src $out";
414− };
415−
416− "gen" = pkgs.stdenv.mkDerivation {
417− name = "gen";
418− version = "v4.0.0";
419− src = pkgs.fetchgit {
420− url = "https://github.com/purescript/purescript-gen.git";
421− rev = "9fbcc2a1261c32e30d79c5418edef4d96fe76931";
422− sha256 = "0kajzcp9a8dmqvb3ga27hlf18m2smbp98a0bmzzb9vv156ckw0b4";
423− };
424− phases = "installPhase";
425− installPhase = "ln -s $src $out";
426− };
427−
428− "identity" = pkgs.stdenv.mkDerivation {
429− name = "identity";
430− version = "v6.0.0";
431− src = pkgs.fetchgit {
432− url = "https://github.com/purescript/purescript-identity.git";
433− rev = "ef6768f8a52ab0bc943a85f5761ba07c257f639f";
434− sha256 = "1lh0pkwwdyd8q9bgf4l1m96gdnardki4r2s359cnhrwp94b43fyr";
435− };
436− phases = "installPhase";
437− installPhase = "ln -s $src $out";
438− };
439−
440− "integers" = pkgs.stdenv.mkDerivation {
441− name = "integers";
442− version = "v6.0.0";
443− src = pkgs.fetchgit {
444− url = "https://github.com/purescript/purescript-integers.git";
445− rev = "54d712b25c594833083d15dc9ff2418eb9c52822";
446− sha256 = "04j9sqvkgyxxvbm8jfc2118wzmgswn8jva9fysgbsnmsg9vcxfm6";
447− };
448− phases = "installPhase";
449− installPhase = "ln -s $src $out";
450− };
451−
452− "invariant" = pkgs.stdenv.mkDerivation {
453− name = "invariant";
454− version = "v6.0.0";
455− src = pkgs.fetchgit {
456− url = "https://github.com/purescript/purescript-invariant.git";
457− rev = "1d2a196d51e90623adb88496c2cfd759c6736894";
458− sha256 = "07rqag47ykdiqc5yfbc1a64ijaqliljhcw1vgbv81m7ljzzd2xna";
459− };
460− phases = "installPhase";
461− installPhase = "ln -s $src $out";
462− };
463−
464− "js-date" = pkgs.stdenv.mkDerivation {
465− name = "js-date";
466− version = "v8.0.0";
467− src = pkgs.fetchgit {
468− url = "https://github.com/purescript-contrib/purescript-js-date.git";
469− rev = "1ea020316946cc4b87195bca9c54d0c16abaa490";
470− sha256 = "03535g8hc4bzyzig25hf75dls9ypsgrdk2nc45h8zw4xyy4ha0gz";
471− };
472− phases = "installPhase";
473− installPhase = "ln -s $src $out";
474− };
475−
476− "js-timers" = pkgs.stdenv.mkDerivation {
477− name = "js-timers";
478− version = "v6.1.0";
479− src = pkgs.fetchgit {
480− url = "https://github.com/purescript-contrib/purescript-js-timers.git";
481− rev = "7cb728b3e6dc29f355143617e6e9ac770ecd9273";
482− sha256 = "0dm933kqhwgmpkylgrlpjplidn8biic8jlzs4l4nny4a1z20mr61";
483− };
484− phases = "installPhase";
485− installPhase = "ln -s $src $out";
486− };
487−
488− "lazy" = pkgs.stdenv.mkDerivation {
489− name = "lazy";
490− version = "v6.0.0";
491− src = pkgs.fetchgit {
492− url = "https://github.com/purescript/purescript-lazy.git";
493− rev = "48347841226b27af5205a1a8ec71e27a93ce86fd";
494− sha256 = "0dxlc3b2bdqsri45i7a9bvwvv0gg43cc1gq61zi41f290a29ny2q";
495− };
496− phases = "installPhase";
497− installPhase = "ln -s $src $out";
498− };
499−
500− "lcg" = pkgs.stdenv.mkDerivation {
501− name = "lcg";
502− version = "v4.0.0";
503− src = pkgs.fetchgit {
504− url = "https://github.com/purescript/purescript-lcg.git";
505− rev = "67c6c6483a563a59ae036d9dca0f1be2835326a5";
506− sha256 = "1shzn6zvc1cxd7v0bvfsk7x3xf59vxby8c5lfjvd746r6396zn65";
507− };
508− phases = "installPhase";
509− installPhase = "ln -s $src $out";
510− };
511−
512− "lists" = pkgs.stdenv.mkDerivation {
513− name = "lists";
514− version = "v7.0.0";
515− src = pkgs.fetchgit {
516− url = "https://github.com/purescript/purescript-lists.git";
517− rev = "b113451e5b41cad87d669a3165f955c71cd863e2";
518− sha256 = "1mg7vy44k8jlqkri7x4ikciixx92b17wi35887x09dwdsicjf0sx";
519− };
520− phases = "installPhase";
521− installPhase = "ln -s $src $out";
522− };
523−
524− "literals" = pkgs.stdenv.mkDerivation {
525− name = "literals";
526− version = "6875fb28026595cfb780318305a77e79b098bb01";
527− src = pkgs.fetchgit {
528− url = "https://github.com/ilyakooo0/purescript-literals.git";
529− rev = "6875fb28026595cfb780318305a77e79b098bb01";
530− sha256 = "0s45cdgpdhni3rj7irr8pch46yxwmdcmj2nrg1vpkvygydkikdmb";
531− };
532− phases = "installPhase";
533− installPhase = "ln -s $src $out";
534− };
535−
536− "maybe" = pkgs.stdenv.mkDerivation {
537− name = "maybe";
538− version = "v6.0.0";
539− src = pkgs.fetchgit {
540− url = "https://github.com/purescript/purescript-maybe.git";
541− rev = "c6f98ac1088766287106c5d9c8e30e7648d36786";
542− sha256 = "0n33g8c579vcs06ii0r7f14jjdwzjw7p583w4nmrv9h442q2cvlz";
543− };
544− phases = "installPhase";
545− installPhase = "ln -s $src $out";
546− };
547−
548− "media-types" = pkgs.stdenv.mkDerivation {
549− name = "media-types";
550− version = "v6.0.0";
551− src = pkgs.fetchgit {
552− url = "https://github.com/purescript-contrib/purescript-media-types.git";
553− rev = "af853de226592f319a953637069a943dd261cba3";
554− sha256 = "0bxpsd2yw3zg58ay649v3xld7n17n7j7n9y8l841cjih9bc7ccxx";
555− };
556− phases = "installPhase";
557− installPhase = "ln -s $src $out";
558− };
559−
560− "newtype" = pkgs.stdenv.mkDerivation {
561− name = "newtype";
562− version = "v5.0.0";
563− src = pkgs.fetchgit {
564− url = "https://github.com/purescript/purescript-newtype.git";
565− rev = "29d8e6dd77aec2c975c948364ec3faf26e14ee7b";
566− sha256 = "0kfc644zn2f9rpx8fy4gjvmz04k9mv1c2xrqis8m3s0ydnhbffd7";
567− };
568− phases = "installPhase";
569− installPhase = "ln -s $src $out";
570− };
571−
572− "nonempty" = pkgs.stdenv.mkDerivation {
573− name = "nonempty";
574− version = "v7.0.0";
575− src = pkgs.fetchgit {
576− url = "https://github.com/purescript/purescript-nonempty.git";
577− rev = "28150ecc7419238b187abd609a92a645273348bb";
578− sha256 = "1mwdc2sny2ygp67kyk7h2493vq7syf7j18s3d9a5gwf1y7jlf7gh";
579− };
580− phases = "installPhase";
581− installPhase = "ln -s $src $out";
582− };
583−
584− "now" = pkgs.stdenv.mkDerivation {
585− name = "now";
586− version = "v6.0.0";
587− src = pkgs.fetchgit {
588− url = "https://github.com/purescript-contrib/purescript-now.git";
589− rev = "b5ffed2381e5fefc063f484e607e8499e79eaf32";
590− sha256 = "01khmqs4iz7dhlvd43zxj19q0c0vvqf1m128vgvgxz5mv430zfgr";
591− };
592− phases = "installPhase";
593− installPhase = "ln -s $src $out";
594− };
595−
596− "nullable" = pkgs.stdenv.mkDerivation {
597− name = "nullable";
598− version = "v6.0.0";
599− src = pkgs.fetchgit {
600− url = "https://github.com/purescript-contrib/purescript-nullable.git";
601− rev = "3202744c6c65e8d1fbba7f4256a1c482078e7fb5";
602− sha256 = "10s3b54pjmr2rxlyzvc8yc99k1dpn0qrijnc4y65yj5z6bxf2791";
603− };
604− phases = "installPhase";
605− installPhase = "ln -s $src $out";
606− };
607−
608− "numbers" = pkgs.stdenv.mkDerivation {
609− name = "numbers";
610− version = "v9.0.0";
611− src = pkgs.fetchgit {
612− url = "https://github.com/purescript/purescript-numbers.git";
613− rev = "2a53528f18f9415334bae28e7bb3cf3be86342c2";
614− sha256 = "1h4v6ir1hq6gvkk0kla38vlcd6bv73xkc8pv71jygwqxrdwfxxgw";
615− };
616− phases = "installPhase";
617− installPhase = "ln -s $src $out";
618− };
619−
620− "ordered-collections" = pkgs.stdenv.mkDerivation {
621− name = "ordered-collections";
622− version = "v3.0.0";
623− src = pkgs.fetchgit {
624− url = "https://github.com/purescript/purescript-ordered-collections.git";
625− rev = "9826b7632d0d0a691173bde308a634195f42a419";
626− sha256 = "1wk8mcn1zsxi0yk9ybas2v7m0drb492806gld1xxxic8x1i19ws0";
627− };
628− phases = "installPhase";
629− installPhase = "ln -s $src $out";
630− };
631−
632− "orders" = pkgs.stdenv.mkDerivation {
633− name = "orders";
634− version = "v6.0.0";
635− src = pkgs.fetchgit {
636− url = "https://github.com/purescript/purescript-orders.git";
637− rev = "f86db621ec5eef1274145f8b1fd8ebbfe0ed4a2c";
638− sha256 = "14fjls3v14ia6fr2w4p0i5dqv10zk343wg28m4c77a17jmvbs9r4";
639− };
640− phases = "installPhase";
641− installPhase = "ln -s $src $out";
642− };
643−
644− "parallel" = pkgs.stdenv.mkDerivation {
645− name = "parallel";
646− version = "v6.0.0";
647− src = pkgs.fetchgit {
648− url = "https://github.com/purescript/purescript-parallel.git";
649− rev = "85290dca837771ac4870071008c933d315ef678f";
650− sha256 = "0bpwvzq4dn7vx5mfj12w1zvvnamc6w2c45c2v54b9yw36snnwpcf";
651− };
652− phases = "installPhase";
653− installPhase = "ln -s $src $out";
654− };
655−
656− "parsing" = pkgs.stdenv.mkDerivation {
657− name = "parsing";
658− version = "v9.1.0";
659− src = pkgs.fetchgit {
660− url = "https://github.com/purescript-contrib/purescript-parsing.git";
661− rev = "44ef16b7cfb7cedc3d518c00ef10c6cb73ff4fc8";
662− sha256 = "1wkk3p1w2k1cvby4airyxgavk1djfzvzc2ch6b8951b592rj8lkr";
663− };
664− phases = "installPhase";
665− installPhase = "ln -s $src $out";
666− };
667−
668− "partial" = pkgs.stdenv.mkDerivation {
669− name = "partial";
670− version = "v4.0.0";
671− src = pkgs.fetchgit {
672− url = "https://github.com/purescript/purescript-partial.git";
673− rev = "0fa0646f5ea1ec5f0c46dcbd770c705a6c9ad3ec";
674− sha256 = "04s1h0r3slyd8kcamhqqrr6piksl9y76nmf2418j0ifhp16qwxmm";
675− };
676− phases = "installPhase";
677− installPhase = "ln -s $src $out";
678− };
679−
680− "prelude" = pkgs.stdenv.mkDerivation {
681− name = "prelude";
682− version = "v6.0.0";
683− src = pkgs.fetchgit {
684− url = "https://github.com/purescript/purescript-prelude.git";
685− rev = "32787f4399c92459c41602131a5858559eb868c5";
686− sha256 = "0jkbckxw2640gmfi2f8bpf2zwnay2dxy8n24rvxl3w3dihcgd9qc";
687− };
688− phases = "installPhase";
689− installPhase = "ln -s $src $out";
690− };
691−
692− "profunctor" = pkgs.stdenv.mkDerivation {
693− name = "profunctor";
694− version = "v6.0.0";
695− src = pkgs.fetchgit {
696− url = "https://github.com/purescript/purescript-profunctor.git";
697− rev = "0a966a14e7b0c827d44657dc1710cdc712d2e034";
698− sha256 = "07rhk8micbc74my6s53xbj2smvvwah2w1drqrcmcnncxdks3lqg3";
699− };
700− phases = "installPhase";
701− installPhase = "ln -s $src $out";
702− };
703−
704− "profunctor-lenses" = pkgs.stdenv.mkDerivation {
705− name = "profunctor-lenses";
706− version = "v8.0.0";
707− src = pkgs.fetchgit {
708− url = "https://github.com/purescript-contrib/purescript-profunctor-lenses.git";
709− rev = "973d567afe458fd802cf4f0d9725b6dc35ad9297";
710− sha256 = "0axz7nznn12iqh6sn9qjg6i8qglpdsqgkp30ndwdj98czcnbnybv";
711− };
712− phases = "installPhase";
713− installPhase = "ln -s $src $out";
714− };
715−
716− "psci-support" = pkgs.stdenv.mkDerivation {
717− name = "psci-support";
718− version = "v6.0.0";
719− src = pkgs.fetchgit {
720− url = "https://github.com/purescript/purescript-psci-support.git";
721− rev = "897cdb543548cb6078d69b6413b54841404eda72";
722− sha256 = "1ix53r8avkn3fw72mngwzw7v6c6mv7j4miw5mrgjrh9hb8p2ydl1";
723− };
724− phases = "installPhase";
725− installPhase = "ln -s $src $out";
726− };
727−
728− "quickcheck" = pkgs.stdenv.mkDerivation {
729− name = "quickcheck";
730− version = "v8.0.1";
731− src = pkgs.fetchgit {
732− url = "https://github.com/purescript/purescript-quickcheck.git";
733− rev = "bf5029f97e6c0d7552d3a08d2ab793a19e2c5e3d";
734− sha256 = "142dvh57fl8b6i7mm37a38v7vkc1znbqz6l6wqa704m53hkikvyd";
735− };
736− phases = "installPhase";
737− installPhase = "ln -s $src $out";
738− };
739−
740− "random" = pkgs.stdenv.mkDerivation {
741− name = "random";
742− version = "v6.0.0";
743− src = pkgs.fetchgit {
744− url = "https://github.com/purescript/purescript-random.git";
745− rev = "9540bc965a9596da02fefd9949418bb19c92533a";
746− sha256 = "0qz14qviz5053j9h1jwpk0gnn692hcdx6fp90wckzrnw31d53174";
747− };
748− phases = "installPhase";
749− installPhase = "ln -s $src $out";
750− };
751−
752− "record" = pkgs.stdenv.mkDerivation {
753− name = "record";
754− version = "v4.0.0";
755− src = pkgs.fetchgit {
756− url = "https://github.com/purescript/purescript-record.git";
757− rev = "c89cd1ada6b636692571fc374196b1c39c4c9f70";
758− sha256 = "1g7s2h1as5cz824wpm0jhjprrh66shha5i4gq37q73yw0s5p2ahm";
759− };
760− phases = "installPhase";
761− installPhase = "ln -s $src $out";
762− };
763−
764− "refs" = pkgs.stdenv.mkDerivation {
765− name = "refs";
766− version = "v6.0.0";
767− src = pkgs.fetchgit {
768− url = "https://github.com/purescript/purescript-refs.git";
769− rev = "f8e6216da4cb9309fde1f20cd6f69ac3a3b7f9e8";
770− sha256 = "09bvfxhjfwfwv55py45s71maazwrr68k0rk4v8ynfqv91h34319h";
771− };
772− phases = "installPhase";
773− installPhase = "ln -s $src $out";
774− };
775−
776− "run" = pkgs.stdenv.mkDerivation {
777− name = "run";
778− version = "v5.0.0";
779− src = pkgs.fetchgit {
780− url = "https://github.com/natefaubion/purescript-run.git";
781− rev = "abec7c343e92154d44b9dafd52b91ee82d32a870";
782− sha256 = "059xhjxjfs1w2hmgld53kciyfws3pmjyz75w836ph99rqr4aczny";
783− };
784− phases = "installPhase";
785− installPhase = "ln -s $src $out";
786− };
787−
788− "safe-coerce" = pkgs.stdenv.mkDerivation {
789− name = "safe-coerce";
790− version = "v2.0.0";
791− src = pkgs.fetchgit {
792− url = "https://github.com/purescript/purescript-safe-coerce.git";
793− rev = "7fa799ae80a38b8d948efcb52608e58e198b3da7";
794− sha256 = "00m4l733gpl0153cbl6n5kly7jr8ids399apza2rbczif40brp9g";
795− };
796− phases = "installPhase";
797− installPhase = "ln -s $src $out";
798− };
799−
800− "st" = pkgs.stdenv.mkDerivation {
801− name = "st";
802− version = "v6.0.0";
803− src = pkgs.fetchgit {
804− url = "https://github.com/purescript/purescript-st.git";
805− rev = "2cc7ae1c3318a303378c4a9f3fa0f10ee7cc3589";
806− sha256 = "1ykk27zn03svfsv2s1mf88d6x3q6qhb9bwjzgals79krw8w0aiyl";
807− };
808− phases = "installPhase";
809− installPhase = "ln -s $src $out";
810− };
811−
812− "strings" = pkgs.stdenv.mkDerivation {
813− name = "strings";
814− version = "v6.0.0";
815− src = pkgs.fetchgit {
816− url = "https://github.com/purescript/purescript-strings.git";
817− rev = "4bc6954448d056f8aa7a659695a6ad60ad4fdf19";
818− sha256 = "101va3rawcn5inp20krfg192bbjbvm27xfzwwc1inb2ya0m98amg";
819− };
820− phases = "installPhase";
821− installPhase = "ln -s $src $out";
822− };
823−
824− "tailrec" = pkgs.stdenv.mkDerivation {
825− name = "tailrec";
826− version = "v6.0.0";
827− src = pkgs.fetchgit {
828− url = "https://github.com/purescript/purescript-tailrec.git";
829− rev = "5e2104aa734b31a17074cc805bf087d72b65afd1";
830− sha256 = "0vc3dpsd2xxz694zlm75nx1cn6c6f29nzkb8xlxkk6ydw3wpsk3w";
831− };
832− phases = "installPhase";
833− installPhase = "ln -s $src $out";
834− };
835−
836− "test-unit" = pkgs.stdenv.mkDerivation {
837− name = "test-unit";
838− version = "v17.0.0";
839− src = pkgs.fetchgit {
840− url = "https://github.com/bodil/purescript-test-unit.git";
841− rev = "3112d7ebe06d467238058a6384dc75ffd960d335";
842− sha256 = "02gfb4dqbj5v7dwifm8jhr0lh7lfp5hari5795w1z48wy3apnvvx";
843− };
844− phases = "installPhase";
845− installPhase = "ln -s $src $out";
846− };
847−
848− "transformers" = pkgs.stdenv.mkDerivation {
849− name = "transformers";
850− version = "v6.0.0";
851− src = pkgs.fetchgit {
852− url = "https://github.com/purescript/purescript-transformers.git";
853− rev = "be72ab52357d9a665cbf93d73ba1c07c4b0957ee";
854− sha256 = "0ijrdsppl8vx0rlbwc9p0vjbmvwlcy4ia7xymvk6y34zbxzjlzm6";
855− };
856− phases = "installPhase";
857− installPhase = "ln -s $src $out";
858− };
859−
860− "tuples" = pkgs.stdenv.mkDerivation {
861− name = "tuples";
862− version = "v7.0.0";
863− src = pkgs.fetchgit {
864− url = "https://github.com/purescript/purescript-tuples.git";
865− rev = "4f52da2729b448c8564369378f1232d8d2dc1d8b";
866− sha256 = "1m1ng0xxicb73945jymcl1hn2y2hmynlnmhb2k0kkn1jrjwgcc3d";
867− };
868− phases = "installPhase";
869− installPhase = "ln -s $src $out";
870− };
871−
872− "type-equality" = pkgs.stdenv.mkDerivation {
873− name = "type-equality";
874− version = "v4.0.1";
875− src = pkgs.fetchgit {
876− url = "https://github.com/purescript/purescript-type-equality.git";
877− rev = "0525b7d39e0fbd81b4209518139fb8ab02695774";
878− sha256 = "1ass38jdycsjisdimdc4drg2w8vkkwp6lkvz3kvy7q0h98vdmlbr";
879− };
880− phases = "installPhase";
881− installPhase = "ln -s $src $out";
882− };
883−
884− "typelevel-prelude" = pkgs.stdenv.mkDerivation {
885− name = "typelevel-prelude";
886− version = "v7.0.0";
887− src = pkgs.fetchgit {
888− url = "https://github.com/purescript/purescript-typelevel-prelude.git";
889− rev = "dca2fe3c8cfd5527d4fe70c4bedfda30148405bf";
890− sha256 = "0x86mrg33kpnrnsfp4p3c92j5lpyqzy87bxdynwf7smk3inqr2jc";
891− };
892− phases = "installPhase";
893− installPhase = "ln -s $src $out";
894− };
895−
896− "uint" = pkgs.stdenv.mkDerivation {
897− name = "uint";
898− version = "v7.0.0";
899− src = pkgs.fetchgit {
900− url = "https://github.com/purescript-contrib/purescript-uint.git";
901− rev = "9e4f76ffd5192472f75583844172fe8ab3c0cb9f";
902− sha256 = "173bhrd006q53s7agwyasxhfbr89x9jpz5b47vm2fr74l3jcw3lq";
903− };
904− phases = "installPhase";
905− installPhase = "ln -s $src $out";
906− };
907−
908− "undefined-is-not-a-problem" = pkgs.stdenv.mkDerivation {
909− name = "undefined-is-not-a-problem";
910− version = "v1.1.0";
911− src = pkgs.fetchgit {
912− url = "https://github.com/paluh/purescript-undefined-is-not-a-problem.git";
913− rev = "8ac77ac8525343f7319cd48bf2ceb736286f3b27";
914− sha256 = "1qv7gdyslfj86ga0a7gxkbpvykm3s1x4kzcm8zi75lhlvkpyjh3w";
915− };
916− phases = "installPhase";
917− installPhase = "ln -s $src $out";
918− };
919−
920− "unfoldable" = pkgs.stdenv.mkDerivation {
921− name = "unfoldable";
922− version = "v6.0.0";
923− src = pkgs.fetchgit {
924− url = "https://github.com/purescript/purescript-unfoldable.git";
925− rev = "493dfe04ed590e20d8f69079df2f58486882748d";
926− sha256 = "15z2k639ph8wdkrc2y838m5am1z7szw2vqymmv021skzisyn7zwf";
927− };
928− phases = "installPhase";
929− installPhase = "ln -s $src $out";
930− };
931−
932− "unicode" = pkgs.stdenv.mkDerivation {
933− name = "unicode";
934− version = "v6.0.0";
935− src = pkgs.fetchgit {
936− url = "https://github.com/purescript-contrib/purescript-unicode.git";
937− rev = "6454d59d9e1fd1bc5a72e80e985d8282022a567a";
938− sha256 = "0w2gsmqcy7pj5vd22qzpig20bdgzmbagyqxrg9mm1njjfsmcm8cv";
939− };
940− phases = "installPhase";
941− installPhase = "ln -s $src $out";
942− };
943−
944− "unsafe-coerce" = pkgs.stdenv.mkDerivation {
945− name = "unsafe-coerce";
946− version = "v6.0.0";
947− src = pkgs.fetchgit {
948− url = "https://github.com/purescript/purescript-unsafe-coerce.git";
949− rev = "ab956f82e66e633f647fb3098e8ddd3ec58d689f";
950− sha256 = "0r6d3dx8jalfzvrvkagz9v05yxwkkhgbzlpswg4w1cyl03zjcla4";
951− };
952− phases = "installPhase";
953− installPhase = "ln -s $src $out";
954− };
955−
956− "untagged-union" = pkgs.stdenv.mkDerivation {
957− name = "untagged-union";
958− version = "6c5bccef38696a16e86ba9a65cf778b4462c4a66";
959− src = pkgs.fetchgit {
960− url = "https://github.com/rowtype-yoga/purescript-untagged-union.git";
961− rev = "6c5bccef38696a16e86ba9a65cf778b4462c4a66";
962− sha256 = "0s4pik6xcr7zqhlrjxjqgzp8hfg09kgd58zq3xjj0inw9ly35ywn";
963− };
964− phases = "installPhase";
965− installPhase = "ln -s $src $out";
966− };
967−
968− "variant" = pkgs.stdenv.mkDerivation {
969− name = "variant";
970− version = "v8.0.0";
971− src = pkgs.fetchgit {
972− url = "https://github.com/natefaubion/purescript-variant.git";
973− rev = "8b2bd73a4202257d80a955c4dd36f6055f149823";
974− sha256 = "18nyxnaqqg1zzydwd2hh9hbzr31j509g5yb1lnd0m60bma4l9h5g";
975− };
976− phases = "installPhase";
977− installPhase = "ln -s $src $out";
978− };
979−
980− "web-dom" = pkgs.stdenv.mkDerivation {
981− name = "web-dom";
982− version = "v6.0.0";
983− src = pkgs.fetchgit {
984− url = "https://github.com/purescript-web/purescript-web-dom.git";
985− rev = "568a1ee158b29e6e739e7a9aaed3e35ca4c4305a";
986− sha256 = "0angs86ld0h3ld889ag55lh62101dfn3fknyqrfv0imgn40vwm44";
987− };
988− phases = "installPhase";
989− installPhase = "ln -s $src $out";
990− };
991−
992− "web-events" = pkgs.stdenv.mkDerivation {
993− name = "web-events";
994− version = "v4.0.0";
995− src = pkgs.fetchgit {
996− url = "https://github.com/purescript-web/purescript-web-events.git";
997− rev = "2124356117be7b764a2f3948032255ac4dab7051";
998− sha256 = "0l47gsgj71x0gjbhjqwsar2y44ljhq3xa0nkgr1qvqxmcm00llqf";
999− };
1000− phases = "installPhase";
1001− installPhase = "ln -s $src $out";
1002− };
1003−
1004− "web-file" = pkgs.stdenv.mkDerivation {
1005− name = "web-file";
1006− version = "v4.0.0";
1007− src = pkgs.fetchgit {
1008− url = "https://github.com/purescript-web/purescript-web-file.git";
1009− rev = "023786ae62bbb8bf58156dd7f02011fa38221ef1";
1010− sha256 = "1wjf1m5y2qsba83is297icv9zyl7jilxdga0192mm1rp0j16jjln";
1011− };
1012− phases = "installPhase";
1013− installPhase = "ln -s $src $out";
1014− };
1015−
1016− "web-html" = pkgs.stdenv.mkDerivation {
1017− name = "web-html";
1018− version = "v4.0.0";
1019− src = pkgs.fetchgit {
1020− url = "https://github.com/purescript-web/purescript-web-html.git";
1021− rev = "be189cf91b9a19cf493637423522e2fe4a0088cc";
1022− sha256 = "0yspv6sci3mkflvqwf5jvz3a8nclmhbvazx9n34acyj3aai7k6bs";
1023− };
1024− phases = "installPhase";
1025− installPhase = "ln -s $src $out";
1026− };
1027−
1028− "web-storage" = pkgs.stdenv.mkDerivation {
1029− name = "web-storage";
1030− version = "v5.0.0";
1031− src = pkgs.fetchgit {
1032− url = "https://github.com/purescript-web/purescript-web-storage.git";
1033− rev = "6b74461e136755db70c271dc898d51776363d7e2";
1034− sha256 = "0q1grh8cp6h1szsqg3xmwlzrc1bbz8yzlwxlcl1iym5mjiyzgkcs";
1035− };
1036− phases = "installPhase";
1037− installPhase = "ln -s $src $out";
1038− };
1039−
1040− };
1041−
1042− cpPackage = pkg:
1043− let
1044− target = ".spago/${pkg.name}/${pkg.version}";
1045− in ''
1046− if [ ! -e ${target} ]; then
1047− echo "Installing ${target}."
1048− mkdir -p ${target}
1049− cp --no-preserve=mode,ownership,timestamp -r ${toString pkg.outPath}/* ${target}
1050− else
1051− echo "${target} already exists. Skipping."
1052− fi
1053− '';
1054−
1055− getGlob = pkg: ''".spago/${pkg.name}/${pkg.version}/src/**/*.purs"'';
1056−
1057− getStoreGlob = pkg: ''"${pkg.outPath}/src/**/*.purs"'';
1058−
1059−in {
1060− inherit inputs;
1061−
1062− installSpagoStyle = pkgs.writeShellScriptBin "install-spago-style" ''
1063− set -e
1064− echo installing dependencies...
1065− ${builtins.toString (builtins.map cpPackage (builtins.attrValues inputs))}
1066− echo "echo done."
1067− '';
1068−
1069− buildSpagoStyle = pkgs.writeShellScriptBin "build-spago-style" ''
1070− set -e
1071− echo building project...
1072− purs compile ${builtins.toString (builtins.map getGlob (builtins.attrValues inputs))} "$@"
1073− echo done.
1074− '';
1075−
1076− buildFromNixStore = pkgs.writeShellScriptBin "build-from-store" ''
1077− set -e
1078− echo building project using sources from nix store...
1079− purs compile ${builtins.toString (
1080− builtins.map getStoreGlob (builtins.attrValues inputs))} "$@"
1081− echo done.
1082− '';
1083−
1084− mkBuildProjectOutput =
1085− { src, purs }:
1086−
1087− pkgs.stdenv.mkDerivation {
1088− name = "build-project-output";
1089− src = src;
1090−
1091− buildInputs = [ purs ];
1092−
1093− installPhase = ''
1094− mkdir -p $out
1095− purs compile "$src/**/*.purs" ${builtins.toString
1096− (builtins.map
1097− (x: ''"${x.outPath}/src/**/*.purs"'')
1098− (builtins.attrValues inputs))}
1099− mv output $out
1100− '';
1101− };
1102−}
spago.dhall+1−7
@@ -26,27 +26,21 @@ to generate this file without the comments in this block.
26 , "datetime-parsing"
26 , "datetime-parsing"
27 , "effect"
27 , "effect"
28 , "either"
28 , "either"
29+ , "el"
29 , "exceptions"
30 , "exceptions"
30 , "foldable-traversable"
31 , "foldable-traversable"
31− , "foreign"
32 , "functions"
32 , "functions"
33− , "integers"
34− , "literals"
35 , "maybe"
33 , "maybe"
36 , "newtype"
34 , "newtype"
37 , "nullable"
35 , "nullable"
38− , "numbers"
39 , "orders"
36 , "orders"
40 , "prelude"
37 , "prelude"
41− , "random"
42 , "refs"
38 , "refs"
43− , "run"
44 , "strings"
39 , "strings"
45 , "transformers"
40 , "transformers"
46 , "tuples"
41 , "tuples"
47 , "typelevel-prelude"
42 , "typelevel-prelude"
48 , "undefined-is-not-a-problem"
43 , "undefined-is-not-a-problem"
49− , "untagged-union"
50 , "web-html"
44 , "web-html"
51 , "web-storage"
45 , "web-storage"
52 ]
46 ]
style.css+10−87
@@ -1,49 +1,32 @@
1+
1:root {
2:root {
2− --color-light: #f7f7f7;
3+ --color-light: #F7F7F7;
3}
4}
4
5
5main {
6main {
6 margin: 1rem;
7 margin: 1rem;
7}
8}
8
9
10+
9nav.p-tabs__list {
11nav.p-tabs__list {
10 top: 0;
12 top: 0;
11 position: sticky;
13 position: sticky;
12 background-color: white;
14 background-color: white;
13 padding-bottom: 1rem;
15 padding-bottom: 1rem;
14− padding-right: 1rem;
15 padding-bottom: 0;
16 padding-bottom: 0;
16 z-index: 10;
17 z-index: 10;
17}
18}
18
19
19−nav h3 {
20− width: 100%;
21−}
22−
23.ninety-counter {
20.ninety-counter {
24 transform: rotate(90deg);
21 transform: rotate(90deg);
25}
22}
26
23
27−@keyframes floating-notification-animation {
28− from {
29− transform: translateY(-60px);
30− opacity: 0;
31− }
32−
33− to {
34− transform: none;
35− opacity: 1;
36− }
37−}
38−
39.floating-notifications {
24.floating-notifications {
40 position: fixed;
25 position: fixed;
41 top: 1rem;
26 top: 1rem;
42 right: 1rem;
27 right: 1rem;
43 left: 1rem;
28 left: 1rem;
44 z-index: 9999;
29 z-index: 9999;
45− animation-duration: 0.5s;
46− animation-name: floating-notification-animation;
47}
30}
48
31
49.simple-flex-center {
32.simple-flex-center {
@@ -55,17 +38,17 @@ nav h3 {
55 align-content: center;
38 align-content: center;
56}
39}
57
40
58−.spinner {
41+.spinner{
59 padding: 1rem;
42 padding: 1rem;
60}
43}
61
44
62.cipher-row-container {
45.cipher-row-container {
63− display: flex;
46+ display: flex;
64− width: 100%;
47+ width: 100%;
65− align-items: baseline;
48+ align-items: baseline;
66− justify-content: space-between;
49+ justify-content: space-between;
67− flex-direction: row;
50+ flex-direction: row;
68− flex-wrap: wrap;
51+ flex-wrap: wrap;
69}
52}
70
53
71.cipher-row p {
54.cipher-row p {
@@ -89,63 +72,3 @@ p {
89.no-scroll-bar::-webkit-scrollbar {
72.no-scroll-bar::-webkit-scrollbar {
90 display: none;
73 display: none;
91}
74}
92−
93−textarea {
94− resize: none;
95−}
96−
97−.password-generator-group {
98− display: flex;
99− flex-direction: row;
100− align-items: baseline;
101− justify-content: space-between;
102−}
103−
104−.password-generator-group > input[type="number"] {
105− width: 5%;
106− margin-bottom: 0px;
107− min-width: 5rem;
108− text-align: center;
109−}
110−
111−.p-side-navigation__drawer {
112− max-width: initial;
113−}
114−
115−.select-cipher-type-container {
116− display: flex;
117− flex-direction: column;
118− align-items: center;
119− justify-content: center;
120−}
121−
122−.select-cipher-type-container > * {
123− margin: 0px;
124− margin-bottom: 1.5rem;
125−}
126−
127−.overlay {
128− position: fixed;
129− top: 0;
130− left: 0;
131− right: 0;
132− bottom: 0;
133−}
134−
135−.select-second-factor-container {
136− display: flex;
137− flex-direction: column;
138− align-items: center;
139− justify-content: center;
140−}
141−
142−.p-tabs__list {
143− overflow: initial;
144−}
145−
146−.p-modal {
147− top: 0;
148− left: 0;
149− right: 0;
150− bottom: 0;
151−}
tests/package-lock.jsondeleted−73
@@ -1,73 +0,0 @@
1−{
2− "name": "warden-tests",
3− "version": "1.0.0",
4− "lockfileVersion": 2,
5− "requires": true,
6− "packages": {
7− "": {
8− "name": "warden-tests",
9− "version": "1.0.0",
10− "devDependencies": {
11− "@playwright/test": "^1.27.1"
12− }
13− },
14− "node_modules/@playwright/test": {
15− "version": "1.27.1",
16− "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.27.1.tgz",
17− "integrity": "sha512-mrL2q0an/7tVqniQQF6RBL2saskjljXzqNcCOVMUjRIgE6Y38nCNaP+Dc2FBW06bcpD3tqIws/HT9qiMHbNU0A==",
18− "dev": true,
19− "dependencies": {
20− "@types/node": "*",
21− "playwright-core": "1.27.1"
22− },
23− "bin": {
24− "playwright": "cli.js"
25− },
26− "engines": {
27− "node": ">=14"
28− }
29− },
30− "node_modules/@types/node": {
31− "version": "18.11.9",
32− "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
33− "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
34− "dev": true
35− },
36− "node_modules/playwright-core": {
37− "version": "1.27.1",
38− "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.27.1.tgz",
39− "integrity": "sha512-9EmeXDncC2Pmp/z+teoVYlvmPWUC6ejSSYZUln7YaP89Z6lpAaiaAnqroUt/BoLo8tn7WYShcfaCh+xofZa44Q==",
40− "dev": true,
41− "bin": {
42− "playwright": "cli.js"
43− },
44− "engines": {
45− "node": ">=14"
46− }
47− }
48− },
49− "dependencies": {
50− "@playwright/test": {
51− "version": "1.27.1",
52− "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.27.1.tgz",
53− "integrity": "sha512-mrL2q0an/7tVqniQQF6RBL2saskjljXzqNcCOVMUjRIgE6Y38nCNaP+Dc2FBW06bcpD3tqIws/HT9qiMHbNU0A==",
54− "dev": true,
55− "requires": {
56− "@types/node": "*",
57− "playwright-core": "1.27.1"
58− }
59− },
60− "@types/node": {
61− "version": "18.11.9",
62− "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
63− "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
64− "dev": true
65− },
66− "playwright-core": {
67− "version": "1.27.1",
68− "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.27.1.tgz",
69− "integrity": "sha512-9EmeXDncC2Pmp/z+teoVYlvmPWUC6ejSSYZUln7YaP89Z6lpAaiaAnqroUt/BoLo8tn7WYShcfaCh+xofZa44Q==",
70− "dev": true
71− }
72− }
73−}
tests/package.jsondeleted−9
@@ -1,9 +0,0 @@
1−{
2− "name": "warden-tests",
3− "version": "1.0.0",
4− "scripts": {},
5− "keywords": [],
6− "devDependencies": {
7− "@playwright/test": "^1.27.1"
8− }
9−}
tests/playwright.config.tsdeleted−65
@@ -1,65 +0,0 @@
1−import type { PlaywrightTestConfig } from '@playwright/test';
2−import { devices } from '@playwright/test';
3−
4−/**
5− * See https://playwright.dev/docs/test-configuration.
6− */
7−const config: PlaywrightTestConfig = {
8− testDir: './src',
9− /* Maximum time one test can run for. */
10− timeout: 30 * 1000,
11− expect: {
12− /**
13− * Maximum time expect() should wait for the condition to be met.
14− * For example in `await expect(locator).toHaveText();`
15− */
16− timeout: 5000
17− },
18− /* Run tests in files in parallel */
19− fullyParallel: false,
20− /* Fail the build on CI if you accidentally left test.only in the source code. */
21− forbidOnly: !!process.env.CI,
22− /* Retry on CI only */
23− retries: 0,
24− /* Opt out of parallel tests on CI. */
25− workers: 1,
26− /* Reporter to use. See https://playwright.dev/docs/test-reporters */
27− reporter: 'html',
28− /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
29− use: {
30− /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
31− actionTimeout: 0,
32− /* Base URL to use in actions like `await page.goto('/')`. */
33− // baseURL: 'http://localhost:3000',
34−
35− /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
36− trace: 'on-first-retry',
37− },
38−
39− /* Configure projects for major browsers */
40− projects: [
41− {
42− name: 'Pixel 3',
43− use: {
44− ...devices['Pixel 3'],
45− launchOptions: {
46− args: ["--disable-web-security"],
47− },
48− headless: process.env.RECORD_TEST !== "true",
49− }
50− },
51−
52− ],
53−
54− /* Folder for test artifacts such as screenshots, videos, traces, etc. */
55− outputDir: 'test-results/',
56−
57− /* Run your local dev server before starting the tests */
58− webServer: {
59− command: './vaultwarden/run.sh',
60− port: 8000,
61− },
62−
63−};
64−
65−export default config;
tests/src/test.spec.tsdeleted−257
@@ -1,257 +0,0 @@
1−import { test, expect, Page } from '@playwright/test';
2−
3−async function logIn(page: Page) {
4− await page.locator('input[type="url"]').tap();
5− await page.locator('input[type="url"]').press('Control+a');
6− await page.locator('input[type="url"]').fill('http://localhost:8000');
7− await page.locator('input[type="email"]').tap();
8− await page.locator('input[type="email"]').fill('test@example.com');
9− await page.locator('input[type="password"]').tap();
10− await page.locator('input[type="password"]').fill('Password123');
11− await page.getByRole('button', { name: 'Log in' }).tap();
12− await page.locator('.p-icon--spinner.u-animation--spin.spinner').waitFor({ state: "visible" })
13− await page.locator('.p-icon--spinner.u-animation--spin.spinner').waitFor({ state: "hidden" })
14−}
15−
16−async function fillInLoginCipher(page: Page) {
17− await page.locator('p:has-text("Entry name") input[type="text"]').tap();
18− await page.locator('p:has-text("Entry name") input[type="text"]').fill('Test login entry');
19− await page.locator('p:has-text("Username") input[type="text"]').tap();
20− await page.locator('p:has-text("Username") input[type="text"]').fill('login_entry_username');
21− await page.locator('input[type="text"]').nth(2).tap();
22− await page.locator('input[type="text"]').nth(2).fill('Password123');
23− await page.locator('input[type="url"]').tap();
24− await page.locator('input[type="url"]').fill('https://example.com');
25−}
26−
27−async function fillInCardCipher(page: Page) {
28− await page.locator('p:has-text("Entry name") input[type="text"]').tap();
29− await page.locator('p:has-text("Entry name") input[type="text"]').fill('Test card');
30− await page.locator('p:has-text("Card number") input[type="text"]').tap();
31− await page.locator('p:has-text("Card number") input[type="text"]').fill('1234567890123456');
32− await page.locator('p:has-text("Expiration date /") input[type="text"]').first().tap();
33− await page.locator('p:has-text("Expiration date /") input[type="text"]').first().fill('01');
34− await page.locator('p:has-text("Expiration date /") input[type="text"]').nth(1).tap();
35− await page.locator('p:has-text("Expiration date /") input[type="text"]').nth(1).fill('01');
36− await page.locator('p:has-text("CVV") input[type="text"]').tap();
37− await page.locator('p:has-text("CVV") input[type="text"]').fill('123');
38− await page.locator('p:has-text("Cardholder name") input[type="text"]').tap();
39− await page.locator('p:has-text("Cardholder name") input[type="text"]').fill('Sampel Palnet');
40−}
41−
42−async function fillInNoteCipher(page: Page) {
43− await page.locator('input[type="text"]').tap();
44− await page.locator('input[type="text"]').fill('Secret note');
45− await page.locator('textarea').tap();
46− await page.locator('textarea').fill('This is a very secret note');
47−}
48−
49−async function fillInContractCipher(page: Page) {
50− await page.locator('p:has-text("Entry name") input[type="text"]').tap();
51− await page.locator('p:has-text("Entry name") input[type="text"]').fill('John Appleseed');
52− await page.locator('p:has-text("First name") input[type="text"]').tap();
53− await page.locator('p:has-text("First name") input[type="text"]').fill('John');
54− await page.locator('p:has-text("Middle name") input[type="text"]').tap();
55− await page.locator('p:has-text("Middle name") input[type="text"]').fill('Mathews');
56− await page.locator('p:has-text("Last name") input[type="text"]').tap();
57− await page.locator('p:has-text("Last name") input[type="text"]').fill('Appleseed');
58− await page.locator('p:has-text("Username") input[type="text"]').tap();
59− await page.locator('p:has-text("Username") input[type="text"]').fill('jappleseed');
60− await page.locator('p:has-text("Company") input[type="text"]').tap();
61− await page.locator('p:has-text("Company") input[type="text"]').fill('Very good building company');
62− await page.locator('p:has-text("Social security number") input[type="number"]').tap();
63− await page.locator('p:has-text("Social security number") input[type="number"]').fill('123456789');
64− await page.locator('p:has-text("Passport number") input[type="number"]').tap();
65− await page.locator('p:has-text("Passport number") input[type="number"]').fill('123456798');
66− await page.locator('p:has-text("License Number") input[type="number"]').tap();
67− await page.locator('p:has-text("License Number") input[type="number"]').fill('12345');
68− await page.locator('input[type="email"]').tap();
69− await page.locator('input[type="email"]').fill('john@example.com');
70− await page.locator('input[type="tel"]').tap();
71− await page.locator('input[type="tel"]').fill('123456789');
72− await page.locator('p:has-text("Address line 1") input[type="text"]').tap();
73− await page.locator('p:has-text("Address line 1") input[type="text"]').fill('Abc def');
74− await page.locator('p:has-text("Address line 2") input[type="text"]').tap();
75− await page.locator('p:has-text("Address line 2") input[type="text"]').fill('Ghijk Lmn');
76−}
77−
78−async function screenshot(page: Page) {
79− await page.waitForLoadState("networkidle")
80−
81− if (await page.locator('div.floating-notifications').isVisible()) {
82− await page.locator("button.p-notification__close").tap()
83− await screenshot(page)
84− } else if (await page.locator('.p-icon--spinner.u-animation--spin.spinner').isVisible()) {
85− await page.locator('.p-icon--spinner.u-animation--spin.spinner').waitFor({ state: "hidden" })
86− await screenshot(page)
87− } else {
88− await expect.soft(page).toHaveScreenshot({ animations: "disabled", fullPage: true, maxDiffPixelRatio: 0.01 })
89− }
90−}
91−
92−async function waitForNotification(page: Page) {
93− await page.locator('div.floating-notifications').waitFor({ state: "visible" })
94−}
95−
96−
97−/**
98− * Screenshots the very first (last edited) entry.
99− */
100−function cipherPage(name: string) {
101− test(name + " cipher page", async ({ page }) => {
102− await logIn(page)
103−
104− await page.locator('.cipher-row').first().tap()
105−
106− await screenshot(page)
107− })
108−}
109−
110−test.beforeEach(async ({ page }) => {
111− await page.goto(`file://${__dirname}/../../dist/index.html`);
112− await page.addStyleTag({ content: '.hide-in-test {opacity: 0;}' })
113−})
114−
115−if (process.env.RECORD_TEST === "true") {
116−
117− test('record', async ({ page }) => {
118− await logIn(page)
119− await page.pause()
120− })
121−
122−} else {
123− test('Login page', async ({ page }) => {
124− await screenshot(page)
125− });
126−
127− test('Empty ciphers page', async ({ page }) => {
128− await logIn(page)
129−
130− await screenshot(page)
131− })
132−
133− test('Login entry page', async ({ page }) => {
134− await logIn(page)
135−
136− await page.getByRole('button').nth(2).tap();
137− await page.getByRole('button', { name: 'Login' }).tap();
138−
139− await screenshot(page)
140−
141− await fillInLoginCipher(page)
142−
143− await screenshot(page)
144−
145− await page.getByRole('heading').locator('span').getByRole('button').tap();
146−
147− await waitForNotification(page)
148− });
149−
150− cipherPage("Login")
151−
152− test('Create Card entry page', async ({ page }) => {
153− await logIn(page)
154−
155− await page.getByRole('button').nth(2).tap();
156− await page.getByRole('button', { name: 'Card' }).tap();
157−
158− await screenshot(page)
159−
160− await fillInCardCipher(page)
161−
162− await screenshot(page)
163−
164− await page.getByRole('heading').locator('span').getByRole('button').tap();
165−
166− await waitForNotification(page)
167− })
168−
169− cipherPage("Card")
170−
171− test('Create Note entry page', async ({ page }) => {
172− await logIn(page)
173−
174− await page.getByRole('button').nth(2).tap();
175− await page.getByRole('button', { name: 'Note' }).tap();
176−
177− await screenshot(page)
178−
179− await fillInNoteCipher(page)
180−
181− await screenshot(page)
182−
183− await page.getByRole('heading').locator('span').getByRole('button').tap();
184−
185− await waitForNotification(page)
186− })
187−
188− cipherPage("Note")
189−
190− test('Create Contact entry page', async ({ page }) => {
191− await logIn(page)
192−
193− await page.getByRole('button').nth(2).tap();
194− await page.getByRole('button', { name: 'Contact' }).tap();
195−
196− await screenshot(page)
197−
198− await fillInContractCipher(page)
199−
200− await screenshot(page)
201−
202− await page.getByRole('heading').locator('span').getByRole('button').tap();
203−
204− await waitForNotification(page)
205− })
206−
207− cipherPage("Contact")
208−
209− test('Filled ciphers page', async ({ page }) => {
210− await logIn(page)
211− await screenshot(page)
212− })
213−
214− test('Side bar', async ({ page }) => {
215− await logIn(page)
216−
217− await page.getByRole('button').nth(1).tap();
218−
219− await screenshot(page)
220− })
221−
222− test('Passwords view', async ({ page }) => {
223− await logIn(page)
224−
225− await page.getByRole('button').nth(1).click();
226− await page.getByText('Passwords').click();
227−
228− await screenshot(page)
229− })
230−
231− test('Notes view', async ({ page }) => {
232− await logIn(page)
233−
234− await page.getByRole('button').nth(1).click();
235− await page.getByText('Notes').click();
236−
237− await screenshot(page)
238− })
239−
240− test('Cards view', async ({ page }) => {
241− await logIn(page)
242−
243− await page.getByRole('button').nth(1).click();
244− await page.getByText('Cards').click();
245−
246− await screenshot(page)
247− })
248−
249− test('Contacts view', async ({ page }) => {
250− await logIn(page)
251−
252− await page.getByRole('button').nth(1).click();
253− await page.getByText('Contacts').click();
254−
255− await screenshot(page)
256− })
257−}
tests/src/test.spec.ts-snapshots/Card-cipher-page-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Cards-view-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Contact-cipher-page-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Contacts-view-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Create-Card-entry-page-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Create-Card-entry-page-2-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Create-Contact-entry-page-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Create-Contact-entry-page-2-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Create-Note-entry-page-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Create-Note-entry-page-2-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Empty-ciphers-page-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Filled-ciphers-page-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Login-cipher-page-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Login-entry-page-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Login-entry-page-2-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Login-page-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Note-cipher-page-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Notes-view-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Passwords-view-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/src/test.spec.ts-snapshots/Side-bar-1-Pixel-3-linux.pngdeleted

Binary file not shown.

tests/vaultwarden/.envdeleted−3
@@ -1,3 +0,0 @@
1−WEB_VAULT_ENABLED=false
2−LOGIN_RATELIMIT_SECONDS=1
3−LOGIN_RATELIMIT_MAX_BURST=100000000
tests/vaultwarden/README.mddeleted−4
@@ -1,4 +0,0 @@
1−# Test vaultwarden setup
2−
3−login: `test@example.com`
4−password: `Password123`
tests/vaultwarden/data/db.sqlite3deleted

Binary file not shown.

tests/vaultwarden/data/db.sqlite3-shmdeleted

Binary file not shown.

tests/vaultwarden/data/db.sqlite3-waldeleted

No changes to the content.

tests/vaultwarden/data/rsa_key.pemdeleted−27
@@ -1,27 +0,0 @@
1−-----BEGIN RSA PRIVATE KEY-----
2−MIIEowIBAAKCAQEArVVTdkrmMbDxyGxGY73Fse9Du7DplgSBPQ5uyOnAsqf6pa1U
3−jjWwTV7Xqzp0z7k32WC64P0eGdacTQGZiFUQxTVm6bJ4TZ8bh4fz51tB4npCAzpr
4−8EcgGRzZT+cA1GQOG7jDqv8w9edWWGdPr6mx1ENvnpXtv60tvnwfsioAUSnx3SC6
5−0oTVCxj1InyneUDXCk/UqBE1wmwl8aF5U3aOc42qcELAgr6i0aCsK1LQjH+SOREh
6−tRQgpDF17IdYAxdYUTyinqrYJnoo5kQXeC/4QoZIsDi1empas7pXwrDlVYtjNK2T
7−Oht6dWUnffc2oTUCNY+ATZ6Nsu4zItEM7yQo/QIDAQABAoIBABUX/q21JLlkXrA0
8−2QYXWKE0TGphd7O9fZrYEExcAgrb3WlfJBygVQG9aoKYfRGwaScHmgZ6VzjuwJuw
9−d6Y7L+zH+Gu1P+W2WKvQNDLyDJ0KotDwwaT+it3zgFC0fIncWUkvXYSIRMWQLxZY
10−ED8A6Da8NC+48DN02E3HnjXY3awCusn9fQkPLeparsdyrvz5s8lnYYQZ6u7FQeD9
11−gM5SUP8WVLtPl4KBidJvHl4qPDAxnu98cZEoffbWIAsg3wvKNZL9yE21ZGWdExxA
12−/czWYO4ckuGY7Tb0Y+MiRI5kBM4VbCzwVfZTLRPXnKddiL7QpLMNmYpHzEcMZut4
13−z3vcdnMCgYEA5ZIzaltIEfL8zmX76pIPlyBs5n98RaagCIxQyURNRSU4H6Sr6yW2
14−CNAszcn6iAxiteXkPUkWmPXE4BFt0ifKgecPQIDk0spaVu2khRPMwUMyR0PfwXfY
15−2fqT0zMZX0MB3VPxnDTY9sAvTi2FsskL9j+Pil7U8bYaixzdc2H+LcsCgYEAwUm2
16−5A1eyX8ojZM5xUaQ/ZAiW+9u0fI5UxJ9Q0SFUWn11LJyIoIvkw6puE10508e7UT1
17−rnYZc5v/Mr6E1oO2NGBHkOZdlfJMD346r2YAtm2Nt/HZuLZU38wyIZzg0FxS6lmZ
18−m1vTEoM6Ko5GVtjvLEst27ZZDgWRW7rJNyYEq1cCgYBm6ZJY9FCrkzUXRYqXziBl
19−DCklbzMDej21d0lj4FWPUK8HKGfVQxOGgeQD4K6JvJunlUYq3w/dRBecptOHaUUT
20−1MP2k5GAmSvEWkXtTkH0xS3N2rR84z/3/6ey/u450S0Nzeq6rsowW1kZf7i2u/+7
21−xSSQ0BA/xvXBNRBlACHU3wKBgQDAuYF0zqgOfY2v7HaT75KuYUMBLDHxgHYMEMl5
22−gx7zWJXXqL4JDonlNZ+gtwqzgL6zkijt9a/XCFpi/HhzdAz/GGkDX888rcWNRS26
23−qhhXzdCa8rlGZfcm1vG9djDrUMMUDJcOw3YoZVRgDlCwU8nW/ncRNjaBtqeDMTFk
24−nbHWLQKBgH0Xatwy6DVHDbU+GYcZBjyQP5zCz0JEjDE8hEhv/ioCfUK1rfjY58zU
25−oXDdn3GpFm6eFxcVxv9Ki4jViQDYAvAErBl0kMkVU6hvITPlMEyqBh89h65xUEnw
26−ttaX+Q2lKGwHsZT4RzA45XjO8kvBymY9siL2JQUMLB8wpu9RyTRj
27−-----END RSA PRIVATE KEY-----
tests/vaultwarden/data/rsa_key.pub.pemdeleted−9
@@ -1,9 +0,0 @@
1−-----BEGIN PUBLIC KEY-----
2−MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArVVTdkrmMbDxyGxGY73F
3−se9Du7DplgSBPQ5uyOnAsqf6pa1UjjWwTV7Xqzp0z7k32WC64P0eGdacTQGZiFUQ
4−xTVm6bJ4TZ8bh4fz51tB4npCAzpr8EcgGRzZT+cA1GQOG7jDqv8w9edWWGdPr6mx
5−1ENvnpXtv60tvnwfsioAUSnx3SC60oTVCxj1InyneUDXCk/UqBE1wmwl8aF5U3aO
6−c42qcELAgr6i0aCsK1LQjH+SOREhtRQgpDF17IdYAxdYUTyinqrYJnoo5kQXeC/4
7−QoZIsDi1empas7pXwrDlVYtjNK2TOht6dWUnffc2oTUCNY+ATZ6Nsu4zItEM7yQo
8−/QIDAQAB
9−-----END PUBLIC KEY-----
tests/vaultwarden/run.shdeleted−13
@@ -1,13 +0,0 @@
1−#!/bin/sh
2−
3−set -e
4−
5−cd "$(dirname "$0")"
6−
7−tmp="$(mktemp -d)"
8−
9−cp -r data .env "$tmp"
10−
11−cd "$tmp"
12−
13−nix run github:NixOS/nixpkgs?rev=d9a1414346059619d9e13ab93e749bbb82e5252a#vaultwarden
vanillanew file+1

Submodule changed.