on master help sign in
Got all buttons working
commite451fb65bc1c3c1da72ba254abb144e977435b2a authoriko <ilyakooo0@gmail.com> dateSat 30 Jul 2022, 19:35 (4 years ago) parent37b471f
13 files changed+106−72
appname.desktop+1−1 backend/Bridge.purs+3−1 backend/Data/Clipboard.js+4 backend/Data/Clipboard.purs+6 backend/Data/OpenURL.js+3 backend/Data/OpenURL.purs+6 backend/Main.purs+5−3 bridge.yaml+2 frontend/Bridge.elm+8−2 frontend/Main.elm+10−2 frontend/Pages/Cipher.elm+58−39 packages.dhall−20 spago.dhall−4
appname.desktop+1−1
@@ -1,6 +1,6 @@
11[Desktop Entry]
22Name=App Title
3−Exec=webapp-container --local-content-can-access-remote-urls --app-id="appname.iko" $@ index.html
3+Exec=webapp-container --webappUrlPatterns=index.html --local-content-can-access-remote-urls --app-id="appname.iko" $@ index.html
44Icon=logo.svg
55Terminal=false
66Type=Application
backend/Bridge.purs+3−1
@@ -28,11 +28,13 @@ derive instance eqCmd_Login :: Eq Cmd_Login
2828derive instance ordCmd_Login :: Ord Cmd_Login
2929
3030data Cmd =
31− Init
31+ Copy String
32+ | Init
3233 | Login Cmd_Login
3334 | NeedCiphersList
3435 | NeedEmail
3536 | NeedsReset
37+ | Open String
3638 | RequestCipher String
3739 | SendMasterPassword String
3840
backend/Data/Clipboard.jsnew file+4
@@ -0,0 +1,4 @@
1+
2+export function clipboard(text) {
3+ return navigator.clipboard.writeText(text)
4+}
backend/Data/Clipboard.pursnew file+6
@@ -0,0 +1,6 @@
1+module Data.Clipboard where
2+
3+import Prelude
4+import Control.Promise (Promise)
5+
6+foreign import clipboard :: String -> Promise Unit
backend/Data/OpenURL.jsnew file+3
@@ -0,0 +1,3 @@
1+export function openURL(url) {
2+ return () => window.open(url, '_blank')
3+}
backend/Data/OpenURL.pursnew file+6
@@ -0,0 +1,6 @@
1+module Data.OpenURL where
2+
3+import Prelude
4+import Effect (Effect)
5+
6+foreign import openURL :: String -> Effect Unit
backend/Main.purs+5−3
@@ -9,19 +9,19 @@ import BW as WB
99import BW.Logic (decrypt, hashPassword, liftPromise)
1010import BW.Logic as Logic
1111import BW.Types (CipherResponse, Email(..), IdentityTokenResponse, Password(..), PreloginResponse, SyncResponse, Urls, cipherTypeCard, cipherTypeIdentity, cipherTypeLogin, cipherTypeSecureNote)
12−import Bridge (Sub_LoadCipher(..))
1312import Bridge as Bridge
1413import Control.El (class HasL, Al, L(..), l)
1514import Control.Monad.Error.Class (throwError)
16−import Control.Monad.List.Trans as List
1715import Control.Monad.Reader (runReaderT)
1816import Data.Argonaut (class DecodeJson)
1917import Data.Array as Array
18+import Data.Clipboard as Clipboard
2019import Data.Either (Either(..))
2120import Data.JNullable (fromJNullable, jnull, nullify)
2221import Data.JNullable as JNullable
2322import Data.JOpt (fromJOpt)
2423import Data.Maybe (Maybe(..))
24+import Data.OpenURL (openURL)
2525import Data.SymmetricCryptoKey (SymmetricCryptoKey)
2626import Data.Timestamp as Timestamp
2727import Data.Traversable (traverse)
@@ -95,7 +95,6 @@ main = do
9595 ciphers <- traverse processCipher sync.ciphers
9696 liftEffect $ Elm.send app $ Bridge.LoadCiphers $ Bridge.Sub_LoadCiphers_List ciphers
9797 api <- getAuthedApi
98− sync <- liftPromise $ api.getSync unit
9998 liftEffect $ Storage.store storage SyncKey sync
10099 pure unit
101100 Bridge.NeedsReset -> do
@@ -206,6 +205,9 @@ main = do
206205 sync <- getOrReset storage SyncKey
207206 send $ Bridge.RecieveEmail sync.profile.email
208207 pure unit
208+ Bridge.Copy text -> run do
209+ liftPromise $ Clipboard.clipboard text
210+ Bridge.Open uri -> openURL uri
209211
210212data SyncKey = SyncKey
211213
bridge.yaml+2
@@ -90,3 +90,5 @@ Cmd:
9090- NeedsReset
9191- RequestCipher: String
9292- NeedEmail
93+- Copy: String
94+- Open: String
frontend/Bridge.elm+8−2
@@ -32,22 +32,26 @@ jsonEncCmd_Login val =
3232
3333
3434type Cmd =
35− Init
35+ Copy String
36+ | Init
3637 | Login Cmd_Login
3738 | NeedCiphersList
3839 | NeedEmail
3940 | NeedsReset
41+ | Open String
4042 | RequestCipher String
4143 | SendMasterPassword String
4244
4345jsonDecCmd : Json.Decode.Decoder ( Cmd )
4446jsonDecCmd =
4547 let jsonDecDictCmd = Dict.fromList
46− [ ("Init", Json.Decode.lazy (\_ -> Json.Decode.succeed Init))
48+ [ ("Copy", Json.Decode.lazy (\_ -> Json.Decode.map Copy (Json.Decode.string)))
49+ , ("Init", Json.Decode.lazy (\_ -> Json.Decode.succeed Init))
4750 , ("Login", Json.Decode.lazy (\_ -> Json.Decode.map Login (jsonDecCmd_Login)))
4851 , ("NeedCiphersList", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedCiphersList))
4952 , ("NeedEmail", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedEmail))
5053 , ("NeedsReset", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedsReset))
54+ , ("Open", Json.Decode.lazy (\_ -> Json.Decode.map Open (Json.Decode.string)))
5155 , ("RequestCipher", Json.Decode.lazy (\_ -> Json.Decode.map RequestCipher (Json.Decode.string)))
5256 , ("SendMasterPassword", Json.Decode.lazy (\_ -> Json.Decode.map SendMasterPassword (Json.Decode.string)))
5357 ]
@@ -57,11 +61,13 @@ jsonDecCmd =
5761jsonEncCmd : Cmd -> Value
5862jsonEncCmd val =
5963 let keyval v = case v of
64+ Copy v1 -> ("Copy", encodeValue (Json.Encode.string v1))
6065 Init -> ("Init", encodeValue (Json.Encode.list identity []))
6166 Login v1 -> ("Login", encodeValue (jsonEncCmd_Login v1))
6267 NeedCiphersList -> ("NeedCiphersList", encodeValue (Json.Encode.list identity []))
6368 NeedEmail -> ("NeedEmail", encodeValue (Json.Encode.list identity []))
6469 NeedsReset -> ("NeedsReset", encodeValue (Json.Encode.list identity []))
70+ Open v1 -> ("Open", encodeValue (Json.Encode.string v1))
6571 RequestCipher v1 -> ("RequestCipher", encodeValue (Json.Encode.string v1))
6672 SendMasterPassword v1 -> ("SendMasterPassword", encodeValue (Json.Encode.string v1))
6773 in encodeSumTaggedObject "tag" "contents" keyval val
frontend/Main.elm+10−2
@@ -36,6 +36,8 @@ type Msg
3636 | RequestCipher CipherId
3737 | PopView
3838 | RecieveEmail String
39+ | Copy String
40+ | Open String
3941
4042
4143type alias CipherId =
@@ -331,6 +333,12 @@ update msg model =
331333 RecieveEmail email ->
332334 ( { model | userEmail = Just email }, Cmd.none )
333335
336+ Copy text ->
337+ ( model, FFI.sendBridge (Bridge.Copy text) )
338+
339+ Open uri ->
340+ ( model, FFI.sendBridge (Bridge.Open uri) )
341+
334342
335343loginCallbacks : Login.Callbacks Msg
336344loginCallbacks =
@@ -342,9 +350,9 @@ ciphersCallbacks =
342350 { selected = RequestCipher, logOut = NeedsReset }
343351
344352
345−cipherCallbacks : Cipher.Callbacks
353+cipherCallbacks : Cipher.Callbacks Msg
346354cipherCallbacks =
347− {}
355+ { copy = Copy, open = Open }
348356
349357
350358masterPasswordCallbacks : MasterPassword.Callbacks Msg
frontend/Pages/Cipher.elm+58−39
@@ -16,16 +16,17 @@ type alias Model =
1616
1717
1818type Msg
19− = Noop
20− | TogglePasswordVisiblity
19+ = TogglePasswordVisiblity
2120 | ToggleCVVVisiblity
21+ | Copy String
22+ | Open String
2223
2324
24−type alias Callbacks =
25− {}
25+type alias Callbacks msg =
26+ { copy : String -> msg, open : String -> msg }
2627
2728
28−page : Callbacks -> Page Bridge.Sub_LoadCipher Model Msg emsg
29+page : Callbacks emsg -> Page Bridge.Sub_LoadCipher Model Msg emsg
2930page callbacks liftMsg =
3031 { init = \cipher -> Tuple.mapSecond (Cmd.map liftMsg) (init cipher)
3132 , view = \model -> view model |> List.map (Html.map liftMsg)
@@ -45,18 +46,21 @@ init cipher =
4546 )
4647
4748
48−update : Callbacks -> (Msg -> emsg) -> Msg -> Model -> ( Result String Model, Cmd emsg )
49−update {} _ msg model =
49+update : Callbacks emsg -> (Msg -> emsg) -> Msg -> Model -> ( Result String Model, Cmd emsg )
50+update { copy, open } _ msg model =
5051 case msg of
51− Noop ->
52− ( Ok model, Cmd.none )
53−
5452 TogglePasswordVisiblity ->
5553 ( Ok { model | passwordHidden = not model.passwordHidden }, Cmd.none )
5654
5755 ToggleCVVVisiblity ->
5856 ( Ok { model | cvvHidden = not model.cvvHidden }, Cmd.none )
5957
58+ Copy text ->
59+ ( Ok model, copy text |> pureCmd )
60+
61+ Open uri ->
62+ ( Ok model, open uri |> pureCmd )
63+
6064
6165subscriptions : Model -> Sub Msg
6266subscriptions _ =
@@ -80,7 +84,7 @@ view { passwordHidden, cipher, cvvHidden } =
8084 maybeList username
8185 (\x ->
8286 row
83− { name = "Username", value = x, nameIcon = "user", icons = [ ( "copy", Noop ) ] }
87+ { name = "Username", value = x, nameIcon = "user", icons = [ ( "copy", Copy x ) ] }
8488 )
8589 ++ maybeList password
8690 (\x ->
@@ -93,14 +97,14 @@ view { passwordHidden, cipher, cvvHidden } =
9397 else
9498 x
9599 , nameIcon = "security"
96− , icons = [ ( hiddenButtonIcon passwordHidden, TogglePasswordVisiblity ), ( "copy", Noop ) ]
100+ , icons = [ ( hiddenButtonIcon passwordHidden, TogglePasswordVisiblity ), ( "copy", Copy x ) ]
97101 }
98102 )
99103 ++ (uris
100104 |> List.map
101105 (\uri ->
102106 row
103− { name = "URL", value = uri, nameIcon = "get-link", icons = [ ( "external-link", Noop ), ( "copy", Noop ) ] }
107+ { name = "URL", value = uri, nameIcon = "get-link", icons = [ ( "external-link", Open uri ), ( "copy", Copy uri ) ] }
104108 )
105109 )
106110
@@ -109,14 +113,19 @@ view { passwordHidden, cipher, cvvHidden } =
109113 ]
110114
111115 Bridge.CardCipher { number, code, cardholderName, expMonth, expYear } ->
112− maybeList number (\x -> row { name = "Card number", value = x, nameIcon = "containers", icons = [ ( "copy", Noop ) ] })
116+ maybeList number (\x -> row { name = "Card number", value = x, nameIcon = "containers", icons = [ ( "copy", Copy x ) ] })
113117 ++ optional (expMonth /= Nothing || expYear /= Nothing)
114118 (row
115− { name = "Expiration date"
116− , value = [ expMonth, expYear ] |> List.concatMap (flip maybeList identity) |> String.join "/"
117− , nameIcon = "timed-out"
118− , icons = [ ( "copy", Noop ) ]
119− }
119+ (let
120+ x =
121+ [ expMonth, expYear ] |> List.concatMap (flip maybeList identity) |> String.join "/"
122+ in
123+ { name = "Expiration date"
124+ , value = x
125+ , nameIcon = "timed-out"
126+ , icons = [ ( "copy", Copy x ) ]
127+ }
128+ )
120129 )
121130 ++ maybeList code
122131 (\x ->
@@ -129,20 +138,25 @@ view { passwordHidden, cipher, cvvHidden } =
129138 else
130139 x
131140 , nameIcon = "security"
132− , icons = [ ( hiddenButtonIcon cvvHidden, ToggleCVVVisiblity ), ( "copy", Noop ) ]
141+ , icons = [ ( hiddenButtonIcon cvvHidden, ToggleCVVVisiblity ), ( "copy", Copy x ) ]
133142 }
134143 )
135144 ++ maybeList cardholderName
136− (\x -> row { name = "Cardholder name", value = x, nameIcon = "user", icons = [ ( "copy", Noop ) ] })
145+ (\x -> row { name = "Cardholder name", value = x, nameIcon = "user", icons = [ ( "copy", Copy x ) ] })
137146
138− Bridge.IdentityCipher { address1, address2, address3, city, company, country, email, firstName, lastName, licenseNumber, middleName, passportNumber, phone, postalCode, ssn, state, title, username } ->
147+ Bridge.IdentityCipher { address1, address2, address3, company, email, firstName, lastName, licenseNumber, middleName, passportNumber, phone, ssn, username } ->
139148 optional (firstName /= Nothing || middleName /= Nothing || lastName /= Nothing)
140149 (row
141− { name = "Name"
142− , value = [ firstName, middleName, lastName ] |> List.concatMap (flip maybeList identity) |> unwords
143− , nameIcon = ""
144− , icons = [ ( "copy", Noop ) ]
145− }
150+ (let
151+ x =
152+ [ firstName, middleName, lastName ] |> List.concatMap (flip maybeList identity) |> unwords
153+ in
154+ { name = "Name"
155+ , value = x
156+ , nameIcon = ""
157+ , icons = [ ( "copy", Copy x ) ]
158+ }
159+ )
146160 )
147161 ++ maybeList username
148162 (\x ->
@@ -150,7 +164,7 @@ view { passwordHidden, cipher, cvvHidden } =
150164 { name = "Username"
151165 , value = x
152166 , nameIcon = ""
153− , icons = [ ( "copy", Noop ) ]
167+ , icons = [ ( "copy", Copy x ) ]
154168 }
155169 )
156170 ++ maybeList company
@@ -159,7 +173,7 @@ view { passwordHidden, cipher, cvvHidden } =
159173 { name = "Company"
160174 , value = x
161175 , nameIcon = ""
162− , icons = [ ( "copy", Noop ) ]
176+ , icons = [ ( "copy", Copy x ) ]
163177 }
164178 )
165179 ++ maybeList ssn
@@ -168,7 +182,7 @@ view { passwordHidden, cipher, cvvHidden } =
168182 { name = "Socia security number"
169183 , value = x
170184 , nameIcon = ""
171− , icons = [ ( "copy", Noop ) ]
185+ , icons = [ ( "copy", Copy x ) ]
172186 }
173187 )
174188 ++ maybeList passportNumber
@@ -177,7 +191,7 @@ view { passwordHidden, cipher, cvvHidden } =
177191 { name = "Passport number"
178192 , value = x
179193 , nameIcon = ""
180− , icons = [ ( "copy", Noop ) ]
194+ , icons = [ ( "copy", Copy x ) ]
181195 }
182196 )
183197 ++ maybeList licenseNumber
@@ -186,7 +200,7 @@ view { passwordHidden, cipher, cvvHidden } =
186200 { name = "License Number"
187201 , value = x
188202 , nameIcon = ""
189− , icons = [ ( "copy", Noop ) ]
203+ , icons = [ ( "copy", Copy x ) ]
190204 }
191205 )
192206 ++ maybeList email
@@ -195,7 +209,7 @@ view { passwordHidden, cipher, cvvHidden } =
195209 { name = "Email"
196210 , value = x
197211 , nameIcon = ""
198− , icons = [ ( "copy", Noop ) ]
212+ , icons = [ ( "copy", Copy x ) ]
199213 }
200214 )
201215 ++ maybeList phone
@@ -204,16 +218,21 @@ view { passwordHidden, cipher, cvvHidden } =
204218 { name = "Phone number"
205219 , value = x
206220 , nameIcon = ""
207− , icons = [ ( "copy", Noop ) ]
221+ , icons = [ ( "copy", Copy x ) ]
208222 }
209223 )
210224 ++ optional (address1 /= Nothing || address2 /= Nothing || address3 /= Nothing)
211225 (row
212− { name = "Address"
213− , value = [ address1, address2, address3 ] |> List.concatMap (flip maybeList identity) |> unwords
214− , nameIcon = ""
215− , icons = [ ( "copy", Noop ) ]
216− }
226+ (let
227+ x =
228+ [ address1, address2, address3 ] |> List.concatMap (flip maybeList identity) |> unwords
229+ in
230+ { name = "Address"
231+ , value = x
232+ , nameIcon = ""
233+ , icons = [ ( "copy", Copy x ) ]
234+ }
235+ )
217236 )
218237 )
219238 |> List.intersperse (hr [] [])
packages.dhall−20
@@ -128,23 +128,3 @@ in upstream
128128 "https://github.com/ilyakooo0/purescript-argonaut-aeson-generic.git"
129129 , version = "purescript-0.14"
130130 }
131− with subtlecrypto =
132− { dependencies =
133− [ "aff"
134− , "aff-promise"
135− , "arraybuffer-types"
136− , "console"
137− , "effect"
138− , "either"
139− , "exceptions"
140− , "foreign"
141− , "functions"
142− , "maybe"
143− , "prelude"
144− , "transformers"
145− , "tuples"
146− , "unsafe-coerce"
147− ]
148− , repo = "https://github.com/xc-jp/purescript-subtlecrypto.git"
149− , version = "7999dc92b94d1b7285375cfaad4a0ae6644b71b6"
150− }
spago.dhall−4
@@ -29,21 +29,17 @@ to generate this file without the comments in this block.
2929 , "el"
3030 , "exceptions"
3131 , "foldable-traversable"
32− , "foreign"
3332 , "functions"
34− , "lists"
3533 , "maybe"
3634 , "newtype"
3735 , "nullable"
3836 , "prelude"
3937 , "refs"
4038 , "strings"
41− , "subtlecrypto"
4239 , "transformers"
4340 , "tuples"
4441 , "typelevel-prelude"
4542 , "undefined-is-not-a-problem"
46− , "unsafe-coerce"
4743 , "web-html"
4844 , "web-storage"
4945 ]