on master help sign in
Got creation working
commitc9bade6e25ceb91c5c194857000005ac107aee61 authoriko <ilyakooo0@gmail.com> dateSat 13 Aug 2022, 09:27 (4 years ago) parent66c03a9
13 files changed+255−27
backend/BW.js+6−1 backend/BW.purs+1−1 backend/Bridge.purs+1 backend/Data/EncString.js−1 backend/Main.purs+8 bridge.yaml+1 frontend/Bridge.elm+3 frontend/Main.elm+116−8 frontend/Pages/Ciphers.elm+8−2 frontend/Pages/EditCipher.elm+16−14 frontend/Pages/SelectCipherType.elm+76 frontend/Utils.elm+7 style.css+12
backend/BW.js+6−1
@@ -17,6 +17,7 @@ import { StateService as BaseStateService } from "../../deps/bw/libs/shared/dist
1717import { PasswordTokenRequest } from "../../deps/bw/libs/shared/dist/src/models/request/identityToken/passwordTokenRequest";
1818import { TokenRequestTwoFactor } from "../../deps/bw/libs/common/src/models/request/identityToken/tokenRequestTwoFactor";
1919import { CipherRequest } from "../../deps/bw/libs/common/src/models/request/cipherRequest";
20+import { CipherCreateRequest } from "../../deps/bw/libs/common/src/models/request/cipherCreateRequest";
2021import { Cipher } from "../../deps/bw/libs/common/src/models/domain/cipher";
2122import { CipherData } from "../../deps/bw/libs/common/src/models/data/cipherData";
2223import { PasswordGenerationService } from "../../deps/bw/libs/common/src/services/passwordGeneration.service";
@@ -76,7 +77,7 @@ export function getServices() {
7677 )
7778 ),
7879 getSync: () => api.getSync().then(sanitize),
79− postCipher: (cipher) => api.postCipher(makeCipherRequest(cipher)),
80+ postCipherCreate: (cipher) => api.postCipherCreate(makeCipherCreateRequest(cipher)),
8081 putCipher: (cipher) => api.putCipher(cipher.id, makeCipherRequest(cipher)),
8182 }
8283 },
@@ -90,6 +91,10 @@ function makeCipherRequest(cipher) {
9091 return new CipherRequest(new Cipher(new CipherData(cipher)))
9192}
9293
94+function makeCipherCreateRequest(cipher) {
95+ return new CipherCreateRequest(new Cipher(new CipherData(cipher)))
96+}
97+
9398class MainBackground {
9499 // messagingService; //: MessagingServiceAbstraction;
95100 // storageService; //: StorageServiceAbstraction;
backend/BW.purs+1−1
@@ -32,7 +32,7 @@ type ApiService
3232 -- TODO: There can really be more request and response types. Maybe handle this later.
3333 , postIdentityToken :: PasswordTokenRequest -> Promise (IdentityCaptchaResponse |+| IdentityTokenResponse)
3434 , getSync :: Unit -> Promise SyncResponse
35− , postCipher :: CipherResponse -> Promise CipherResponse
35+ , postCipherCreate :: CipherResponse -> Promise CipherResponse
3636 , putCipher :: CipherResponse -> Promise CipherResponse
3737 }
3838
backend/Bridge.purs+1
@@ -448,6 +448,7 @@ derive instance ordCmd_Login :: Ord Cmd_Login
448448
449449data Cmd =
450450 Copy String
451+ | CreateCipher FullCipher
451452 | GeneratePassword PasswordGeneratorConfig
452453 | Init
453454 | Login Cmd_Login
backend/Data/EncString.js−1
@@ -1,7 +1,6 @@
11import { EncString } from "../../deps/bw/libs/shared/dist/src/models/domain/encString"
22
33export function fromString(str) {
4− console.log("fromString " + str)
54 const x = new EncString(str)
65 return x
76}
backend/Main.purs+8
@@ -198,6 +198,14 @@ main = do
198198 password <- liftPromise $ services.passwordGeneration.generatePassword cfg
199199 send $ Bridge.GeneratedPassword password
200200 pure unit
201+ Bridge.CreateCipher fullCipher ->
202+ runWithDecryptionKey do
203+ api <- getAuthedApi
204+ cipher <- encodeCipher fullCipher
205+ newCipher <- liftPromise (api.postCipherCreate cipher) >>= decodeCipher
206+ send $ Bridge.CipherChanged newCipher
207+ performSync
208+ pure unit
201209
202210processCipher ::
203211 forall r.
bridge.yaml+1
@@ -33,6 +33,7 @@ Cmd:
3333- Copy: String
3434- Open: String
3535- UpdateCipher: FullCipher
36+- CreateCipher: FullCipher
3637- GeneratePassword: PasswordGeneratorConfig
3738
3839FullCipher:
frontend/Bridge.elm+3
@@ -502,6 +502,7 @@ jsonEncCmd_Login val =
502502
503503type Cmd =
504504 Copy String
505+ | CreateCipher FullCipher
505506 | GeneratePassword PasswordGeneratorConfig
506507 | Init
507508 | Login Cmd_Login
@@ -517,6 +518,7 @@ jsonDecCmd : Json.Decode.Decoder ( Cmd )
517518jsonDecCmd =
518519 let jsonDecDictCmd = Dict.fromList
519520 [ ("Copy", Json.Decode.lazy (\_ -> Json.Decode.map Copy (Json.Decode.string)))
521+ , ("CreateCipher", Json.Decode.lazy (\_ -> Json.Decode.map CreateCipher (jsonDecFullCipher)))
520522 , ("GeneratePassword", Json.Decode.lazy (\_ -> Json.Decode.map GeneratePassword (jsonDecPasswordGeneratorConfig)))
521523 , ("Init", Json.Decode.lazy (\_ -> Json.Decode.succeed Init))
522524 , ("Login", Json.Decode.lazy (\_ -> Json.Decode.map Login (jsonDecCmd_Login)))
@@ -535,6 +537,7 @@ jsonEncCmd : Cmd -> Value
535537jsonEncCmd val =
536538 let keyval v = case v of
537539 Copy v1 -> ("Copy", encodeValue (Json.Encode.string v1))
540+ CreateCipher v1 -> ("CreateCipher", encodeValue (jsonEncFullCipher v1))
538541 GeneratePassword v1 -> ("GeneratePassword", encodeValue (jsonEncPasswordGeneratorConfig v1))
539542 Init -> ("Init", encodeValue (Json.Encode.list identity []))
540543 Login v1 -> ("Login", encodeValue (jsonEncCmd_Login v1))
frontend/Main.elm+116−8
@@ -16,6 +16,7 @@ import Pages.Loader exposing (loader)
1616import Pages.Login as Login
1717import Pages.MasterPassword as MasterPassword
1818import Pages.Navigation as Navigation exposing (TopButton(..))
19+import Pages.SelectCipherType as SelectCipherType
1920import Task
2021import Time
2122import Types exposing (CipherId)
@@ -58,8 +59,12 @@ type Msg
5859 | UpdateLastNotificatioTime Time.Posix
5960 | EditCipher Bridge.FullCipher
6061 | UpdateCipher Bridge.FullCipher
62+ | CreateCipher Bridge.FullCipher
6163 | FireGlobalEvent Event
6264 | GeneratePassword Bridge.PasswordGeneratorConfig
65+ | CreateNewCipher
66+ | SelectCipherTypeMsg SelectCipherType.Msg
67+ | OpenNewCipherEditPage Bridge.CipherType
6368
6469
6570type alias Model =
@@ -79,10 +84,11 @@ type PageModel
7984 = LoginModel Login.Model
8085 | LoadingPage
8186 | CiphersModel Ciphers.Model
82− | EditCipherModel EditCipher.Model
87+ | EditCipherModel (EditCipher.Model Msg)
8388 | MasterPasswordModel MasterPassword.Model
8489 | CipherModel Cipher.Model
8590 | CaptchaModel Captcha.Model
91+ | SelectCipherTypeModel SelectCipherType.Model
8692
8793
8894showPage :
@@ -162,13 +168,23 @@ showPage email page =
162168 EditCipherModel model ->
163169 let
164170 p =
165− EditCipher.page editCipherCallbacks EditCipherMsg
171+ EditCipher.page EditCipherMsg
166172 in
167173 { title = p.title model
168174 , body = p.view model
169175 , topButton = Just (BackButton { action = PopView, icon = Just "close" })
170176 }
171177
178+ SelectCipherTypeModel model ->
179+ let
180+ p =
181+ SelectCipherType.page selectCipherTypeCallbacks SelectCipherTypeMsg
182+ in
183+ { title = p.title model
184+ , body = p.view model
185+ , topButton = Just simpleBackButton
186+ }
187+
172188
173189main : Program () Model Msg
174190main =
@@ -263,6 +279,9 @@ doNotStoreInHistory page =
263279 LoadingPage ->
264280 True
265281
282+ SelectCipherTypeModel _ ->
283+ True
284+
266285 _ ->
267286 False
268287
@@ -388,8 +407,6 @@ update msg model =
388407 , cmd
389408 )
390409
391− -- (Ciphers.page ciphersCallbacks CiphersMsg).init ciphers
392− -- |> Tuple.mapFirst (\pageModel -> appendPageStack <| CiphersModel pageModel)
393410 OpenCiphersScreen ->
394411 ( appendPageStack <| LoadingPage, Cmd.batch [ sendBridge Bridge.NeedCiphersList, sendBridge Bridge.NeedEmail ] )
395412
@@ -425,7 +442,7 @@ update msg model =
425442 EditCipherMsg imsg ->
426443 case currentPage of
427444 EditCipherModel page ->
428− (EditCipher.page editCipherCallbacks EditCipherMsg).update imsg page |> processPage EditCipherModel
445+ (EditCipher.page EditCipherMsg).update imsg page |> processPage EditCipherModel
429446
430447 _ ->
431448 ( model, Cmd.none )
@@ -479,7 +496,7 @@ update msg model =
479496 ( model, Cmd.none )
480497
481498 EditCipher cipher ->
482− (EditCipher.page editCipherCallbacks EditCipherMsg).init cipher
499+ (EditCipher.page EditCipherMsg).init { fullCipher = cipher, callbacks = editCipherCallbacks }
483500 |> Tuple.mapFirst (\pageModel -> keepStackWith <| EditCipherModel pageModel)
484501
485502 UpdateCipher cipher ->
@@ -491,6 +508,14 @@ update msg model =
491508 ]
492509 )
493510
511+ CreateCipher cipher ->
512+ ( model
513+ , Cmd.batch
514+ [ Bridge.CreateCipher cipher |> sendBridge
515+ , PopView |> pureCmd
516+ ]
517+ )
518+
494519 FireGlobalEvent ev ->
495520 ( { model
496521 | pageStack =
@@ -514,10 +539,13 @@ update msg model =
514539 (Cipher.page cipherCallbacks CipherMsg).event m ev |> CipherModel
515540
516541 EditCipherModel m ->
517− (EditCipher.page editCipherCallbacks EditCipherMsg).event m ev |> EditCipherModel
542+ (EditCipher.page EditCipherMsg).event m ev |> EditCipherModel
518543
519544 CaptchaModel m ->
520545 (Captcha.page captchaCallbacks CaptchaMsg).event m ev |> CaptchaModel
546+
547+ SelectCipherTypeModel m ->
548+ (SelectCipherType.page selectCipherTypeCallbacks SelectCipherTypeMsg).event m ev |> SelectCipherTypeModel
521549 )
522550 }
523551 , Cmd.none
@@ -526,6 +554,73 @@ update msg model =
526554 GeneratePassword cfg ->
527555 ( model, FFI.sendBridge (Bridge.GeneratePassword cfg) )
528556
557+ SelectCipherTypeMsg imsg ->
558+ case currentPage of
559+ SelectCipherTypeModel page ->
560+ (SelectCipherType.page selectCipherTypeCallbacks SelectCipherTypeMsg).update imsg page |> processPage SelectCipherTypeModel
561+
562+ _ ->
563+ ( model, Cmd.none )
564+
565+ CreateNewCipher ->
566+ (SelectCipherType.page selectCipherTypeCallbacks SelectCipherTypeMsg).init ()
567+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| SelectCipherTypeModel pageModel)
568+
569+ OpenNewCipherEditPage t ->
570+ (EditCipher.page EditCipherMsg).init
571+ { callbacks = createCipherCallbacks
572+ , fullCipher =
573+ { reprompt = 0
574+ , favorite = False
575+ , id = ""
576+ , name = ""
577+ , cipher =
578+ case t of
579+ Bridge.LoginType ->
580+ Bridge.LoginCipher
581+ { uris = []
582+ , username = Nothing
583+ , password = Nothing
584+ }
585+
586+ Bridge.NoteType ->
587+ Bridge.NoteCipher ""
588+
589+ Bridge.CardType ->
590+ Bridge.CardCipher
591+ { cardholderName = Nothing
592+ , brand = Nothing
593+ , number = Nothing
594+ , expMonth = Nothing
595+ , expYear = Nothing
596+ , code = Nothing
597+ }
598+
599+ Bridge.IdentityType ->
600+ Bridge.IdentityCipher
601+ { title = Nothing
602+ , firstName = Nothing
603+ , middleName = Nothing
604+ , lastName = Nothing
605+ , address1 = Nothing
606+ , address2 = Nothing
607+ , address3 = Nothing
608+ , city = Nothing
609+ , state = Nothing
610+ , postalCode = Nothing
611+ , country = Nothing
612+ , company = Nothing
613+ , email = Nothing
614+ , phone = Nothing
615+ , ssn = Nothing
616+ , username = Nothing
617+ , passportNumber = Nothing
618+ , licenseNumber = Nothing
619+ }
620+ }
621+ }
622+ |> Tuple.mapFirst (\pageModel -> keepStackWith <| EditCipherModel pageModel)
623+
529624
530625loginCallbacks : Login.Callbacks Msg
531626loginCallbacks =
@@ -534,7 +629,10 @@ loginCallbacks =
534629
535630ciphersCallbacks : Ciphers.Callbacks Msg
536631ciphersCallbacks =
537− { selected = RequestCipher, logOut = NeedsReset }
632+ { selected = RequestCipher
633+ , logOut = NeedsReset
634+ , createNewCipher = CreateNewCipher
635+ }
538636
539637
540638cipherCallbacks : Cipher.Callbacks Msg
@@ -547,6 +645,11 @@ editCipherCallbacks =
547645 { save = UpdateCipher, generatePassword = GeneratePassword }
548646
549647
648+createCipherCallbacks : EditCipher.Callbacks Msg
649+createCipherCallbacks =
650+ { save = CreateCipher, generatePassword = GeneratePassword }
651+
652+
550653captchaCallbacks : Captcha.Callbacks
551654captchaCallbacks =
552655 {}
@@ -557,3 +660,8 @@ masterPasswordCallbacks =
557660 { submit = SendMasterPassword
558661 , reset = NeedsReset
559662 }
663+
664+
665+selectCipherTypeCallbacks : SelectCipherType.Callbacks Msg
666+selectCipherTypeCallbacks =
667+ { choose = OpenNewCipherEditPage }
frontend/Pages/Ciphers.elm+8−2
@@ -64,7 +64,7 @@ menuConfig email { ciphersListFilter, menuVisible } =
6464 , current = ciphersListFilter == SpecificCiphers Bridge.CardType
6565 }
6666 , { icon = "user"
67− , name = "Identities"
67+ , name = "Contacts"
6868 , trigger = UpdateFilter (SpecificCiphers Bridge.IdentityType)
6969 , current = ciphersListFilter == SpecificCiphers Bridge.IdentityType
7070 }
@@ -83,11 +83,13 @@ type Msg
8383 | LogOut
8484 | LoadMore InfiniteScroll.Direction
8585 | InfiniteScrollMsg InfiniteScroll.Msg
86+ | CreateNewCipher
8687
8788
8889type alias Callbacks msg =
8990 { selected : String -> msg
9091 , logOut : msg
92+ , createNewCipher : msg
9193 }
9294
9395
@@ -118,6 +120,7 @@ page callbacks liftMsg =
118120 Bridge.NoteType ->
119121 "Notes"
120122 )
123+ , span [ Attr.class "u-float-right" ] [ iconButton "plus" (liftMsg CreateNewCipher) ]
121124 ]
122125 , event =
123126 \model ev ->
@@ -155,7 +158,7 @@ init ciphers =
155158
156159
157160update : Callbacks emsg -> (Msg -> emsg) -> Msg -> Model -> ( Result String Model, Cmd emsg )
158−update { logOut } liftMsg msg model =
161+update { logOut, createNewCipher } liftMsg msg model =
159162 case msg of
160163 Noop ->
161164 ( Ok model, Cmd.none )
@@ -191,6 +194,9 @@ update { logOut } liftMsg msg model =
191194 in
192195 ( Ok { model | scroll = scroll }, Cmd.map liftMsg cmd )
193196
197+ CreateNewCipher ->
198+ ( Ok model, pureCmd createNewCipher )
199+
194200
195201subscriptions : Model -> Sub Msg
196202subscriptions _ =
frontend/Pages/EditCipher.elm+16−14
@@ -11,9 +11,10 @@ import Pages.PasswordGenerator as PasswordGenerator
1111import Utils exposing (..)
1212
1313
14−type alias Model =
14+type alias Model msg =
1515 { fullCipher : Bridge.FullCipher
1616 , passwordGenerator : Maybe PasswordGenerator.Model
17+ , callbacks : Callbacks msg
1718 }
1819
1920
@@ -31,14 +32,14 @@ type alias Callbacks msg =
3132 }
3233
3334
34−page : Callbacks emsg -> Page Bridge.FullCipher Model Msg emsg
35−page callbacks liftMsg =
36− { init = \data -> Tuple.mapSecond (Cmd.map liftMsg) (init data)
35+page : Page { fullCipher : Bridge.FullCipher, callbacks : Callbacks emsg } (Model emsg) Msg emsg
36+page liftMsg =
37+ { init = init
3738 , view = \model -> view model |> List.map (Html.map liftMsg)
38− , update = \msg model -> update callbacks liftMsg msg model
39+ , update = \msg model -> update liftMsg msg model
3940 , subscriptions = \model -> subscriptions model |> Sub.map liftMsg
4041 , title =
41− \{ fullCipher } ->
42+ \{ fullCipher, callbacks } ->
4243 [ text fullCipher.name
4344 , span [ Attr.class "u-float-right" ] [ iconButton "task-outstanding" (callbacks.save fullCipher) ]
4445 ]
@@ -77,17 +78,18 @@ page callbacks liftMsg =
7778 }
7879
7980
80−init : Bridge.FullCipher -> ( Model, Cmd Msg )
81−init cipher =
82− ( { fullCipher = cipher
81+init : { fullCipher : Bridge.FullCipher, callbacks : Callbacks emsg } -> ( Model emsg, Cmd emsg )
82+init { fullCipher, callbacks } =
83+ ( { fullCipher = fullCipher
8384 , passwordGenerator = Nothing
85+ , callbacks = callbacks
8486 }
8587 , Cmd.none
8688 )
8789
8890
89−update : Callbacks emsg -> (Msg -> emsg) -> Msg -> Model -> ( Result String Model, Cmd emsg )
90−update { generatePassword } _ msg model =
91+update : (Msg -> emsg) -> Msg -> Model emsg -> ( Result String (Model emsg), Cmd emsg )
92+update _ msg model =
9193 case msg of
9294 EditCipher fullCipher ->
9395 ( Ok { model | fullCipher = fullCipher }, Cmd.none )
@@ -106,10 +108,10 @@ update { generatePassword } _ msg model =
106108 ( Ok { model | passwordGenerator = Nothing }, Cmd.none )
107109
108110 GeneratePassword cfg ->
109− ( Ok model, pureCmd (generatePassword cfg) )
111+ ( Ok model, pureCmd (model.callbacks.generatePassword cfg) )
110112
111113
112−subscriptions : Model -> Sub Msg
114+subscriptions : Model emsg -> Sub Msg
113115subscriptions _ =
114116 Sub.none
115117
@@ -128,7 +130,7 @@ row { name, nameIcon, attrs } =
128130 ]
129131
130132
131−view : Model -> List (Html Msg)
133+view : Model emsg -> List (Html Msg)
132134view { fullCipher, passwordGenerator } =
133135 maybeList passwordGenerator
134136 (\x ->
frontend/Pages/SelectCipherType.elmnew file+76
@@ -0,0 +1,76 @@
1+module Pages.SelectCipherType exposing (..)
2+
3+import Bridge
4+import Html exposing (..)
5+import Html.Attributes as Attr
6+import Html.Events as Ev
7+import Page exposing (..)
8+import Utils exposing (..)
9+
10+
11+type alias Model =
12+ {}
13+
14+
15+type Msg
16+ = Choose Bridge.CipherType
17+
18+
19+type alias Callbacks msg =
20+ { choose : Bridge.CipherType -> msg
21+ }
22+
23+
24+page : Callbacks emsg -> Page () Model Msg emsg
25+page callbacks liftMsg =
26+ { init = \() -> Tuple.mapSecond (Cmd.map liftMsg) init
27+ , view = \model -> view model |> List.map (Html.map liftMsg)
28+ , update = \msg model -> update callbacks liftMsg msg model
29+ , subscriptions = \model -> subscriptions model |> Sub.map liftMsg
30+ , title = always [ text "Select entry type" ]
31+ , event = \model _ -> model
32+ }
33+
34+
35+init : ( Model, Cmd Msg )
36+init =
37+ ( {}, Cmd.none )
38+
39+
40+update : Callbacks emsg -> (Msg -> emsg) -> Msg -> Model -> ( Result String Model, Cmd emsg )
41+update { choose } _ msg model =
42+ case msg of
43+ Choose t ->
44+ ( Ok model, pureCmd (choose t) )
45+
46+
47+subscriptions : Model -> Sub Msg
48+subscriptions model =
49+ Sub.none
50+
51+
52+view : Model -> List (Html Msg)
53+view {} =
54+ [ div [ Attr.class "select-cipher-type-container" ]
55+ [ button
56+ [ Attr.class "p-button"
57+ , Ev.onClick (Choose Bridge.LoginType)
58+ ]
59+ [ text "Login" ]
60+ , button
61+ [ Attr.class "p-button"
62+ , Ev.onClick (Choose Bridge.CardType)
63+ ]
64+ [ text "Card" ]
65+ , button
66+ [ Attr.class "p-button"
67+ , Ev.onClick (Choose Bridge.NoteType)
68+ ]
69+ [ text "Note" ]
70+ , button
71+ [ Attr.class "p-button"
72+ , Ev.onClick (Choose Bridge.IdentityType)
73+ ]
74+ [ text "Contact" ]
75+ ]
76+ ]
frontend/Utils.elm+7
@@ -2,6 +2,7 @@ module Utils exposing (..)
22
33import Html exposing (..)
44import Html.Attributes as Attr
5+import Html.Events as Ev
56import Task
67
78
@@ -144,3 +145,9 @@ spanList f aa =
144145
145146 else
146147 ( [], aa )
148+
149+
150+iconButton : String -> msg -> Html msg
151+iconButton name msg =
152+ button [ Attr.class "p-button is-inline is-dense has-icon", Ev.onClick msg ]
153+ [ i [ Attr.class ("p-icon--" ++ name) ] [] ]
style.css+12
@@ -111,3 +111,15 @@ textarea {
111111.p-side-navigation__drawer {
112112 max-width: initial;
113113}
114+
115+.select-cipher-type-container {
116+ display: flex;
117+ flex-direction: column;
118+ align-items: center;
119+ justify-content: center;
120+}
121+
122+.select-cipher-type-container > * {
123+ margin: 0px;
124+ margin-bottom: 1.5rem;
125+}