on 40dfa7d help sign in
.github/FUNDING.yml+1−1
since splitsnapshots
unifiedsplit
@@ -1 +1 @@
1−custom: ["https://iko.soy/donate"]
1+custom: https://iko.soy/donate
.github/workflows/build.yaml+7−47
@@ -5,21 +5,13 @@ on:
5 branches: ["master"]
5 branches: ["master"]
6 pull_request:
6 pull_request:
7 branches: ["master"]
7 branches: ["master"]
8− release:
9− types: [prereleased]
10
8
11jobs:
9jobs:
12 build:
10 build:
13 runs-on: ubuntu-latest
11 runs-on: ubuntu-latest
14
12
15 steps:
13 steps:
16− - uses: cachix/install-nix-action@v19
14+ - uses: cachix/install-nix-action@v18
17−
18− - name: Cachix
19− uses: cachix/cachix-action@v12
20− with:
21− name: iko
22− authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
23
15
24 - uses: actions/checkout@v3
16 - uses: actions/checkout@v3
25 with:
17 with:
@@ -27,26 +19,20 @@ jobs:
27
19
28 - name: Install clickable
20 - name: Install clickable
29 run: |
21 run: |
30− docker --version
31 sudo apt install adb git python3 python3-pip python3-setuptools
22 sudo apt install adb git python3 python3-pip python3-setuptools
32− pip3 install --user clickable-ut==7.10.0 --upgrade
23+ pip3 install --user clickable-ut --upgrade
33 echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.bashrc
24 echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.bashrc
34
25
35− - name: Build artifacts
26+ - name: Build bw libraries
36− run: ./dev/build.sh
27+ run: ./dev/build-bw.sh
37
28
38 - name: Build Warden
29 - name: Build Warden
39− run: clickable build --output click
30+ run: clickable build --output dist
40−
41− - uses: actions/upload-artifact@v3
42− with:
43− name: click
44− path: click/*
45
31
46 - uses: actions/upload-artifact@v3
32 - uses: actions/upload-artifact@v3
47 with:
33 with:
48− name: dist
34+ name: warden
49− path: dist
35+ path: dist/*
50
36
51 # Tests
37 # Tests
52
38
@@ -69,29 +55,3 @@ jobs:
69 with:
55 with:
70 name: playwright-report
56 name: playwright-report
71 path: tests/playwright-report/
57 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−6
@@ -7,6 +7,7 @@ static/backend.js
7.spago
7.spago
8output
8output
9.psc-ide-port
9.psc-ide-port
10+backend.js
10elm.js
11elm.js
11output-es
12output-es
12elm-stuff
13elm-stuff
@@ -14,9 +15,3 @@ node_modules/
14/tests/test-results/
15/tests/test-results/
15/tests/playwright-report/
16/tests/playwright-report/
16/tests/playwright/.cache/
17/tests/playwright/.cache/
17−generated-docs
18−backend.js.map
19−.spago2nix
20−backend.js
21−vanilla
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
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+54−34
@@ -1,29 +1,27 @@
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";
20−import { CipherRequest } from "../../bw/vault/models/request/cipher.request";
19+import { CipherRequest } from "../../deps/bw/libs/common/src/models/request/cipherRequest";
21−import { CipherCreateRequest } from "../../bw/vault/models/request/cipher-create.request";
20+import { CipherCreateRequest } from "../../deps/bw/libs/common/src/models/request/cipherCreateRequest";
22−import { Cipher } from "../../bw/vault/models/domain/cipher";
21+import { Cipher } from "../../deps/bw/libs/common/src/models/domain/cipher";
23−import { CipherData } from "../../bw/vault/models/data/cipher.data";
22+import { CipherData } from "../../deps/bw/libs/common/src/models/data/cipherData";
24−import { PasswordGenerationService } from "../../bw/services/passwordGeneration.service";
23+import { PasswordGenerationService } from "../../deps/bw/libs/common/src/services/passwordGeneration.service";
25−import { TotpService } from "../../bw/services/totp.service"
24+import { TotpService } from "../../deps/bw/libs/shared/dist/src/services/totp.service"
26−import { EncryptServiceImplementation } from "../../bw/services/cryptography/encrypt.service.implementation"
27
25
28function sanitize(obj) {
26function sanitize(obj) {
29 return JSON.parse(JSON.stringify(obj));
27 return JSON.parse(JSON.stringify(obj));
@@ -75,7 +73,7 @@ export function getServices() {
75 req.email,
73 req.email,
76 req.masterPasswordHash,
74 req.masterPasswordHash,
77 req.captchaResponse,
75 req.captchaResponse,
78− new TokenTwoFactorRequest(
76+ new TokenRequestTwoFactor(
79 req.twoFactor.provider,
77 req.twoFactor.provider,
80 req.twoFactor.token,
78 req.twoFactor.token,
81 req.twoFactor.remember
79 req.twoFactor.remember
@@ -133,7 +131,6 @@ class MainBackground {
133 new StateFactory(GlobalState, Account)
131 new StateFactory(GlobalState, Account)
134 );
132 );
135 this.stateService = new StateService(
133 this.stateService = new StateService(
136− this.storageService,
137 this.storageService,
134 this.storageService,
138 this.storageService,
135 this.storageService,
139 this.logService,
136 this.logService,
@@ -164,13 +161,8 @@ class MainBackground {
164 );
161 );
165 this.i18nService = new I18nService("en");
162 this.i18nService = new I18nService("en");
166 this.cryptoFunctionService = new WebCryptoFunctionService(window);
163 this.cryptoFunctionService = new WebCryptoFunctionService(window);
167− this.encryptService = new EncryptServiceImplementation(
168− this.cryptoFunctionService,
169− this.logService
170− );
171 this.cryptoService = new BrowserCryptoService(
164 this.cryptoService = new BrowserCryptoService(
172 this.cryptoFunctionService,
165 this.cryptoFunctionService,
173− this.encryptService,
174 this.platformUtilsService,
166 this.platformUtilsService,
175 this.logService,
167 this.logService,
176 this.stateService
168 this.stateService
@@ -214,6 +206,34 @@ class MainBackground {
214 }
206 }
215}
207}
216
208
209+class MemoryStorageService {
210+
211+ constructor() {
212+ this.storage = {};
213+ }
214+
215+ async get(key) {
216+ return this.storage[key]
217+ }
218+
219+ async has(key) {
220+ return key in this.storage;
221+ }
222+
223+ async save(key, obj) {
224+ if (obj == null) {
225+ this.remove(key)
226+ return
227+ }
228+
229+ this.storage[key] = obj
230+ }
231+
232+ async remove(key) {
233+ delete this.storage[key]
234+ }
235+}
236+
217class BrowserCryptoService extends CryptoService {
237class BrowserCryptoService extends CryptoService {
218 async retrieveKeyFromStorage(keySuffix) {
238 async retrieveKeyFromStorage(keySuffix) {
219 if (keySuffix === "biometric") {
239 if (keySuffix === "biometric") {
@@ -294,7 +314,7 @@ class BrowserPlatformUtilsService {
294 saveFile(win, blobData, blobOptions, fileName) {
314 saveFile(win, blobData, blobOptions, fileName) {
295 // BrowserApi.downloadFile(win, blobData, blobOptions, fileName);
315 // BrowserApi.downloadFile(win, blobData, blobOptions, fileName);
296 }
316 }
297− getApplicationVersionNumber() {
317+ getApplicationVersion() {
298 // return Promise.resolve(BrowserApi.getApplicationVersion());
318 // return Promise.resolve(BrowserApi.getApplicationVersion());
299 }
319 }
300 supportsWebAuthn(win) {
320 supportsWebAuthn(win) {
backend/BW.purs+39−37
@@ -17,31 +17,31 @@ import Effect (Effect)
17import Effect.Unsafe (unsafePerformEffect)
17import Effect.Unsafe (unsafePerformEffect)
18import Untagged.Union (type (|+|))
18import Untagged.Union (type (|+|))
19
19
20−type TotpService =
20+type TotpService
21− { getCode :: String -> Promise String
21+ = { getCode :: String -> Promise String
22− , getTimeInterval :: String -> Int
22+ , getTimeInterval :: String -> Int
23− }
23+ }
24−
24+
25−type CryptoService =
25+type CryptoService
26− { makeKey :: Fn4 Password String KDF KdfConfig (Promise SymmetricCryptoKey)
26+ = { makeKey :: Fn4 Password String KDF Int (Promise SymmetricCryptoKey)
27− , hashPassword :: Fn3 Password SymmetricCryptoKey (JNullable HashPurpose) (Promise StringHash)
27+ , hashPassword :: Fn3 Password SymmetricCryptoKey (JNullable HashPurpose) (Promise StringHash)
28− , decryptToUtf8 :: Fn2 EncString SymmetricCryptoKey (Promise String)
28+ , decryptToUtf8 :: Fn2 EncString SymmetricCryptoKey (Promise String)
29− , decryptToBytes :: Fn2 EncString SymmetricCryptoKey (Promise ArrayBuffer)
29+ , decryptToBytes :: Fn2 EncString SymmetricCryptoKey (Promise ArrayBuffer)
30− , encrypt :: Fn2 String SymmetricCryptoKey (Promise EncString)
30+ , encrypt :: Fn2 String SymmetricCryptoKey (Promise EncString)
31− , stretchKey :: SymmetricCryptoKey -> Promise SymmetricCryptoKey
31+ , stretchKey :: SymmetricCryptoKey -> Promise SymmetricCryptoKey
32− }
32+ }
33−
33+
34−type ApiService =
34+type ApiService
35− { postPrelogin :: PreloginRequest -> Promise PreloginResponse
35+ = { postPrelogin :: PreloginRequest -> Promise PreloginResponse
36− , getProfile :: Unit -> Promise ProfileResponse
36+ , getProfile :: Unit -> Promise ProfileResponse
37− -- TODO: There can really be more request and response types. Maybe handle this later.
37+ -- TODO: There can really be more request and response types. Maybe handle this later.
38− , postIdentityToken :: PasswordTokenRequest -> Promise (IdentityCaptchaResponse |+| IdentityTwoFactorResponse |+| IdentityTokenResponse)
38+ , postIdentityToken :: PasswordTokenRequest -> Promise (IdentityCaptchaResponse |+| IdentityTwoFactorResponse |+| IdentityTokenResponse)
39− , getSync :: Unit -> Promise SyncResponse
39+ , getSync :: Unit -> Promise SyncResponse
40− , postCipherCreate :: CipherResponse -> Promise CipherResponse
40+ , postCipherCreate :: CipherResponse -> Promise CipherResponse
41− , putCipher :: CipherResponse -> Promise CipherResponse
41+ , putCipher :: CipherResponse -> Promise CipherResponse
42− , deleteCipher :: String -> Promise Unit
42+ , deleteCipher :: String -> Promise Unit
43− , postTwoFactorEmail :: TwoFactorEmailRequest -> Promise Unit
43+ , postTwoFactorEmail :: TwoFactorEmailRequest -> Promise Unit
44− }
44+ }
45
45
46type PasswordGeneration =
46type PasswordGeneration =
47 { generatePassword :: Bridge.PasswordGeneratorConfig -> Promise String
47 { generatePassword :: Bridge.PasswordGeneratorConfig -> Promise String
@@ -55,13 +55,15 @@ cryptoFunctionsTypeSha512 = "sha512" :: CryptoFunctionsType
55
55
56cryptoFunctionsTypeMd5 = "md5" :: CryptoFunctionsType
56cryptoFunctionsTypeMd5 = "md5" :: CryptoFunctionsType
57
57
58−type CryptoFunctionsType = String
58+type CryptoFunctionsType
59+ = String
59
60
60−type CryptoFunctions =
61+type CryptoFunctions
61− { hash :: Fn2 String CryptoFunctionsType (Promise Hash)
62+ = { hash :: Fn2 String CryptoFunctionsType (Promise Hash)
62− }
63+ }
63
64
65+newtype Hash
64−newtype Hash = Hash (ArrayBuffer)
66+ = Hash (ArrayBuffer)
65
67
66hashToArray :: Hash -> Array Int
68hashToArray :: Hash -> Array Int
67hashToArray (Hash buf) =
69hashToArray (Hash buf) =
@@ -84,12 +86,12 @@ instance EncodeJson Hash where
84instance DecodeJson Hash where
86instance DecodeJson Hash where
85 decodeJson = decodeJson >>> map arrayToHash
87 decodeJson = decodeJson >>> map arrayToHash
86
88
87−type Services =
89+type Services
88− { crypto :: CryptoService
90+ = { crypto :: CryptoService
89− , getApi :: Urls -> JNullable IdentityTokenResponse -> Promise ApiService
91+ , getApi :: Urls -> JNullable IdentityTokenResponse -> Promise ApiService
90− , cryptoFunctions :: CryptoFunctions
92+ , cryptoFunctions :: CryptoFunctions
91− , passwordGeneration :: PasswordGeneration
93+ , passwordGeneration :: PasswordGeneration
92− , totpService :: TotpService
94+ , totpService :: TotpService
93− }
95+ }
94
96
95foreign import getServices :: Effect Services
97foreign import getServices :: Effect Services
backend/BW/Logic.purs+248−294
@@ -3,7 +3,6 @@ module BW.Logic where
3import BW
3import BW
4import BW.Types
4import BW.Types
5import Prelude
5import Prelude
6−
7import Bridge as Bridge
6import Bridge as Bridge
8import Control.Monad.Error.Class (throwError)
7import Control.Monad.Error.Class (throwError)
9import Control.Promise (Promise)
8import Control.Promise (Promise)
@@ -15,7 +14,6 @@ import Data.JNullable as JNullable
15import Data.JOpt (JOpt(..), fromJOpt)
14import Data.JOpt (JOpt(..), fromJOpt)
16import Data.Maybe (Maybe(..), fromMaybe, maybe)
15import Data.Maybe (Maybe(..), fromMaybe, maybe)
17import Data.Newtype (class Newtype, unwrap, wrap)
16import Data.Newtype (class Newtype, unwrap, wrap)
18−import Data.Number.Format as Number
19import Data.String as String
17import Data.String as String
20import Data.SymmetricCryptoKey (SymmetricCryptoKey)
18import Data.SymmetricCryptoKey (SymmetricCryptoKey)
21import Data.SymmetricCryptoKey as SymmetricCryptoKey
19import Data.SymmetricCryptoKey as SymmetricCryptoKey
@@ -27,51 +25,43 @@ import Effect.Aff.Class (class MonadAff, liftAff)
27import Effect.Class (liftEffect)
25import Effect.Class (liftEffect)
28import Effect.Exception (error)
26import Effect.Exception (error)
29import Effect.Exception as Exc
27import Effect.Exception as Exc
30−import Effect.Random (random)
31−import Localstorage as Storage
32import Run (Run)
28import Run (Run)
33import Run.Reader (Reader, askAt)
29import Run.Reader (Reader, askAt)
34−import Storage (DeviceIDKey(..))
35import Type.Prelude (Proxy(..))
30import Type.Prelude (Proxy(..))
36import Untagged.Union (type (|+|))
31import Untagged.Union (type (|+|))
37−import Web.Storage.Storage (Storage)
38
32
39-- | Creates the master key
33-- | Creates the master key
40−makePreloginKey
34+makePreloginKey ::
41− :: forall r
35+ forall r.
42− . PreloginResponse
36+ PreloginResponse ->
43− -> Email
37+ Email ->
44− -> Password
38+ Password ->
45− -> Run
39+ Run
40+ ( crypto ::
46− ( crypto :: Reader CryptoService
41+ Reader CryptoService
47− , effect :: Effect
42+ , effect :: Effect
48− , aff :: Aff
43+ , aff :: Aff
49− | r
44+ | r
50− )
45+ )
51− SymmetricCryptoKey
46+ SymmetricCryptoKey
52−makePreloginKey { kdf, kdfIterations, kdfMemory, kdfParallelism } (Email email') password = do
47+makePreloginKey { kdf, kdfIterations } (Email email') password = do
53 crypto <- askAt (Proxy :: _ "crypto")
48 crypto <- askAt (Proxy :: _ "crypto")
54 let
49 let
55 email = (String.trim >>> String.toLower) email'
50 email = (String.trim >>> String.toLower) email'
56− liftPromise $ runFn4 crypto.makeKey password email kdf
51+ liftPromise $ runFn4 crypto.makeKey password email kdf kdfIterations
57− { iterations: kdfIterations
58− , memory: kdfMemory
59− , parallelism: kdfParallelism
60− }
61
52
62−makeDecryptionKey
53+makeDecryptionKey ::
63− :: forall r
54+ forall r.
64− .
65 -- | Matser key (prelogin key)
55 -- | Matser key (prelogin key)
66− SymmetricCryptoKey
56+ SymmetricCryptoKey ->
67− -> EncryptedString
57+ EncryptedString ->
68− -> Run
58+ Run
69− ( crypto :: Reader CryptoService
59+ ( crypto :: Reader CryptoService
70− , effect :: Effect
60+ , effect :: Effect
71− , aff :: Aff
61+ , aff :: Aff
72− | r
62+ | r
73− )
63+ )
74− SymmetricCryptoKey
64+ SymmetricCryptoKey
75makeDecryptionKey masterKey str = do
65makeDecryptionKey masterKey str = do
76 crypto <- askAt (Proxy :: _ "crypto")
66 crypto <- askAt (Proxy :: _ "crypto")
77 let
67 let
@@ -88,32 +78,28 @@ makeDecryptionKey masterKey str = do
88 liftEffect $ Exc.throw $ "Unsupported key encryption type: " <> show encType
78 liftEffect $ Exc.throw $ "Unsupported key encryption type: " <> show encType
89 pure $ SymmetricCryptoKey.fromArrayBuffer key
79 pure $ SymmetricCryptoKey.fromArrayBuffer key
90
80
91−getLogInRequestToken
81+getLogInRequestToken ::
92− :: forall r
82+ forall r.
93− . { prelogin :: PreloginResponse
83+ { prelogin :: PreloginResponse
94− , email :: Email
84+ , email :: Email
95− , password :: Password
85+ , password :: Password
96− , captchaResponse :: Maybe String
86+ , captchaResponse :: Maybe String
97− , secondFactor :: Bridge.Cmd_Login_secondFactor_Maybe
87+ , secondFactor :: Bridge.Cmd_Login_secondFactor_Maybe
98− }
88+ } ->
99− -> Run
89+ Run
100− ( api :: Reader ApiService
90+ ( api :: Reader ApiService
101− , crypto :: Reader CryptoService
91+ , crypto :: Reader CryptoService
102− , effect :: Effect
92+ , effect :: Effect
103− , aff :: Aff
93+ , aff :: Aff
104− , storage :: Reader Storage
105− | r
94+ | r
106− )
95+ )
107− (IdentityCaptchaResponse |+| IdentityTwoFactorResponse |+| IdentityTokenResponse)
96+ (IdentityCaptchaResponse |+| IdentityTwoFactorResponse |+| IdentityTokenResponse)
108−getLogInRequestToken
97+getLogInRequestToken { prelogin
109− { prelogin
110− , email
98+, email
111− , password
99+, password
112− , captchaResponse
100+, captchaResponse
113− , secondFactor: Bridge.Cmd_Login_secondFactor_Maybe secondFactor
101+, secondFactor: Bridge.Cmd_Login_secondFactor_Maybe secondFactor
114− } = do
102+} = do
115− key <- makePreloginKey prelogin email password
116− crypto <- askAt (Proxy :: _ "crypto")
117 let
103 let
118 twoFactor =
104 twoFactor =
119 maybe
105 maybe
@@ -125,11 +111,7 @@ getLogInRequestToken
125 x { provider = bridgeToSecondFactorType provider }
111 x { provider = bridgeToSecondFactorType provider }
126 )
112 )
127 secondFactor
113 secondFactor
128− _localHashedPassword <-
129− liftPromise
130− $ runFn3 crypto.hashPassword password key (nullify hashPurposeLocalAuthorization)
131− StringHash hashedPassword <- liftPromise $ runFn3 crypto.hashPassword password key jnull
114+ StringHash hashedPassword <- bwPasswordStringHash prelogin email password
132− deviceId <- getDeviceID
133 api :: ApiService <- askAt (Proxy :: _ "api")
115 api :: ApiService <- askAt (Proxy :: _ "api")
134 liftPromise
116 liftPromise
135 $ api.postIdentityToken
117 $ api.postIdentityToken
@@ -140,23 +122,23 @@ getLogInRequestToken
140 , device:
122 , device:
141 { type: deviceTypeUnknownBrowser
123 { type: deviceTypeUnknownBrowser
142 , name: "Ubuntu Touch"
124 , name: "Ubuntu Touch"
143− , identifier: deviceId
125+ , identifier: "42"
144 , pushToken: jnull
126 , pushToken: jnull
145 }
127 }
146 }
128 }
147
129
148−bwPasswordStringHash
130+bwPasswordStringHash ::
149− :: forall r
131+ forall r.
150− . PreloginResponse
132+ PreloginResponse ->
151− -> Email
133+ Email ->
152− -> Password
134+ Password ->
153− -> Run
135+ Run
154− ( crypto :: Reader CryptoService
136+ ( crypto :: Reader CryptoService
155− , effect :: Effect
137+ , effect :: Effect
156− , aff :: Aff
138+ , aff :: Aff
157− | r
139+ | r
158− )
140+ )
159− StringHash
141+ StringHash
160bwPasswordStringHash prelogin email password = do
142bwPasswordStringHash prelogin email password = do
161 key <- makePreloginKey prelogin email password
143 key <- makePreloginKey prelogin email password
162 crypto <- askAt (Proxy :: _ "crypto")
144 crypto <- askAt (Proxy :: _ "crypto")
@@ -165,47 +147,47 @@ bwPasswordStringHash prelogin email password = do
165 $ runFn3 crypto.hashPassword password key (nullify hashPurposeLocalAuthorization)
147 $ runFn3 crypto.hashPassword password key (nullify hashPurposeLocalAuthorization)
166 liftPromise $ runFn3 crypto.hashPassword password key jnull
148 liftPromise $ runFn3 crypto.hashPassword password key jnull
167
149
168−hashPassword
150+hashPassword ::
169− :: forall r
151+ forall r.
170− . Password
152+ Password ->
171− -> Run
153+ Run
172− ( cryptoFunctions :: Reader CryptoFunctions
154+ ( cryptoFunctions :: Reader CryptoFunctions
173− , aff :: Aff
155+ , aff :: Aff
174− , effect :: Effect
156+ , effect :: Effect
175− | r
157+ | r
176− )
158+ )
177− Hash
159+ Hash
178hashPassword (Password password) = do
160hashPassword (Password password) = do
179 cryptoFunctions <- askAt (Proxy :: _ "cryptoFunctions")
161 cryptoFunctions <- askAt (Proxy :: _ "cryptoFunctions")
180 liftPromise $ runFn2 cryptoFunctions.hash password cryptoFunctionsTypeSha512
162 liftPromise $ runFn2 cryptoFunctions.hash password cryptoFunctionsTypeSha512
181
163
182−decrypt
164+decrypt ::
183− :: forall r
165+ forall r.
184− . EncryptedString
166+ EncryptedString ->
185− -> Run
167+ Run
186− ( key :: Reader SymmetricCryptoKey
168+ ( key :: Reader SymmetricCryptoKey
187− , crypto :: Reader CryptoService
169+ , crypto :: Reader CryptoService
188− , aff :: Aff
170+ , aff :: Aff
189− , effect :: Effect
171+ , effect :: Effect
190− | r
172+ | r
191− )
173+ )
192− String
174+ String
193decrypt input = do
175decrypt input = do
194 crypto <- askAt (Proxy :: _ "crypto")
176 crypto <- askAt (Proxy :: _ "crypto")
195 key <- askAt (Proxy :: _ "key")
177 key <- askAt (Proxy :: _ "key")
196 liftPromise $ runFn2 crypto.decryptToUtf8 (EncString.fromString input) key
178 liftPromise $ runFn2 crypto.decryptToUtf8 (EncString.fromString input) key
197
179
198−encrypt
180+encrypt ::
199− :: forall r
181+ forall r.
200− . String
182+ String ->
201− -> Run
183+ Run
202− ( key :: Reader SymmetricCryptoKey
184+ ( key :: Reader SymmetricCryptoKey
203− , crypto :: Reader CryptoService
185+ , crypto :: Reader CryptoService
204− , aff :: Aff
186+ , aff :: Aff
205− , effect :: Effect
187+ , effect :: Effect
206− | r
188+ | r
207− )
189+ )
208− EncryptedString
190+ EncryptedString
209encrypt input = do
191encrypt input = do
210 crypto <- askAt (Proxy :: _ "crypto")
192 crypto <- askAt (Proxy :: _ "crypto")
211 key <- askAt (Proxy :: _ "key")
193 key <- askAt (Proxy :: _ "key")
@@ -214,17 +196,17 @@ encrypt input = do
214liftPromise :: forall m a. MonadAff m => Promise a -> m a
196liftPromise :: forall m a. MonadAff m => Promise a -> m a
215liftPromise = liftAff <<< Promise.toAff
197liftPromise = liftAff <<< Promise.toAff
216
198
217−encodeCipher
199+encodeCipher ::
218− :: forall r
200+ forall r.
219− . Bridge.FullCipher
201+ Bridge.FullCipher ->
220− -> Run
202+ Run
221− ( key :: Reader SymmetricCryptoKey
203+ ( key :: Reader SymmetricCryptoKey
222− , crypto :: Reader CryptoService
204+ , crypto :: Reader CryptoService
223− , aff :: Aff
205+ , aff :: Aff
224− , effect :: Effect
206+ , effect :: Effect
225− | r
207+ | r
226− )
208+ )
227− CipherResponse
209+ CipherResponse
228encodeCipher
210encodeCipher
229 (Bridge.FullCipher { name, cipher, id, favorite, reprompt, collectionIds }) = do
211 (Bridge.FullCipher { name, cipher, id, favorite, reprompt, collectionIds }) = do
230 let
212 let
@@ -240,14 +222,14 @@ encodeCipher
240 pure
222 pure
241 x
223 x
242 { card =
224 { card =
243− nullify
225+ nullify
244− { cardholderName
226+ { cardholderName
245− , brand
227+ , brand
246− , number
228+ , number
247− , expMonth
229+ , expMonth
248− , expYear
230+ , expYear
249− , code
231+ , code
250− }
232+ }
251 , type = cipherTypeCard
233 , type = cipherTypeCard
252 }
234 }
253 Bridge.IdentityCipher (Bridge.Cipher_IdentityCipher identity) -> do
235 Bridge.IdentityCipher (Bridge.Cipher_IdentityCipher identity) -> do
@@ -272,26 +254,26 @@ encodeCipher
272 pure
254 pure
273 x
255 x
274 { identity =
256 { identity =
275− nullify
257+ nullify
276− { address1
258+ { address1
277− , address2
259+ , address2
278− , address3
260+ , address3
279− , city
261+ , city
280− , company
262+ , company
281− , country
263+ , country
282− , email
264+ , email
283− , firstName
265+ , firstName
284− , lastName
266+ , lastName
285− , licenseNumber
267+ , licenseNumber
286− , middleName
268+ , middleName
287− , passportNumber
269+ , passportNumber
288− , phone
270+ , phone
289− , postalCode
271+ , postalCode
290− , ssn
272+ , ssn
291− , state
273+ , state
292− , title
274+ , title
293− , username
275+ , username
294− }
276+ }
295 , type = cipherTypeIdentity
277 , type = cipherTypeIdentity
296 }
278 }
297 Bridge.LoginCipher (Bridge.Cipher_LoginCipher login) -> do
279 Bridge.LoginCipher (Bridge.Cipher_LoginCipher login) -> do
@@ -299,7 +281,7 @@ encodeCipher
299 uris <-
281 uris <-
300 traverse
282 traverse
301 ( \uri -> do
283 ( \uri -> do
302− uriEnc <- nullify <$> encrypt uri
284+ uriEnc <- encrypt uri
303 pure { uri: uriEnc, match: jnull }
285 pure { uri: uriEnc, match: jnull }
304 )
286 )
305 (unwrap login.uris)
287 (unwrap login.uris)
@@ -308,14 +290,14 @@ encodeCipher
308 pure
290 pure
309 x
291 x
310 { login =
292 { login =
311− nullify
293+ nullify
312− { password
294+ { password
313− , uris: JOpt $ opt uris
295+ , uris: JOpt $ opt uris
314− , username
296+ , username
315− , passwordRevisionDate: jnull
297+ , passwordRevisionDate: jnull
316− , totp: totp
298+ , totp: totp
317− , autofillOnPageLoad: JOpt undefined
299+ , autofillOnPageLoad: JOpt undefined
318− }
300+ }
319 , type = cipherTypeLogin
301 , type = cipherTypeLogin
320 }
302 }
321 Bridge.NoteCipher note -> do
303 Bridge.NoteCipher note -> do
@@ -350,110 +332,100 @@ encodeCipher
350 , reprompt
332 , reprompt
351 }
333 }
352
334
353−-- | Check if the cipher is supported by Warden.
335+decodeCipher ::
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
336+ forall r.
362− . CipherResponse
337+ CipherResponse ->
363− -> Run
338+ Run
364− ( key :: Reader SymmetricCryptoKey
339+ ( key :: Reader SymmetricCryptoKey
365− , crypto :: Reader CryptoService
340+ , crypto :: Reader CryptoService
366− , aff :: Aff
341+ , aff :: Aff
367− , effect :: Effect
342+ , effect :: Effect
368− | r
343+ | r
369− )
344+ )
370− (Maybe Bridge.FullCipher)
345+ Bridge.FullCipher
371−decodeCipher cipher | not (supportedCipher cipher) =
372− pure $ Nothing
373decodeCipher cipher = do
346decodeCipher cipher = do
374 name <- decrypt cipher.name
347 name <- decrypt cipher.name
375 cipherType <- case cipher.type of
348 cipherType <- case cipher.type of
376 n
349 n
377 | cipherTypeSecureNote == n -> do
350 | cipherTypeSecureNote == n -> do
378− note <- fromJNullable "" <$> (traverse decrypt cipher.notes)
351+ note <- fromJNullable "" <$> (traverse decrypt cipher.notes)
379− pure $ Bridge.NoteCipher note
352+ pure $ Bridge.NoteCipher note
380 n
353 n
381 | cipherTypeLogin == n -> do
354 | cipherTypeLogin == n -> do
382− case JNullable.toMaybe cipher.login of
355+ case JNullable.toMaybe cipher.login of
383− Nothing -> liftEffect $ throwError $ error "Login data is missing"
356+ Nothing -> liftEffect $ throwError $ error "Login data is missing"
384− Just login -> do
357+ Just login -> do
385− username <- decryptNullable login.username
358+ username <- decryptNullable login.username
386− password <- decryptNullable login.password
359+ password <- decryptNullable login.password
387− totp <- decryptNullable login.totp
360+ totp <- decryptNullable login.totp
388− uris <- fromJOpt [] <$>
389− ((traverse >>> traverse) (_.uri >>> JNullable.toMaybe >>> maybe (pure "") decrypt) login.uris)
361+ uris <- fromJOpt [] <$> ((traverse >>> traverse) (_.uri >>> decrypt) login.uris)
390− pure $ Bridge.LoginCipher
362+ pure $ Bridge.LoginCipher
391− $ Bridge.Cipher_LoginCipher
363+ $ Bridge.Cipher_LoginCipher
392− { username
364+ { username
393− , password
365+ , password
394− , uris: wrap uris
366+ , uris: wrap uris
395− , totp
367+ , totp
396− }
368+ }
397 n
369 n
398 | cipherTypeCard == n -> do
370 | cipherTypeCard == n -> do
399− case JNullable.toMaybe cipher.card of
371+ case JNullable.toMaybe cipher.card of
400− Nothing -> liftEffect $ throwError $ error "Card data is missing"
372+ Nothing -> liftEffect $ throwError $ error "Card data is missing"
401− Just card -> do
373+ Just card -> do
402− cardholderName <- decryptNullable card.cardholderName
374+ cardholderName <- decryptNullable card.cardholderName
403− number <- decryptNullable card.number
375+ number <- decryptNullable card.number
404− code <- decryptNullable card.code
376+ code <- decryptNullable card.code
405− brand <- decryptNullable card.brand
377+ brand <- decryptNullable card.brand
406− expMonth <- decryptNullable card.expMonth
378+ expMonth <- decryptNullable card.expMonth
407− expYear <- decryptNullable card.expYear
379+ expYear <- decryptNullable card.expYear
408− pure $ Bridge.CardCipher
380+ pure $ Bridge.CardCipher
409− $ Bridge.Cipher_CardCipher
381+ $ Bridge.Cipher_CardCipher
410− { brand, cardholderName, code, expMonth, expYear, number }
382+ { brand, cardholderName, code, expMonth, expYear, number }
411 n
383 n
412 | cipherTypeIdentity == n -> do
384 | cipherTypeIdentity == n -> do
413− case JNullable.toMaybe cipher.identity of
385+ case JNullable.toMaybe cipher.identity of
414− Nothing -> liftEffect $ throwError $ error "Identity data is missing"
386+ Nothing -> liftEffect $ throwError $ error "Identity data is missing"
415− Just identity -> do
387+ Just identity -> do
416− firstName <- decryptNullable identity.firstName
388+ firstName <- decryptNullable identity.firstName
417− middleName <- decryptNullable identity.middleName
389+ middleName <- decryptNullable identity.middleName
418− lastName <- decryptNullable identity.lastName
390+ lastName <- decryptNullable identity.lastName
419− address1 <- decryptNullable identity.address1
391+ address1 <- decryptNullable identity.address1
420− address2 <- decryptNullable identity.address2
392+ address2 <- decryptNullable identity.address2
421− address3 <- decryptNullable identity.address3
393+ address3 <- decryptNullable identity.address3
422− city <- decryptNullable identity.city
394+ city <- decryptNullable identity.city
423− company <- decryptNullable identity.company
395+ company <- decryptNullable identity.company
424− country <- decryptNullable identity.country
396+ country <- decryptNullable identity.country
425− email <- decryptNullable identity.email
397+ email <- decryptNullable identity.email
426− licenseNumber <- decryptNullable identity.licenseNumber
398+ licenseNumber <- decryptNullable identity.licenseNumber
427− passportNumber <- decryptNullable identity.passportNumber
399+ passportNumber <- decryptNullable identity.passportNumber
428− phone <- decryptNullable identity.phone
400+ phone <- decryptNullable identity.phone
429− postalCode <- decryptNullable identity.postalCode
401+ postalCode <- decryptNullable identity.postalCode
430− ssn <- decryptNullable identity.ssn
402+ ssn <- decryptNullable identity.ssn
431− state <- decryptNullable identity.state
403+ state <- decryptNullable identity.state
432− title <- decryptNullable identity.title
404+ title <- decryptNullable identity.title
433− username <- decryptNullable identity.username
405+ username <- decryptNullable identity.username
434− pure $ Bridge.IdentityCipher
406+ pure $ Bridge.IdentityCipher
435− $ wrap
407+ $ wrap
436− { firstName
408+ { firstName
437− , middleName
409+ , middleName
438− , lastName
410+ , lastName
439− , address1
411+ , address1
440− , address2
412+ , address2
441− , address3
413+ , address3
442− , city
414+ , city
443− , company
415+ , company
444− , country
416+ , country
445− , email
417+ , email
446− , licenseNumber
418+ , licenseNumber
447− , passportNumber
419+ , passportNumber
448− , phone
420+ , phone
449− , postalCode
421+ , postalCode
450− , ssn
422+ , ssn
451− , state
423+ , state
452− , title
424+ , title
453− , username
425+ , username
454− }
426+ }
455 n -> liftEffect $ throwError $ error $ "Unsupported cipher type: " <> show n
427 n -> liftEffect $ throwError $ error $ "Unsupported cipher type: " <> show n
456− pure $ Just
428+ pure
457 $ wrap
429 $ wrap
458 { cipher: cipherType
430 { cipher: cipherType
459 , name
431 , name
@@ -463,50 +435,32 @@ decodeCipher cipher = do
463 , collectionIds: wrap <<< fromJNullable [] $ cipher.collectionIds
435 , collectionIds: wrap <<< fromJNullable [] $ cipher.collectionIds
464 }
436 }
465
437
466−decryptNullable
438+decryptNullable ::
467− :: forall x r
439+ forall x r.
468− . Newtype x (Maybe String)
440+ Newtype x (Maybe String) =>
469− => JNullable EncryptedString
441+ JNullable EncryptedString ->
470− -> Run
442+ Run
471− ( key :: Reader SymmetricCryptoKey
443+ ( key :: Reader SymmetricCryptoKey
472− , crypto :: Reader CryptoService
444+ , crypto :: Reader CryptoService
473− , aff :: Aff
445+ , aff :: Aff
474− , effect :: Effect
446+ , effect :: Effect
475− | r
447+ | r
476− )
448+ )
477− x
449+ x
478decryptNullable x = wrap <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt x)
450decryptNullable x = wrap <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt x)
479
451
480−encryptNullable
452+encryptNullable ::
481− :: forall x r
453+ forall x r.
482− . Newtype x (Maybe String)
454+ Newtype x (Maybe String) =>
483− => x
455+ 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
456 Run
457+ ( key :: Reader SymmetricCryptoKey
458+ , crypto :: Reader CryptoService
459+ , aff :: Aff
499− ( effect :: Effect
460+ , effect :: Effect
500− , storage :: Reader Storage
501 | r
461 | r
502 )
462 )
503− String
463+ (JNullable EncryptedString)
504−getDeviceID = do
464+encryptNullable x = case unwrap x of
505− storage <- askAt (Proxy :: _ "storage")
465+ Nothing -> pure jnull
506− maybeId <- liftEffect $ Storage.get storage DeviceIDKey
466+ Just y -> nullify <$> encrypt y
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+396−392
@@ -4,25 +4,22 @@ import Prelude
4
4
5import Bridge as Bridge
5import Bridge as Bridge
6import Data.Argonaut (class DecodeJson, class EncodeJson)
6import 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)
7import Data.JNullable (JNullable)
11import Data.JOpt (JOpt)
8import Data.JOpt (JOpt)
12import Data.Maybe (Maybe(..))
9import Data.Maybe (Maybe(..))
13−import Data.Nullable (Nullable)
14import Data.ShowableJson (ShowableJson)
10import Data.ShowableJson (ShowableJson)
15import Data.Timestamp (Timestamp)
11import Data.Timestamp (Timestamp)
16−import Data.Traversable (for)
12+import Data.Traversable (traverse)
17−import Data.Tuple.Nested ((/\))
13+import Foreign (Foreign)
18import Foreign as Foreign
14import Foreign as Foreign
15+import Foreign.Object (Object)
19import Literals.Undefined (Undefined)
16import Literals.Undefined (Undefined)
20import Type.Prelude (Proxy(..))
17import Type.Prelude (Proxy(..))
21−import Untagged.TypeCheck (class HasRuntimeType)
18+import Untagged.TypeCheck (class HasRuntimeType, hasRuntimeType)
22import Untagged.Union (type (|+|))
19import Untagged.Union (type (|+|))
23−import Untagged.Union as Union
24
20
25−newtype EncryptedString = EncryptedString String
21+newtype EncryptedString
22+ = EncryptedString String
26
23
27derive newtype instance Show EncryptedString
24derive newtype instance Show EncryptedString
28derive newtype instance Ord EncryptedString
25derive newtype instance Ord EncryptedString
@@ -31,86 +28,78 @@ derive newtype instance EncodeJson EncryptedString
31derive newtype instance DecodeJson EncryptedString
28derive newtype instance DecodeJson EncryptedString
32
29
33kdfPBKDF2_SHA256 = 0 :: KDF
30kdfPBKDF2_SHA256 = 0 :: KDF
34−kdfArgon2id = 1 :: KDF
35
31
36−type KDF = Int
32+type KDF
37−
33+ = Int
34+
38−type PreloginResponse =
35+type PreloginResponse
39− { kdf :: KDF
36+ = { kdf :: KDF
40− , kdfIterations :: Int
37+ , 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− }
38+ }
50−
39+
51−type PreloginRequest =
40+type PreloginRequest
52− { email :: Email
41+ = { email :: Email
53− }
42+ }
54−
43+
55−type ProfileResponse =
44+type ProfileResponse
56− { id :: String
45+ = { id :: String
57− , name :: JNullable String
46+ , name :: JNullable String
58− , email :: String
47+ , email :: String
59− , emailVerified :: Boolean
48+ , emailVerified :: Boolean
60− , masterPasswordHint :: JNullable String
49+ , masterPasswordHint :: JNullable String
61− -- , premiumPersonally :: Boolean
50+ , premiumPersonally :: Boolean
62− -- , premiumFromOrganization :: Boolean
51+ -- , premiumFromOrganization :: Boolean
63− , culture :: JNullable String
52+ , culture :: JNullable String
64− , twoFactorEnabled :: Boolean
53+ , twoFactorEnabled :: Boolean
65− , key :: EncryptedString
54+ , key :: EncryptedString
66− , privateKey :: EncryptedString
55+ , privateKey :: EncryptedString
67− , securityStamp :: JNullable String
56+ , securityStamp :: JNullable String
68− , forcePasswordReset :: Boolean
57+ , forcePasswordReset :: Boolean
69− , usesKeyConnector :: Boolean
58+ , usesKeyConnector :: Boolean
70− -- , organizations :: Array ProfileOrganizationResponse
59+ , organizations :: Array ProfileOrganizationResponse
71− , providers :: Array ProfileProviderResponse
60+ , providers :: Array ProfileProviderResponse
72− , providerOrganizations :: Array ProfileProviderOrganizationResponse
61+ , providerOrganizations :: Array ProfileProviderOrganizationResponse
73− }
62+ }
74−
63+
75−type ProfileOrganizationResponse =
64+type ProfileOrganizationResponse
76− { id :: String
65+ = { id :: String
77− , name :: JNullable String
66+ , name :: JNullable String
78− , usePolicies :: JNullable Boolean
67+ , usePolicies :: JNullable Boolean
79− , useGroups :: JNullable Boolean
68+ , useGroups :: JNullable Boolean
80− , useDirectory :: JNullable Boolean
69+ , useDirectory :: JNullable Boolean
81− , useEvents :: JNullable Boolean
70+ , useEvents :: JNullable Boolean
82− , useTotp :: JNullable Boolean
71+ , useTotp :: JNullable Boolean
83− , use2fa :: JNullable Boolean
72+ , use2fa :: JNullable Boolean
84− , useApi :: JNullable Boolean
73+ , useApi :: JNullable Boolean
85− , useSso :: JNullable Boolean
74+ , useSso :: JNullable Boolean
86− , useKeyConnector :: JNullable Boolean
75+ , useKeyConnector :: JNullable Boolean
87− , useResetPassword :: JNullable Boolean
76+ , useResetPassword :: JNullable Boolean
88− , selfHost :: JNullable Boolean
77+ , selfHost :: JNullable Boolean
89− , usersGetPremium :: JNullable Boolean
78+ , usersGetPremium :: JNullable Boolean
90− , seats :: JNullable Int
79+ , seats :: JNullable Int
91− , maxCollections :: JNullable Int
80+ , maxCollections :: JNullable Int
92− , maxStorageGb :: JNullable Int
81+ , maxStorageGb :: JNullable Int
93− , key :: JNullable String
82+ , key :: JNullable String
94− , hasPublicAndPrivateKeys :: JNullable Boolean
83+ , hasPublicAndPrivateKeys :: JNullable Boolean
95− , status :: JNullable OrganizationUserStatusType
84+ , status :: JNullable OrganizationUserStatusType
96− , type :: JNullable OrganizationUserType
85+ , type :: JNullable OrganizationUserType
97− , enabled :: JNullable Boolean
86+ , enabled :: JNullable Boolean
98− , ssoBound :: JNullable Boolean
87+ , ssoBound :: JNullable Boolean
99− , identifier :: JNullable String
88+ , identifier :: JNullable String
100− , permissions :: JNullable PermissionsApi
89+ , permissions :: JNullable PermissionsApi
101− , resetPasswordEnrolled :: JNullable Boolean
90+ , resetPasswordEnrolled :: JNullable Boolean
102− , userId :: JNullable String
91+ , userId :: JNullable String
103− , providerId :: JNullable String
92+ , providerId :: JNullable String
104− , providerName :: JNullable String
93+ , providerName :: JNullable String
105− , familySponsorshipFriendlyName :: JNullable String
94+ , familySponsorshipFriendlyName :: JNullable String
106− , familySponsorshipAvailable :: JNullable Boolean
95+ , familySponsorshipAvailable :: JNullable Boolean
107− , planProductType :: JNullable ProductType
96+ , planProductType :: JNullable ProductType
108− , keyConnectorEnabled :: JNullable Boolean
97+ , keyConnectorEnabled :: JNullable Boolean
109− , keyConnectorUrl :: JNullable String
98+ , keyConnectorUrl :: JNullable String
110− , familySponsorshipLastSyncDate :: JNullable Timestamp
99+ , familySponsorshipLastSyncDate :: JNullable Timestamp
111− , familySponsorshipValidUntil :: JNullable Timestamp
100+ , familySponsorshipValidUntil :: JNullable Timestamp
112− , familySponsorshipToDelete :: JNullable Boolean
101+ , familySponsorshipToDelete :: JNullable Boolean
113− }
102+ }
114
103
115organizationUserStatusTypeInvited = 0 :: OrganizationUserStatusType
104organizationUserStatusTypeInvited = 0 :: OrganizationUserStatusType
116
105
@@ -118,7 +107,8 @@ organizationUserStatusTypeAccepted = 0 :: OrganizationUserStatusType
118
107
119organizationUserStatusTypeConfirmed = 0 :: OrganizationUserStatusType
108organizationUserStatusTypeConfirmed = 0 :: OrganizationUserStatusType
120
109
121−type OrganizationUserStatusType = Int
110+type OrganizationUserStatusType
111+ = Int
122
112
123organizationUserTypeOwner = 0 :: OrganizationUserType
113organizationUserTypeOwner = 0 :: OrganizationUserType
124
114
@@ -130,26 +120,27 @@ organizationUserTypeManager = 3 :: OrganizationUserType
130
120
131organizationUserTypeCustom = 4 :: OrganizationUserType
121organizationUserTypeCustom = 4 :: OrganizationUserType
132
122
133−type OrganizationUserType = Int
123+type OrganizationUserType
134−
124+ = Int
125+
135−type PermissionsApi =
126+type PermissionsApi
136− { accessEventLogs :: Boolean
127+ = { accessEventLogs :: Boolean
137− , accessImportExport :: Boolean
128+ , accessImportExport :: Boolean
138− , accessReports :: Boolean
129+ , accessReports :: Boolean
139− , manageAllCollections :: Boolean
130+ , manageAllCollections :: Boolean
140− , createNewCollections :: Boolean
131+ , createNewCollections :: Boolean
141− , editAnyCollection :: Boolean
132+ , editAnyCollection :: Boolean
142− , deleteAnyCollection :: Boolean
133+ , deleteAnyCollection :: Boolean
143− , manageAssignedCollections :: Boolean
134+ , manageAssignedCollections :: Boolean
144− , editAssignedCollections :: Boolean
135+ , editAssignedCollections :: Boolean
145− , deleteAssignedCollections :: Boolean
136+ , deleteAssignedCollections :: Boolean
146− , manageCiphers :: Boolean
137+ , manageCiphers :: Boolean
147− , manageGroups :: Boolean
138+ , manageGroups :: Boolean
148− , manageSso :: Boolean
139+ , manageSso :: Boolean
149− , managePolicies :: Boolean
140+ , managePolicies :: Boolean
150− , manageUsers :: Boolean
141+ , manageUsers :: Boolean
151− , manageResetPassword :: Boolean
142+ , manageResetPassword :: Boolean
152− }
143+ }
153
144
154productTypeFree = 0 :: ProductType
145productTypeFree = 0 :: ProductType
155
146
@@ -159,19 +150,20 @@ productTypeTeams = 2 :: ProductType
159
150
160productTypeEnterprise = 3 :: ProductType
151productTypeEnterprise = 3 :: ProductType
161
152
162−type ProductType = Int
153+type ProductType
163−
154+ = Int
155+
164−type ProfileProviderResponse =
156+type ProfileProviderResponse
165− { id :: String
157+ = { id :: String
166− , name :: JNullable String
158+ , name :: JNullable String
167− , key :: JNullable String
159+ , key :: JNullable String
168− , status :: JNullable ProviderUserStatusType
160+ , status :: JNullable ProviderUserStatusType
169− , type :: JNullable ProviderUserType
161+ , type :: JNullable ProviderUserType
170− , enabled :: Boolean
162+ , enabled :: Boolean
171− , permissions :: PermissionsApi
163+ , permissions :: PermissionsApi
172− , userId :: JNullable String
164+ , userId :: JNullable String
173− , useEvents :: Boolean
165+ , useEvents :: Boolean
174− }
166+ }
175
167
176providerUserStatusTypeInvited = 0 :: ProviderUserStatusType
168providerUserStatusTypeInvited = 0 :: ProviderUserStatusType
177
169
@@ -179,79 +171,81 @@ providerUserStatusTypeAccepted = 1 :: ProviderUserStatusType
179
171
180providerUserStatusTypeConfirmed = 2 :: ProviderUserStatusType
172providerUserStatusTypeConfirmed = 2 :: ProviderUserStatusType
181
173
182−type ProviderUserStatusType = Int
174+type ProviderUserStatusType
175+ = Int
183
176
184providerUserTypeProviderAdmin = 0 :: ProviderUserType
177providerUserTypeProviderAdmin = 0 :: ProviderUserType
185
178
186providerUserTypeServiceUser = 1 :: ProviderUserType
179providerUserTypeServiceUser = 1 :: ProviderUserType
187
180
188−type ProviderUserType = Int
181+type ProviderUserType
189−
182+ = Int
183+
190−type ProfileProviderOrganizationResponse =
184+type ProfileProviderOrganizationResponse
191− { id :: String
185+ = { id :: String
192− , name :: JNullable String
186+ , name :: JNullable String
193− , usePolicies :: Boolean
187+ , usePolicies :: Boolean
194− , useGroups :: Boolean
188+ , useGroups :: Boolean
195− , useDirectory :: Boolean
189+ , useDirectory :: Boolean
196− , useEvents :: Boolean
190+ , useEvents :: Boolean
197− , useTotp :: Boolean
191+ , useTotp :: Boolean
198− , use2fa :: Boolean
192+ , use2fa :: Boolean
199− , useApi :: Boolean
193+ , useApi :: Boolean
200− , useSso :: Boolean
194+ , useSso :: Boolean
201− , useKeyConnector :: Boolean
195+ , useKeyConnector :: Boolean
202− , useResetPassword :: Boolean
196+ , useResetPassword :: Boolean
203− , selfHost :: Boolean
197+ , selfHost :: Boolean
204− , usersGetPremium :: Boolean
198+ , usersGetPremium :: Boolean
205− , seats :: Int
199+ , seats :: Int
206− , maxCollections :: Int
200+ , maxCollections :: Int
207− , maxStorageGb :: JNullable Int
201+ , maxStorageGb :: JNullable Int
208− , key :: JNullable String
202+ , key :: JNullable String
209− , hasPublicAndPrivateKeys :: Boolean
203+ , hasPublicAndPrivateKeys :: Boolean
210− , status :: OrganizationUserStatusType
204+ , status :: OrganizationUserStatusType
211− , type :: OrganizationUserType
205+ , type :: OrganizationUserType
212− , enabled :: Boolean
206+ , enabled :: Boolean
213− , ssoBound :: Boolean
207+ , ssoBound :: Boolean
214− , identifier :: JNullable String
208+ , identifier :: JNullable String
215− , permissions :: PermissionsApi
209+ , permissions :: PermissionsApi
216− , resetPasswordEnrolled :: Boolean
210+ , resetPasswordEnrolled :: Boolean
217− , userId :: JNullable String
211+ , userId :: JNullable String
218− , providerId :: JNullable String
212+ , providerId :: JNullable String
219− , providerName :: JNullable String
213+ , providerName :: JNullable String
220− , familySponsorshipFriendlyName :: JNullable String
214+ , familySponsorshipFriendlyName :: JNullable String
221− , familySponsorshipAvailable :: Boolean
215+ , familySponsorshipAvailable :: Boolean
222− , planProductType :: ProductType
216+ , planProductType :: ProductType
223− , keyConnectorEnabled :: Boolean
217+ , keyConnectorEnabled :: Boolean
224− , keyConnectorUrl :: JNullable String
218+ , keyConnectorUrl :: JNullable String
225− , familySponsorshipLastSyncDate :: JNullable Timestamp
219+ , familySponsorshipLastSyncDate :: JNullable Timestamp
226− , familySponsorshipValidUntil :: JNullable Timestamp
220+ , familySponsorshipValidUntil :: JNullable Timestamp
227− , familySponsorshipToDelete :: JNullable Boolean
221+ , familySponsorshipToDelete :: JNullable Boolean
228− }
222+ }
229−
223+
230−type Urls =
224+type Urls
231− { base :: JNullable String
225+ = { base :: JNullable String
232− , webVault :: JNullable String
226+ , webVault :: JNullable String
233− , api :: JNullable String
227+ , api :: JNullable String
234− , identity :: JNullable String
228+ , identity :: JNullable String
235− , icons :: JNullable String
229+ , icons :: JNullable String
236− , notifications :: JNullable String
230+ , notifications :: JNullable String
237− , events :: JNullable String
231+ , events :: JNullable String
238− , keyConnector :: JNullable String
232+ , keyConnector :: JNullable String
239− }
233+ }
240−
234+
241−type PasswordTokenRequest =
235+type PasswordTokenRequest
242− { email :: Email
236+ = { email :: Email
243− , masterPasswordHash :: String
237+ , masterPasswordHash :: String
244− , captchaResponse :: String
238+ , captchaResponse :: String
245− , twoFactor :: TokenRequestTwoFactor
239+ , twoFactor :: TokenRequestTwoFactor
246− , device :: DeviceRequest
240+ , device :: DeviceRequest
247− }
241+ }
248−
242+
249−type DeviceRequest =
243+type DeviceRequest
250− { type :: DeviceType
244+ = { type :: DeviceType
251− , name :: String
245+ , name :: String
252− , identifier :: String
246+ , identifier :: String
253− , pushToken :: JNullable String
247+ , pushToken :: JNullable String
254− }
248+ }
255
249
256deviceTypeAndroid = 0 :: DeviceType
250deviceTypeAndroid = 0 :: DeviceType
257
251
@@ -295,13 +289,14 @@ deviceTypeVivaldiExtension = 19 :: DeviceType
295
289
296deviceTypeSafariExtension = 20 :: DeviceType
290deviceTypeSafariExtension = 20 :: DeviceType
297
291
298−type DeviceType = Int
292+type DeviceType
293+ = Int
299
294
300−type TokenRequestTwoFactor =
295+type TokenRequestTwoFactor
301− { provider :: TwoFactorProviderType
296+ = { provider :: TwoFactorProviderType
302− , token :: String
297+ , token :: String
303− , remember :: Boolean
298+ , remember :: Boolean
304− }
299+ }
305
300
306twoFactorProviderTypeAuthenticator = 0 :: TwoFactorProviderType
301twoFactorProviderTypeAuthenticator = 0 :: TwoFactorProviderType
307
302
@@ -319,11 +314,12 @@ twoFactorProviderTypeOrganizationDuo = 6 :: TwoFactorProviderType
319
314
320twoFactorProviderTypeWebAuthn = 7 :: TwoFactorProviderType
315twoFactorProviderTypeWebAuthn = 7 :: TwoFactorProviderType
321
316
322−type TwoFactorProviderType = Int
317+type TwoFactorProviderType
318+ = Int
323
319
324−secondFactorTypeToBridge
320+secondFactorTypeToBridge ::
325− :: TwoFactorProviderType
321+ TwoFactorProviderType ->
326− -> Maybe Bridge.TwoFactorProviderType
322+ Maybe Bridge.TwoFactorProviderType
327secondFactorTypeToBridge x = case x of
323secondFactorTypeToBridge x = case x of
328 n
324 n
329 | n == twoFactorProviderTypeAuthenticator -> Just Bridge.Authenticator
325 | n == twoFactorProviderTypeAuthenticator -> Just Bridge.Authenticator
@@ -353,17 +349,21 @@ bridgeToSecondFactorType Bridge.Remember = twoFactorProviderTypeRemember
353bridgeToSecondFactorType Bridge.OrganizationDuo = twoFactorProviderTypeOrganizationDuo
349bridgeToSecondFactorType Bridge.OrganizationDuo = twoFactorProviderTypeOrganizationDuo
354bridgeToSecondFactorType Bridge.WebAuthn = twoFactorProviderTypeWebAuthn
350bridgeToSecondFactorType Bridge.WebAuthn = twoFactorProviderTypeWebAuthn
355
351
356−newtype Password = Password String
352+newtype Password
353+ = Password String
357
354
358hashPurposeServerAuthorization = 1 :: HashPurpose
355hashPurposeServerAuthorization = 1 :: HashPurpose
359
356
360hashPurposeLocalAuthorization = 2 :: HashPurpose
357hashPurposeLocalAuthorization = 2 :: HashPurpose
361
358
362−type HashPurpose = Int
359+type HashPurpose
360+ = Int
363
361
364−newtype StringHash = StringHash String
362+newtype StringHash
363+ = StringHash String
365
364
366−newtype AccessToken = AccessToken String
365+newtype AccessToken
366+ = AccessToken String
367
367
368derive newtype instance Show AccessToken
368derive newtype instance Show AccessToken
369derive newtype instance Eq AccessToken
369derive newtype instance Eq AccessToken
@@ -371,7 +371,8 @@ derive newtype instance Ord AccessToken
371derive newtype instance EncodeJson AccessToken
371derive newtype instance EncodeJson AccessToken
372derive newtype instance DecodeJson AccessToken
372derive newtype instance DecodeJson AccessToken
373
373
374−newtype RefreshToken = RefreshToken String
374+newtype RefreshToken
375+ = RefreshToken String
375
376
376derive newtype instance Show RefreshToken
377derive newtype instance Show RefreshToken
377derive newtype instance Eq RefreshToken
378derive newtype instance Eq RefreshToken
@@ -383,33 +384,27 @@ type IdentityCaptchaResponse =
383 { siteKey :: String
384 { siteKey :: String
384 }
385 }
385
386
386−type IdentityTokenResponse =
387+type IdentityTokenResponse
387− { accessToken :: AccessToken
388+ = { accessToken :: AccessToken
388− , expiresIn :: Int
389+ , expiresIn :: Int
389− , refreshToken :: RefreshToken
390+ , refreshToken :: RefreshToken
390− , tokenType :: String
391+ , tokenType :: String
391− , resetMasterPassword :: Boolean
392+ , resetMasterPassword :: Boolean
392− , privateKey :: EncryptedString
393+ , privateKey :: EncryptedString
393− , key :: EncryptedString
394+ , key :: EncryptedString
394− , twoFactorToken :: JNullable String
395+ , twoFactorToken :: JNullable String
395− , kdf :: KDF
396+ , kdf :: KDF
396− , kdfIterations :: Int
397+ , kdfIterations :: Int
397− , forcePasswordReset :: JNullable Boolean
398+ , forcePasswordReset :: JNullable Boolean
398− , apiUseKeyConnector :: JNullable Boolean
399+ , apiUseKeyConnector :: JNullable Boolean
399− , keyConnectorUrl :: JNullable String
400+ , keyConnectorUrl :: JNullable String
400− }
401+ }
401−
402+
402−newtype TwoFactorProviderTypes = TwoFactorProviderTypes (Array (Int |+| String))
403+newtype TwoFactorProviderTypes = TwoFactorProviderTypes (Array TwoFactorProviderType)
403
404
404instance HasRuntimeType TwoFactorProviderTypes where
405instance HasRuntimeType TwoFactorProviderTypes where
405 hasRuntimeType Proxy = Foreign.isArray
406 hasRuntimeType Proxy = Foreign.isArray
406
407
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−
413type IdentityTwoFactorResponse =
408type IdentityTwoFactorResponse =
414 { twoFactorProviders :: TwoFactorProviderTypes
409 { twoFactorProviders :: TwoFactorProviderTypes
415 -- it is a Map type and untaged unions gets confused
410 -- it is a Map type and untaged unions gets confused
@@ -417,57 +412,59 @@ type IdentityTwoFactorResponse =
417 , captchaToken :: String |+| Undefined
412 , captchaToken :: String |+| Undefined
418 }
413 }
419
414
420−newtype Email = Email String
415+newtype Email
416+ = Email String
421
417
422−type SyncResponse =
418+type SyncResponse
423− { profile :: ProfileResponse
419+ = { profile :: ProfileResponse
424− , folders :: Array FolderResponse
420+ , folders :: Array FolderResponse
425− , collections :: Array CollectionDetailsResponse
421+ , collections :: Array CollectionDetailsResponse
426− , ciphers :: Array CipherResponse
422+ , ciphers :: Array CipherResponse
427− , domains :: JNullable DomainsResponse
423+ , domains :: JNullable DomainsResponse
428− , policies :: JNullable (Array PolicyResponse)
424+ , policies :: JNullable (Array PolicyResponse)
429− , sends :: Array SendResponse
425+ , sends :: Array SendResponse
430− }
426+ }
431
427
432−type FolderResponse =
428+type FolderResponse
433− { id :: String
429+ = { id :: String
434− , name :: JNullable String
430+ , name :: JNullable String
435− , revisionDate :: JNullable String
431+ , revisionDate :: JNullable String
432+ }
433+
434+type CollectionDetailsResponse
435+ = { id :: String
436+ , organizationId :: JNullable String
437+ , name :: JNullable String
438+ , externalId :: JNullable String
439+ , readOnly :: Boolean
436− }
440+ }
437
441
438−type CollectionDetailsResponse =
439− { id :: String
440− , organizationId :: JNullable String
441− , name :: JNullable String
442− , externalId :: JNullable String
443− , readOnly :: Boolean
444− }
445
442
446type CipherId = String
443type CipherId = String
447
444
448−type CipherResponse =
445+type CipherResponse
449− { id :: CipherId
446+ = { id :: CipherId
450− , organizationId :: JNullable String
447+ , organizationId :: JNullable String
451− , folderId :: JNullable String
448+ , folderId :: JNullable String
452− , type :: CipherType
449+ , type :: CipherType
453− , name :: EncryptedString
450+ , name :: EncryptedString
454− , notes :: JNullable EncryptedString
451+ , notes :: JNullable EncryptedString
455− , fields :: JNullable (Array FieldApi)
452+ , fields :: JNullable (Array FieldApi)
456− , login :: JNullable LoginApi
453+ , login :: JNullable LoginApi
457− , card :: JNullable CardApi
454+ , card :: JNullable CardApi
458− , identity :: JNullable IdentityApi
455+ , identity :: JNullable IdentityApi
459− , secureNote :: JNullable SecureNoteApi
456+ , secureNote :: JNullable SecureNoteApi
460− , favorite :: Boolean
457+ , favorite :: Boolean
461− , edit :: JNullable Boolean
458+ , edit :: JNullable Boolean
462− , viewPassword :: JNullable Boolean
459+ , viewPassword :: JNullable Boolean
463− , organizationUseTotp :: JNullable Boolean
460+ , organizationUseTotp :: JNullable Boolean
464− , revisionDate :: JNullable Timestamp
461+ , revisionDate :: JNullable Timestamp
465− , attachments :: JNullable (Array AttachmentResponse)
462+ , attachments :: JNullable (Array AttachmentResponse)
466− , passwordHistory :: JNullable (Array PasswordHistoryResponse)
463+ , passwordHistory :: JNullable (Array PasswordHistoryResponse)
467− , collectionIds :: JNullable (Array String)
464+ , collectionIds :: JNullable (Array String)
468− , deletedDate :: JNullable String
465+ , deletedDate :: JNullable String
469− , reprompt :: CipherRepromptType
466+ , reprompt :: CipherRepromptType
470− }
467+ }
471
468
472cipherTypeLogin = 1 :: CipherType
469cipherTypeLogin = 1 :: CipherType
473
470
@@ -477,14 +474,15 @@ cipherTypeCard = 3 :: CipherType
477
474
478cipherTypeIdentity = 4 :: CipherType
475cipherTypeIdentity = 4 :: CipherType
479
476
480−type CipherType = Int
477+type CipherType
478+ = Int
481
479
482−type FieldApi =
480+type FieldApi
483− { name :: JNullable String
481+ = { name :: JNullable String
484− , value :: JNullable String
482+ , value :: JNullable String
485− , type :: FieldType
483+ , type :: FieldType
486− , linkedId :: JNullable LinkedIdType
484+ , linkedId :: JNullable LinkedIdType
487− }
485+ }
488
486
489fieldTypeText = 0 :: FieldType
487fieldTypeText = 0 :: FieldType
490
488
@@ -494,7 +492,8 @@ fieldTypeBoolean = 2 :: FieldType
494
492
495fieldTypeLinked = 3 :: FieldType
493fieldTypeLinked = 3 :: FieldType
496
494
497−type FieldType = Int
495+type FieldType
496+ = Int
498
497
499linkedIdTypeLoginLinkedIdUsername = 100 :: LinkedIdType
498linkedIdTypeLoginLinkedIdUsername = 100 :: LinkedIdType
500
499
@@ -550,22 +549,23 @@ linkedIdTypeIdentityLinkedIdLastName = 417 :: LinkedIdType
550
549
551linkedIdTypeIdentityLinkedIdFullName = 418 :: LinkedIdType
550linkedIdTypeIdentityLinkedIdFullName = 418 :: LinkedIdType
552
551
553−type LinkedIdType = Int
552+type LinkedIdType
553+ = Int
554
554
555−type LoginApi =
555+type LoginApi
556− { uris :: JOpt (Array LoginUriApi)
556+ = { uris :: JOpt (Array LoginUriApi)
557− , username :: JNullable EncryptedString
557+ , username :: JNullable EncryptedString
558− , password :: JNullable EncryptedString
558+ , password :: JNullable EncryptedString
559− , passwordRevisionDate :: JNullable String
559+ , passwordRevisionDate :: JNullable String
560− , totp :: JNullable EncryptedString
560+ , totp :: JNullable EncryptedString
561− -- This thing is undefined in some cases for some reson. Just ignoring it
561+ -- This thing is undefined in some cases for some reson. Just ignoring it
562− , autofillOnPageLoad :: JOpt (JNullable Boolean)
562+ , autofillOnPageLoad :: JOpt (JNullable Boolean)
563− }
563+ }
564
564
565−type LoginUriApi =
565+type LoginUriApi
566− { uri :: JNullable EncryptedString
566+ = { uri :: EncryptedString
567− , match :: JNullable UriMatchType
567+ , match :: JNullable UriMatchType
568− }
568+ }
569
569
570uriMatchTypeDomain = 0 :: UriMatchType
570uriMatchTypeDomain = 0 :: UriMatchType
571
571
@@ -579,85 +579,87 @@ uriMatchTypeRegularExpression = 4 :: UriMatchType
579
579
580uriMatchTypeNever = 5 :: UriMatchType
580uriMatchTypeNever = 5 :: UriMatchType
581
581
582−type UriMatchType = Int
582+type UriMatchType
583−
583+ = Int
584+
584−type CardApi =
585+type CardApi
585− { cardholderName :: JNullable EncryptedString
586+ = { cardholderName :: JNullable EncryptedString
586− , brand :: JNullable EncryptedString
587+ , brand :: JNullable EncryptedString
587− , number :: JNullable EncryptedString
588+ , number :: JNullable EncryptedString
588− , expMonth :: JNullable EncryptedString
589+ , expMonth :: JNullable EncryptedString
589− , expYear :: JNullable EncryptedString
590+ , expYear :: JNullable EncryptedString
590− , code :: JNullable EncryptedString
591+ , code :: JNullable EncryptedString
591− }
592+ }
592−
593+
593−type IdentityApi =
594+type IdentityApi
594− { title :: JNullable EncryptedString
595+ = { title :: JNullable EncryptedString
595− , firstName :: JNullable EncryptedString
596+ , firstName :: JNullable EncryptedString
596− , middleName :: JNullable EncryptedString
597+ , middleName :: JNullable EncryptedString
597− , lastName :: JNullable EncryptedString
598+ , lastName :: JNullable EncryptedString
598− , address1 :: JNullable EncryptedString
599+ , address1 :: JNullable EncryptedString
599− , address2 :: JNullable EncryptedString
600+ , address2 :: JNullable EncryptedString
600− , address3 :: JNullable EncryptedString
601+ , address3 :: JNullable EncryptedString
601− , city :: JNullable EncryptedString
602+ , city :: JNullable EncryptedString
602− , state :: JNullable EncryptedString
603+ , state :: JNullable EncryptedString
603− , postalCode :: JNullable EncryptedString
604+ , postalCode :: JNullable EncryptedString
604− , country :: JNullable EncryptedString
605+ , country :: JNullable EncryptedString
605− , company :: JNullable EncryptedString
606+ , company :: JNullable EncryptedString
606− , email :: JNullable EncryptedString
607+ , email :: JNullable EncryptedString
607− , phone :: JNullable EncryptedString
608+ , phone :: JNullable EncryptedString
608− , ssn :: JNullable EncryptedString
609+ , ssn :: JNullable EncryptedString
609− , username :: JNullable EncryptedString
610+ , username :: JNullable EncryptedString
610− , passportNumber :: JNullable EncryptedString
611+ , passportNumber :: JNullable EncryptedString
611− , licenseNumber :: JNullable EncryptedString
612+ , licenseNumber :: JNullable EncryptedString
612− }
613+ }
613
614
614secureNoteTypeGeneric = 0 :: SecureNoteType
615secureNoteTypeGeneric = 0 :: SecureNoteType
615
616
616−type SecureNoteType = Int
617+type SecureNoteType
618+ = Int
617
619
618−type SecureNoteApi =
620+type SecureNoteApi = {
619− {
620 -- type :: SecureNoteType
621 -- type :: SecureNoteType
621− }
622+}
622−
623+
623−type AttachmentResponse =
624+type AttachmentResponse
624− { id :: String
625+ = { id :: String
625− , url :: JNullable String
626+ , url :: JNullable String
626− , fileName :: JNullable String
627+ , fileName :: JNullable String
627− , key :: JNullable String
628+ , key :: JNullable String
628− , size :: JNullable String
629+ , size :: JNullable String
629− , sizeName :: JNullable String
630+ , sizeName :: JNullable String
630− }
631+ }
631−
632+
632−type PasswordHistoryResponse =
633+type PasswordHistoryResponse
633− { password :: String
634+ = { password :: String
634− , lastUsedDate :: JNullable String
635+ , lastUsedDate :: JNullable String
635− }
636+ }
636
637
637cipherRepromptTypeNone = 0 :: CipherRepromptType
638cipherRepromptTypeNone = 0 :: CipherRepromptType
638
639
639cipherRepromptTypePassword = 1 :: CipherRepromptType
640cipherRepromptTypePassword = 1 :: CipherRepromptType
640
641
641−type CipherRepromptType = Int
642+type CipherRepromptType
643+ = Int
642
644
643−type DomainsResponse =
645+type DomainsResponse
644− { equivalentDomains :: Array (Array String)
646+ = { equivalentDomains :: Array (Array String)
645− , globalEquivalentDomains :: Array GlobalDomainResponse
647+ , globalEquivalentDomains :: Array GlobalDomainResponse
646− }
648+ }
647
649
648−type GlobalDomainResponse =
650+type GlobalDomainResponse
649− { type :: Int
651+ = { type :: Int
650− , domains :: Array String
652+ , domains :: Array String
651− , excluded :: Boolean
653+ , excluded :: Boolean
652− }
654+ }
653
655
654−type PolicyResponse =
656+type PolicyResponse
655− { id :: String
657+ = { id :: String
656− , organizationId :: JNullable String
658+ , organizationId :: JNullable String
657− , type :: PolicyType
659+ , type :: PolicyType
658− , data :: ShowableJson
660+ , data :: ShowableJson
659− , enabled :: Boolean
661+ , enabled :: Boolean
660− }
662+ }
661
663
662policyTypeTwoFactorAuthentication = 0 :: PolicyType -- Requires users to have 2fa enabled
664policyTypeTwoFactorAuthentication = 0 :: PolicyType -- Requires users to have 2fa enabled
663
665
@@ -681,44 +683,46 @@ policyTypeMaximumVaultTimeout = 9 :: PolicyType -- Sets the maximum allowed vaul
681
683
682policyTypeDisablePersonalVaultExport = 10 :: PolicyType -- Disable personal vault export
684policyTypeDisablePersonalVaultExport = 10 :: PolicyType -- Disable personal vault export
683
685
684−type PolicyType = Int
686+type PolicyType
685−
687+ = Int
688+
686−type SendResponse =
689+type SendResponse
687− { id :: String
690+ = { id :: String
688− , accessId :: JNullable String
691+ , accessId :: JNullable String
689− , type :: SendType
692+ , type :: SendType
690− , name :: JNullable String
693+ , name :: JNullable String
691− , notes :: JNullable String
694+ , notes :: JNullable String
692− , file :: JNullable SendFileApi
695+ , file :: JNullable SendFileApi
693− , text :: JNullable SendTextApi
696+ , text :: JNullable SendTextApi
694− , key :: JNullable String
697+ , key :: JNullable String
695− , maxAccessCount :: JNullable Int
698+ , maxAccessCount :: JNullable Int
696− , accessCount :: JNullable Int
699+ , accessCount :: JNullable Int
697− , revisionDate :: JNullable String
700+ , revisionDate :: JNullable String
698− , expirationDate :: JNullable String
701+ , expirationDate :: JNullable String
699− , deletionDate :: JNullable String
702+ , deletionDate :: JNullable String
700− , password :: JNullable String
703+ , password :: JNullable String
701− , disable :: Boolean
704+ , disable :: Boolean
702− , hideEmail :: Boolean
705+ , hideEmail :: Boolean
703− }
706+ }
704
707
705sendTypeText = 0 :: SendType
708sendTypeText = 0 :: SendType
706
709
707sendTypeFile = 1 :: SendType
710sendTypeFile = 1 :: SendType
708
711
709−type SendType = Int
712+type SendType
713+ = Int
710
714
711−type SendFileApi =
715+type SendFileApi
712− { id :: String
716+ = { id :: String
713− , fileName :: JNullable String
717+ , fileName :: JNullable String
714− , size :: JNullable String
718+ , size :: JNullable String
715− , sizeName :: JNullable String
719+ , sizeName :: JNullable String
716− }
720+ }
717
721
718−type SendTextApi =
722+type SendTextApi
719− { text :: JNullable String
723+ = { text :: JNullable String
720− , hidden :: Boolean
724+ , hidden :: Boolean
721− }
725+ }
722
726
723type TwoFactorEmailRequest =
727type TwoFactorEmailRequest =
724 { email :: Email
728 { email :: Email
backend/Data/EncString.js+1−1
@@ -1,4 +1,4 @@
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 const x = new EncString(str)
4 const x = new EncString(str)
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/Main.purs+138−145
@@ -3,20 +3,19 @@ module Main
3 ) where
3 ) where
4
4
5import Prelude
5import Prelude
6−
7import BW (ApiService, CryptoFunctions, Services, CryptoService)
6import BW (ApiService, CryptoFunctions, Services, CryptoService)
8import BW as WB
7import BW as WB
9−import BW.Logic (bwPasswordStringHash, decodeCipher, decrypt, encodeCipher, hashPassword, liftPromise, supportedCipher)
8+import BW.Logic (bwPasswordStringHash, decodeCipher, decrypt, encodeCipher, hashPassword, liftPromise)
10import BW.Logic as Logic
9import BW.Logic as Logic
11−import BW.Types (CipherResponse, Email(..), Password(..), Urls, cipherTypeCard, cipherTypeIdentity, cipherTypeLogin, cipherTypeSecureNote, fromTwoFactorProviderType)
10+import BW.Types (CipherResponse, Email(..), Password(..), TwoFactorProviderTypes(..), Urls, cipherTypeCard, cipherTypeIdentity, cipherTypeLogin, cipherTypeSecureNote, secondFactorTypeToBridge)
12import Bridge as Bridge
11import Bridge as Bridge
13−import Control.Monad.Error.Class (catchError)
12+import Control.Monad.Error.Class (catchError, throwError)
13+import Control.Monad.Error.Class as Error
14import Data.Argonaut (class DecodeJson)
14import Data.Argonaut (class DecodeJson)
15import Data.Array as Array
15import Data.Array as Array
16import Data.Clipboard as Clipboard
16import Data.Clipboard as Clipboard
17import Data.DateTime (DateTime)
17import Data.DateTime (DateTime)
18import Data.Either (Either(..))
18import Data.Either (Either(..))
19−import Data.Foldable (for_)
20import Data.HCaptcha (bindHCaptchToken)
19import Data.HCaptcha (bindHCaptchToken)
21import Data.JNullable (jnull, nullify)
20import Data.JNullable (jnull, nullify)
22import Data.JNullable as JNullable
21import Data.JNullable as JNullable
@@ -30,7 +29,7 @@ import Effect (Effect)
30import Effect.Aff (Aff, runAff_, try)
29import Effect.Aff (Aff, runAff_, try)
31import Effect.Class (liftEffect)
30import Effect.Class (liftEffect)
32import Effect.Class.Console (log)
31import Effect.Class.Console (log)
33−import Effect.Exception (throw)
32+import Effect.Exception (error)
34import Effect.Exception as Exc
33import Effect.Exception as Exc
35import Effect.Ref as Ref
34import Effect.Ref as Ref
36import Elm as Elm
35import Elm as Elm
@@ -62,19 +61,19 @@ main = do
62 let
61 let
63 runAff act = runElmAff app $ run $ act
62 runAff act = runElmAff app $ run $ act
64
63
65− run
64+ run ::
66− :: forall a
65+ forall a.
67− . Run
66+ Run
68− ( app :: Reader Elm
67+ ( app :: Reader Elm
69− , aff :: Aff
68+ , aff :: Aff
70− , effect :: Effect
69+ , effect :: Effect
71− , crypto :: Reader CryptoService
70+ , crypto :: Reader CryptoService
72− , storage :: Reader Storage
71+ , storage :: Reader Storage
73− , services :: Reader Services
72+ , services :: Reader Services
74− , cryptoFunctions :: Reader CryptoFunctions
73+ , cryptoFunctions :: Reader CryptoFunctions
75− )
74+ )
76− a
75+ a ->
77− -> Run (EFFECT + AFF + ()) a
76+ Run (EFFECT + AFF + ()) a
78 run act =
77 run act =
79 runReaderAt (Proxy :: _ "app") app
78 runReaderAt (Proxy :: _ "app") app
80 $ runReaderAt (Proxy :: _ "crypto") services.crypto
79 $ runReaderAt (Proxy :: _ "crypto") services.crypto
@@ -83,19 +82,19 @@ main = do
83 $ runReaderAt (Proxy :: _ "cryptoFunctions") services.cryptoFunctions
82 $ runReaderAt (Proxy :: _ "cryptoFunctions") services.cryptoFunctions
84 $ act
83 $ act
85
84
86− runWithDecryptionKey
85+ runWithDecryptionKey ::
87− :: Run
86+ Run
88− ( app :: Reader Elm
87+ ( app :: Reader Elm
89− , aff :: Aff
88+ , aff :: Aff
90− , effect :: Effect
89+ , effect :: Effect
91− , key :: Reader SymmetricCryptoKey
90+ , key :: Reader SymmetricCryptoKey
92− , crypto :: Reader CryptoService
91+ , crypto :: Reader CryptoService
93− , storage :: Reader Storage
92+ , storage :: Reader Storage
94− , services :: Reader Services
93+ , services :: Reader Services
95− , cryptoFunctions :: Reader CryptoFunctions
94+ , cryptoFunctions :: Reader CryptoFunctions
96− )
95+ )
97− Unit
96+ Unit ->
98− -> Effect Unit
97+ Effect Unit
99 runWithDecryptionKey act = do
98 runWithDecryptionKey act = do
100 maybeKey <- Ref.read masterKeyRef
99 maybeKey <- Ref.read masterKeyRef
101 runAff
100 runAff
@@ -132,10 +131,7 @@ main = do
132 }
131 }
133 pure $ Right resp
132 pure $ Right resp
134 )
133 )
135− ( \err -> do
136− log $ show err
137− pure $ Left unit
134+ (const $ pure $ Left unit)
138− )
139 case map (toEither1 >>> map toEither1) $ loginResponse of
135 case map (toEither1 >>> map toEither1) $ loginResponse of
140 Left _ -> send Bridge.WrongPassword
136 Left _ -> send Bridge.WrongPassword
141 Right (Left { siteKey }) -> send $ Bridge.NeedsCaptcha siteKey
137 Right (Left { siteKey }) -> send $ Bridge.NeedsCaptcha siteKey
@@ -153,15 +149,20 @@ main = do
153 Storage.store storage SyncKey sync
149 Storage.store storage SyncKey sync
154 Storage.store storage TokenKey token
150 Storage.store storage TokenKey token
155 send Bridge.LoginSuccessful
151 send Bridge.LoginSuccessful
156− Right (Right (Left { twoFactorProviders, captchaToken })) -> do
152+ Right (Right (Left { twoFactorProviders: TwoFactorProviderTypes rawProviders, captchaToken })) -> do
157 case toEither1 captchaToken of
153 case toEither1 captchaToken of
158 Left captchaTokenString ->
154 Left captchaTokenString ->
159 liftEffect
155 liftEffect
160 $ Ref.write (Just captchaTokenString) hCaptchaTokenRef
156 $ Ref.write (Just captchaTokenString) hCaptchaTokenRef
161 Right _ -> pure unit
157 Right _ -> pure unit
162− providers <- case fromTwoFactorProviderType twoFactorProviders of
158+ providers <-
159+ liftEffect
160+ $ traverse
161+ ( \x ->
162+ secondFactorTypeToBridge x
163− Left x -> liftEffect $ throw $ "Unknown second factor provider: " <> x
163+ # Error.liftMaybe (error $ "Unknown second factor provider: " <> show x)
164− Right x -> pure x
164+ )
165+ rawProviders
165 send $ Bridge.NeedsSecondFactor $ Bridge.Sub_NeedsSecondFactor_List providers
166 send $ Bridge.NeedsSecondFactor $ Bridge.Sub_NeedsSecondFactor_List providers
166 Bridge.NeedCiphersList ->
167 Bridge.NeedCiphersList ->
167 runWithDecryptionKey do
168 runWithDecryptionKey do
@@ -186,9 +187,9 @@ main = do
186 Bridge.Init -> do
187 Bridge.Init -> do
187 Storage.get storage TokenKey
188 Storage.get storage TokenKey
188 >>= \x ->
189 >>= \x ->
189− Elm.send app case x of
190+ Elm.send app case x of
190− Just _ -> Bridge.LoginSuccessful
191+ Just _ -> Bridge.LoginSuccessful
191− Nothing -> Bridge.NeedsLogin
192+ Nothing -> Bridge.NeedsLogin
192 Bridge.RequestCipher id ->
193 Bridge.RequestCipher id ->
193 runWithDecryptionKey do
194 runWithDecryptionKey do
194 sync <- getOrReset SyncKey
195 sync <- getOrReset SyncKey
@@ -196,7 +197,8 @@ main = do
196 Nothing -> pure unit
197 Nothing -> pure unit
197 Just cipherResponse -> do
198 Just cipherResponse -> do
198 cipher <- decodeCipher cipherResponse
199 cipher <- decodeCipher cipherResponse
199− for_ cipher $ send <<< Bridge.LoadCipher
200+ send $ Bridge.LoadCipher cipher
201+ pure unit
200 pure unit
202 pure unit
201 Bridge.NeedEmail ->
203 Bridge.NeedEmail ->
202 runWithDecryptionKey do
204 runWithDecryptionKey do
@@ -212,7 +214,7 @@ main = do
212 api <- getAuthedApi
214 api <- getAuthedApi
213 cipher <- encodeCipher fullCipher
215 cipher <- encodeCipher fullCipher
214 newCipher <- liftPromise (api.putCipher cipher) >>= decodeCipher
216 newCipher <- liftPromise (api.putCipher cipher) >>= decodeCipher
215− for_ newCipher $ send <<< Bridge.CipherChanged
217+ send $ Bridge.CipherChanged newCipher
216 performSync
218 performSync
217 pure unit
219 pure unit
218 Bridge.GeneratePassword cfg ->
220 Bridge.GeneratePassword cfg ->
@@ -225,7 +227,7 @@ main = do
225 api <- getAuthedApi
227 api <- getAuthedApi
226 cipher <- encodeCipher fullCipher
228 cipher <- encodeCipher fullCipher
227 newCipher <- liftPromise (api.postCipherCreate cipher) >>= decodeCipher
229 newCipher <- liftPromise (api.postCipherCreate cipher) >>= decodeCipher
228− for_ newCipher $ send <<< Bridge.CipherChanged
230+ send $ Bridge.CipherChanged newCipher
229 performSync
231 performSync
230 pure unit
232 pure unit
231 Bridge.DeleteCipher c@(Bridge.FullCipher { id }) ->
233 Bridge.DeleteCipher c@(Bridge.FullCipher { id }) ->
@@ -243,20 +245,14 @@ main = do
243 interval = totpService.getTimeInterval totp
245 interval = totpService.getTimeInterval totp
244 send $ Bridge.Totp
246 send $ Bridge.Totp
245 $ Bridge.Sub_Totp
247 $ Bridge.Sub_Totp
246− { interval
247− , code
248− , source: totp
248+ { interval, code, source: totp
249 }
249 }
250 pure unit
250 pure unit
251 Bridge.ChooseSecondFactor
251 Bridge.ChooseSecondFactor
252 ( Bridge.Cmd_ChooseSecondFactor
252 ( Bridge.Cmd_ChooseSecondFactor
253− { email: email'
254− , factor
255− , server
256− , password
257− , requestFromServer
253+ { email: email', factor, server, password, requestFromServer
258− }
254+ }
259− ) ->
255+ ) ->
260 when requestFromServer
256 when requestFromServer
261 let
257 let
262 email = Email email'
258 email = Email email'
@@ -273,18 +269,17 @@ main = do
273 pure unit
269 pure unit
274 _ -> pure unit
270 _ -> pure unit
275
271
276−processCipher
272+processCipher ::
277− :: forall r
273+ forall r.
278− . CipherResponse
274+ CipherResponse ->
279− -> Run
275+ Run
280− ( crypto :: Reader CryptoService
276+ ( crypto :: Reader CryptoService
281− , key :: Reader SymmetricCryptoKey
277+ , key :: Reader SymmetricCryptoKey
282− , aff :: Aff
278+ , aff :: Aff
283− , effect :: Effect
279+ , effect :: Effect
284− | r
280+ | r
285− )
281+ )
286− (Maybe { cipher :: Bridge.Sub_LoadCiphers, date :: DateTime })
282+ { cipher :: Bridge.Sub_LoadCiphers, date :: DateTime }
287−processCipher cipher | not (supportedCipher cipher) = pure Nothing
288processCipher cipher = do
283processCipher cipher = do
289 name <- decrypt cipher.name
284 name <- decrypt cipher.name
290 cipherType <- case cipher.type of
285 cipherType <- case cipher.type of
@@ -296,12 +291,10 @@ processCipher cipher = do
296 | n == cipherTypeCard -> pure Bridge.CardType
291 | n == cipherTypeCard -> pure Bridge.CardType
297 n
292 n
298 | n == cipherTypeIdentity -> pure Bridge.IdentityType
293 | n == cipherTypeIdentity -> pure Bridge.IdentityType
299− n -> liftEffect $ throw $ "Unsupported cipher type: " <> show n
294+ n -> liftEffect $ throwError $ error $ "Unsupported cipher type: " <> show n
300 date <- liftEffect $ maybe (pure bottom) (Timestamp.toDateTime) $ JNullable.toMaybe cipher.revisionDate
295 date <- liftEffect $ maybe (pure bottom) (Timestamp.toDateTime) $ JNullable.toMaybe cipher.revisionDate
301 pure
296 pure
302− $ Just
303− $
304− { cipher:
297+ $ { cipher:
305 Bridge.Sub_LoadCiphers
298 Bridge.Sub_LoadCiphers
306 { name: name
299 { name: name
307 , date: maybe "" Timestamp.toLocalDateTimeString $ JNullable.toMaybe cipher.revisionDate
300 , date: maybe "" Timestamp.toLocalDateTimeString $ JNullable.toMaybe cipher.revisionDate
@@ -335,18 +328,18 @@ baseUrl server =
335 , keyConnector: jnull
328 , keyConnector: jnull
336 }
329 }
337
330
338−getOrReset
331+getOrReset ::
339− :: forall k t r
332+ forall k t r.
340− . StorageKey k t
333+ StorageKey k t =>
341− => DecodeJson t
334+ DecodeJson t =>
342− => k
335+ k ->
343− -> Run
336+ Run
344− ( storage :: Reader Storage
337+ ( storage :: Reader Storage
345− , app :: Reader Elm
338+ , app :: Reader Elm
346− , effect :: Effect
339+ , effect :: Effect
347− | r
340+ | r
348− )
341+ )
349− t
342+ t
350getOrReset key = do
343getOrReset key = do
351 storage <- askAt (Proxy :: _ "storage")
344 storage <- askAt (Proxy :: _ "storage")
352 app <- askAt (Proxy :: _ "app")
345 app <- askAt (Proxy :: _ "app")
@@ -357,69 +350,69 @@ getOrReset key = do
357 Exc.throw "Encountered an internal error. Resetting the app."
350 Exc.throw "Encountered an internal error. Resetting the app."
358 liftEffect $ try (Storage.get storage key)
351 liftEffect $ try (Storage.get storage key)
359 >>= \x -> case x of
352 >>= \x -> case x of
360− Left err -> do
353+ Left err -> do
361− log $ show err
354+ log $ show err
362− handleError
355+ handleError
363− Right Nothing -> handleError
356+ Right Nothing -> handleError
364− Right (Just y) -> pure y
357+ Right (Just y) -> pure y
365
358
366−getAuthedApi
359+getAuthedApi ::
367− :: forall r
360+ forall r.
368− . Run
361+ Run
369− ( storage :: Reader Storage
362+ ( storage :: Reader Storage
370− , app :: Reader Elm
363+ , app :: Reader Elm
371− , aff :: Aff
364+ , aff :: Aff
372− , effect :: Effect
365+ , effect :: Effect
373− , services :: Reader Services
366+ , services :: Reader Services
374− | r
367+ | r
375− )
368+ )
376− ApiService
369+ ApiService
377getAuthedApi = do
370getAuthedApi = do
378 services <- askAt (Proxy :: _ "services")
371 services <- askAt (Proxy :: _ "services")
379 token <- getOrReset TokenKey
372 token <- getOrReset TokenKey
380 url <- getOrReset UrlsKey
373 url <- getOrReset UrlsKey
381 liftPromise $ services.getApi (baseUrl url) (nullify token)
374 liftPromise $ services.getApi (baseUrl url) (nullify token)
382
375
383−requestMasterPassword
376+requestMasterPassword ::
384− :: forall r
377+ forall r.
385− . Run
378+ Run
386− ( storage :: Reader Storage
379+ ( storage :: Reader Storage
387− , app :: Reader Elm
380+ , app :: Reader Elm
388− , effect :: Effect
381+ , effect :: Effect
389− | r
382+ | r
390− )
383+ )
391− Unit
384+ Unit
392requestMasterPassword = do
385requestMasterPassword = do
393 url <- getOrReset UrlsKey
386 url <- getOrReset UrlsKey
394 sync <- getOrReset SyncKey
387 sync <- getOrReset SyncKey
395 send $ Bridge.NeedsMasterPassword $ Bridge.Sub_NeedsMasterPassword { server: url, login: sync.profile.email }
388 send $ Bridge.NeedsMasterPassword $ Bridge.Sub_NeedsMasterPassword { server: url, login: sync.profile.email }
396
389
397−send
390+send ::
398− :: forall r
391+ forall r.
399− . Bridge.Sub
392+ Bridge.Sub ->
400− -> Run
393+ Run
401− ( app :: Reader Elm
394+ ( app :: Reader Elm
402− , effect :: Effect
395+ , effect :: Effect
403− | r
396+ | r
404− )
397+ )
405− Unit
398+ Unit
406send sub = do
399send sub = do
407 app <- askAt (Proxy :: _ "app")
400 app <- askAt (Proxy :: _ "app")
408 liftEffect $ Elm.send app sub
401 liftEffect $ Elm.send app sub
409
402
410−performSync
403+performSync ::
411− :: forall r
404+ forall r.
412− . Run
405+ Run
413− ( storage :: Reader Storage
406+ ( storage :: Reader Storage
414− , app :: Reader Elm
407+ , app :: Reader Elm
415− , aff :: Aff
408+ , aff :: Aff
416− , effect :: Effect
409+ , effect :: Effect
417− , services :: Reader Services
410+ , services :: Reader Services
418− , crypto :: Reader CryptoService
411+ , crypto :: Reader CryptoService
419− , key :: Reader SymmetricCryptoKey
412+ , key :: Reader SymmetricCryptoKey
420− | r
413+ | r
421− )
414+ )
422− Unit
415+ Unit
423performSync = do
416performSync = do
424 api <- getAuthedApi
417 api <- getAuthedApi
425 storage <- askAt (Proxy :: _ "storage")
418 storage <- askAt (Proxy :: _ "storage")
@@ -427,22 +420,22 @@ performSync = do
427 liftEffect $ Storage.store storage SyncKey newSync
420 liftEffect $ Storage.store storage SyncKey newSync
428 sendCiphers
421 sendCiphers
429
422
430−sendCiphers
423+sendCiphers ::
431− :: forall r
424+ forall r.
432− . Run
425+ Run
433− ( storage :: Reader Storage
426+ ( storage :: Reader Storage
434− , app :: Reader Elm
427+ , app :: Reader Elm
435− , aff :: Aff
428+ , aff :: Aff
436− , effect :: Effect
429+ , effect :: Effect
437− , services :: Reader Services
430+ , services :: Reader Services
438− , crypto :: Reader CryptoService
431+ , crypto :: Reader CryptoService
439− , key :: Reader SymmetricCryptoKey
432+ , key :: Reader SymmetricCryptoKey
440− | r
433+ | r
441− )
434+ )
442− Unit
435+ Unit
443sendCiphers = do
436sendCiphers = do
444 sync <- getOrReset SyncKey
437 sync <- getOrReset SyncKey
445− ciphers <- Array.catMaybes <$> traverse processCipher sync.ciphers
438+ ciphers <- traverse processCipher sync.ciphers
446 let
439 let
447 sortedCiphers = Array.sortWith (_.date >>> Down) ciphers
440 sortedCiphers = Array.sortWith (_.date >>> Down) ciphers
448 send $ Bridge.LoadCiphers $ Bridge.Sub_LoadCiphers_List $ map _.cipher sortedCiphers
441 send $ Bridge.LoadCiphers $ Bridge.Sub_LoadCiphers_List $ map _.cipher sortedCiphers
backend/Storage.purs+1−7
@@ -2,7 +2,7 @@ module Storage where
2
2
3import Prelude
3import Prelude
4
4
5−import BW (Hash)
5+import BW (Hash(..))
6import BW.Types (IdentityTokenResponse, SyncResponse, PreloginResponse)
6import BW.Types (IdentityTokenResponse, SyncResponse, PreloginResponse)
7import Localstorage (class StorageKey)
7import Localstorage (class StorageKey)
8
8
@@ -35,9 +35,3 @@ data MasterPasswordHashKey
35
35
36instance StorageKey MasterPasswordHashKey Hash where
36instance StorageKey MasterPasswordHashKey Hash where
37 storageKey MasterPasswordHashKey = "master-password-hash"
37 storageKey MasterPasswordHashKey = "master-password-hash"
38−
39−data DeviceIDKey
40− = DeviceIDKey
41−
42−instance StorageKey DeviceIDKey String where
43− storageKey DeviceIDKey = "device-uuid"
build.sh+14−2
@@ -1,5 +1,17 @@
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"/{appname.apparmor,appname.desktop,manifest.json,logo.png,index.html,style.css} "$INSTALL_DIR"
8+mkdir -p "$INSTALL_DIR"/vanilla
9+cp -r "$SRC_DIR"/vanilla/dist "$INSTALL_DIR"/vanilla
10+
11+elm make "$SRC_DIR/frontend/Main.elm" --optimize --output="$TEMP/elm.js"
12+
13+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"
14+
15+(cd "$SRC_DIR" && spago bundle-app --to "$TEMP/backend.js")
16+
17+terser "$TEMP/backend.js" --ecma 2018 --mangle --compress 'drop_console=true' --comments=false --toplevel --output "$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.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+nix run github:NixOS/nixpkgs?rev=d9a1414346059619d9e13ab93e749bbb82e5252a#elmPackages.elm-live -- $1 --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/spago2nix.shdeleted−3
@@ -1,3 +0,0 @@
1−#!/bin/sh
2−
3−nix run "github:justinwoo/spago2nix#spago2nix" -- generate
dev/start-chrome.sh+1−3
@@ -1,8 +1,6 @@
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+if test -f /Applications/Chromium.app/Contents/MacOS/Chromium; then
6 /Applications/Chromium.app/Contents/MacOS/Chromium --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
4 /Applications/Chromium.app/Contents/MacOS/Chromium --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
7else
5else
8 flatpak run com.github.Eloston.UngoogledChromium --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
6 flatpak run com.github.Eloston.UngoogledChromium --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
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−}
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−
index.html+1−1
@@ -7,7 +7,7 @@
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/dist/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+5−5
@@ -4,12 +4,12 @@
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.1.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+4−4
@@ -99,8 +99,8 @@ 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 argonaut-aeson-generic =
106 with argonaut-aeson-generic =
@@ -125,7 +125,7 @@ in upstream
125 ]
125 ]
126 , repo =
126 , repo =
127 "https://github.com/ilyakooo0/purescript-argonaut-aeson-generic.git"
127 "https://github.com/ilyakooo0/purescript-argonaut-aeson-generic.git"
128− , version = "3e388500811ef4b6718fc776789f3be050ad7b57"
128+ , version = "purescript-0.14"
129 }
129 }
130 with untagged-union =
130 with untagged-union =
131 { dependencies =
131 { dependencies =
@@ -147,7 +147,7 @@ in upstream
147 }
147 }
148 with literals =
148 with literals =
149 { repo = "https://github.com/ilyakooo0/purescript-literals.git"
149 { repo = "https://github.com/ilyakooo0/purescript-literals.git"
150− , version = "6875fb28026595cfb780318305a77e79b098bb01"
150+ , version = "iko/_null"
151 , dependencies =
151 , dependencies =
152 [ "assert"
152 [ "assert"
153 , "effect"
153 , "effect"
registry.datdeleted

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−3
@@ -29,16 +29,14 @@ to generate this file without the comments in this block.
29 , "exceptions"
29 , "exceptions"
30 , "foldable-traversable"
30 , "foldable-traversable"
31 , "foreign"
31 , "foreign"
32+ , "foreign-object"
32 , "functions"
33 , "functions"
33− , "integers"
34 , "literals"
34 , "literals"
35 , "maybe"
35 , "maybe"
36 , "newtype"
36 , "newtype"
37 , "nullable"
37 , "nullable"
38− , "numbers"
39 , "orders"
38 , "orders"
40 , "prelude"
39 , "prelude"
41− , "random"
42 , "refs"
40 , "refs"
43 , "run"
41 , "run"
44 , "strings"
42 , "strings"
tests/src/test.spec.ts+2−3
@@ -85,7 +85,7 @@ async function screenshot(page: Page) {
85 await page.locator('.p-icon--spinner.u-animation--spin.spinner').waitFor({ state: "hidden" })
85 await page.locator('.p-icon--spinner.u-animation--spin.spinner').waitFor({ state: "hidden" })
86 await screenshot(page)
86 await screenshot(page)
87 } else {
87 } else {
88− await expect.soft(page).toHaveScreenshot({ animations: "disabled", fullPage: true, maxDiffPixelRatio: 0.01 })
88+ await expect.soft(page).toHaveScreenshot({ mask: [page.locator(".hide-in-test")], animations: "disabled", fullPage: true })
89 }
89 }
90}
90}
91
91
@@ -108,8 +108,7 @@ function cipherPage(name: string) {
108}
108}
109
109
110test.beforeEach(async ({ page }) => {
110test.beforeEach(async ({ page }) => {
111− await page.goto(`file://${__dirname}/../../dist/index.html`);
111+ await page.goto(`file://${__dirname}/../../build/all/app/install/index.html`);
112− await page.addStyleTag({ content: '.hide-in-test {opacity: 0;}' })
113})
112})
114
113
115if (process.env.RECORD_TEST === "true") {
114if (process.env.RECORD_TEST === "true") {
tests/src/test.spec.ts-snapshots/Card-cipher-page-1-Pixel-3-linux.png

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

vanillanew file+1

Submodule changed.