@lifeready/core 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/lifeready-core.umd.js +15939 -0
- package/bundles/lifeready-core.umd.js.map +1 -0
- package/bundles/lifeready-core.umd.min.js +16 -0
- package/bundles/lifeready-core.umd.min.js.map +1 -0
- package/esm2015/lib/_common/ast.js +40 -0
- package/esm2015/lib/_common/deferred-promise.js +24 -0
- package/esm2015/lib/_common/exceptions.js +157 -0
- package/esm2015/lib/_common/queries.gql.js +190 -0
- package/esm2015/lib/_common/run-outside-angular.js +79 -0
- package/esm2015/lib/_common/types.js +1 -0
- package/esm2015/lib/_common/utils.js +44 -0
- package/esm2015/lib/api/contact-card.gql.js +79 -0
- package/esm2015/lib/api/contact-card.service.js +154 -0
- package/esm2015/lib/api/contact-card2.gql.js +60 -0
- package/esm2015/lib/api/contact-card2.service.js +103 -0
- package/esm2015/lib/api/file.service.js +74 -0
- package/esm2015/lib/api/item2.gql.js +110 -0
- package/esm2015/lib/api/item2.service.js +311 -0
- package/esm2015/lib/api/key-exchange.gql.js +188 -0
- package/esm2015/lib/api/key-exchange.service.js +442 -0
- package/esm2015/lib/api/key-exchange.types.js +18 -0
- package/esm2015/lib/api/key-exchange2.gql.js +171 -0
- package/esm2015/lib/api/key-exchange2.service.js +479 -0
- package/esm2015/lib/api/lock.gql.js +40 -0
- package/esm2015/lib/api/lock.service.js +64 -0
- package/esm2015/lib/api/lr-apollo.service.js +46 -0
- package/esm2015/lib/api/lr-graphql/index.js +6 -0
- package/esm2015/lib/api/lr-graphql/lr-graphql.service.js +155 -0
- package/esm2015/lib/api/lr-graphql/lr-merged-mutation.js +213 -0
- package/esm2015/lib/api/lr-graphql/lr-mutation-base.js +51 -0
- package/esm2015/lib/api/lr-graphql/lr-mutation.js +48 -0
- package/esm2015/lib/api/lr-graphql/lr.service.js +18 -0
- package/esm2015/lib/api/message.service.js +138 -0
- package/esm2015/lib/api/persist.service.js +181 -0
- package/esm2015/lib/api/query-processor/common-processors.service.js +93 -0
- package/esm2015/lib/api/query-processor/index.js +3 -0
- package/esm2015/lib/api/query-processor/query-processor.service.js +192 -0
- package/esm2015/lib/api/query-processor/tp-password-reset-processor.service.js +109 -0
- package/esm2015/lib/api/shared-contact-card.service.js +119 -0
- package/esm2015/lib/api/shared-contact-card2.gql.js +41 -0
- package/esm2015/lib/api/shared-contact-card2.service.js +117 -0
- package/esm2015/lib/api/time.service.js +146 -0
- package/esm2015/lib/api/types/graphql.types.js +7 -0
- package/esm2015/lib/api/types/index.js +3 -0
- package/esm2015/lib/api/types/lr-graphql.types.js +71 -0
- package/esm2015/lib/auth/auth.config.js +57 -0
- package/esm2015/lib/auth/auth.gql.js +48 -0
- package/esm2015/lib/auth/auth.types.js +27 -0
- package/esm2015/lib/auth/idle.service.js +168 -0
- package/esm2015/lib/auth/idle.types.js +7 -0
- package/esm2015/lib/auth/lbop.service.js +355 -0
- package/esm2015/lib/auth/life-ready-auth.service.js +500 -0
- package/esm2015/lib/auth/password.service.js +320 -0
- package/esm2015/lib/auth/register.service.js +172 -0
- package/esm2015/lib/auth/two-factor.service.js +74 -0
- package/esm2015/lib/category/category-meta.service.js +99 -0
- package/esm2015/lib/category/category.gql.js +406 -0
- package/esm2015/lib/category/category.service.js +390 -0
- package/esm2015/lib/category/category.types.js +29 -0
- package/esm2015/lib/cryptography/cryptography.types.js +11 -0
- package/esm2015/lib/cryptography/encryption.service.js +189 -0
- package/esm2015/lib/cryptography/key-factory.service.js +237 -0
- package/esm2015/lib/cryptography/key-graph.service.js +280 -0
- package/esm2015/lib/cryptography/key-meta.service.js +200 -0
- package/esm2015/lib/cryptography/key.service.js +124 -0
- package/esm2015/lib/cryptography/slip39.service.js +169 -0
- package/esm2015/lib/cryptography/web-crypto.service.js +29 -0
- package/esm2015/lib/life-ready.config.js +84 -0
- package/esm2015/lib/life-ready.module.js +74 -0
- package/esm2015/lib/plan/plan.gql.js +123 -0
- package/esm2015/lib/plan/plan.service.js +149 -0
- package/esm2015/lib/plan/plan.types.js +11 -0
- package/esm2015/lib/record/record-attachment.service.js +101 -0
- package/esm2015/lib/record/record.gql.js +179 -0
- package/esm2015/lib/record/record.service.js +206 -0
- package/esm2015/lib/record/record.types.js +15 -0
- package/esm2015/lib/record-type/record-type.service.js +75 -0
- package/esm2015/lib/record-type/record-type.types.js +28 -0
- package/esm2015/lib/scenario/approvals/scenario-approval.gql.js +105 -0
- package/esm2015/lib/scenario/approvals/scenario-approval.types.js +1 -0
- package/esm2015/lib/scenario/approvals/scenario-approver.service.js +300 -0
- package/esm2015/lib/scenario/claimants/scenario-claimant.gql.js +52 -0
- package/esm2015/lib/scenario/claimants/scenario-claimant.service.js +97 -0
- package/esm2015/lib/scenario/claimants/scenario-claimant.types.js +1 -0
- package/esm2015/lib/scenario/receivers/scenario-receiver.gql.js +150 -0
- package/esm2015/lib/scenario/receivers/scenario-receiver.service.js +229 -0
- package/esm2015/lib/scenario/receivers/scenario-receiver.types.js +1 -0
- package/esm2015/lib/scenario/scenario-setup.service.js +269 -0
- package/esm2015/lib/scenario/scenario.gql.js +368 -0
- package/esm2015/lib/scenario/scenario.service.js +611 -0
- package/esm2015/lib/scenario/scenario.types.js +64 -0
- package/esm2015/lib/search/search.gql.js +62 -0
- package/esm2015/lib/search/search.service.js +156 -0
- package/esm2015/lib/search/search.types.js +6 -0
- package/esm2015/lib/trusted-parties/tp-password-reset-request.service.js +112 -0
- package/esm2015/lib/trusted-parties/tp-password-reset-user.service.js +129 -0
- package/esm2015/lib/trusted-parties/tp-password-reset.constants.js +4 -0
- package/esm2015/lib/trusted-parties/tp-password-reset.gql.js +232 -0
- package/esm2015/lib/trusted-parties/tp-password-reset.service.js +299 -0
- package/esm2015/lib/trusted-parties/trusted-party.gql.js +148 -0
- package/esm2015/lib/trusted-parties/trusted-party.service.js +326 -0
- package/esm2015/lib/trusted-parties/trusted-party.types.js +41 -0
- package/esm2015/lib/trusted-parties/trusted-party2.gql.js +87 -0
- package/esm2015/lib/trusted-parties/trusted-party2.service.js +215 -0
- package/esm2015/lib/users/profile-details.service.js +214 -0
- package/esm2015/lib/users/profile.gql.js +97 -0
- package/esm2015/lib/users/profile.service.js +169 -0
- package/esm2015/lib/users/profile.types.js +34 -0
- package/esm2015/lib/users/user.gql.js +60 -0
- package/esm2015/lib/users/user.service.js +79 -0
- package/esm2015/lib/users/user.types.js +5 -0
- package/esm2015/lifeready-core.js +10 -0
- package/esm2015/public-api.js +81 -0
- package/fesm2015/lifeready-core.js +13314 -0
- package/fesm2015/lifeready-core.js.map +1 -0
- package/lib/_common/ast.d.ts +11 -0
- package/lib/_common/deferred-promise.d.ts +12 -0
- package/lib/_common/exceptions.d.ts +109 -0
- package/lib/_common/queries.gql.d.ts +10 -0
- package/lib/_common/run-outside-angular.d.ts +14 -0
- package/{src/lib/_common/types.ts → lib/_common/types.d.ts} +3 -6
- package/lib/_common/utils.d.ts +3 -0
- package/lib/api/contact-card.gql.d.ts +7 -0
- package/lib/api/contact-card.service.d.ts +52 -0
- package/lib/api/contact-card2.gql.d.ts +34 -0
- package/lib/api/contact-card2.service.d.ts +49 -0
- package/lib/api/file.service.d.ts +18 -0
- package/lib/api/item2.gql.d.ts +96 -0
- package/lib/api/item2.service.d.ts +177 -0
- package/lib/api/key-exchange.gql.d.ts +9 -0
- package/lib/api/key-exchange.service.d.ts +39 -0
- package/lib/api/key-exchange.types.d.ts +196 -0
- package/lib/api/key-exchange2.gql.d.ts +125 -0
- package/lib/api/key-exchange2.service.d.ts +187 -0
- package/lib/api/lock.gql.d.ts +27 -0
- package/lib/api/lock.service.d.ts +25 -0
- package/lib/api/lr-apollo.service.d.ts +15 -0
- package/lib/api/lr-graphql/lr-graphql.service.d.ts +60 -0
- package/lib/api/lr-graphql/lr-merged-mutation.d.ts +27 -0
- package/lib/api/lr-graphql/lr-mutation-base.d.ts +28 -0
- package/lib/api/lr-graphql/lr-mutation.d.ts +8 -0
- package/lib/api/lr-graphql/lr.service.d.ts +9 -0
- package/lib/api/message.service.d.ts +58 -0
- package/lib/api/persist.service.d.ts +31 -0
- package/lib/api/query-processor/common-processors.service.d.ts +36 -0
- package/lib/api/query-processor/query-processor.service.d.ts +18 -0
- package/lib/api/query-processor/tp-password-reset-processor.service.d.ts +15 -0
- package/lib/api/shared-contact-card.service.d.ts +33 -0
- package/lib/api/shared-contact-card2.gql.d.ts +36 -0
- package/lib/api/shared-contact-card2.service.d.ts +45 -0
- package/lib/api/time.service.d.ts +16 -0
- package/lib/api/types/graphql.types.d.ts +29 -0
- package/lib/api/types/lr-graphql.types.d.ts +385 -0
- package/lib/auth/auth.config.d.ts +5 -0
- package/lib/auth/auth.gql.d.ts +15 -0
- package/lib/auth/auth.types.d.ts +66 -0
- package/lib/auth/idle.service.d.ts +40 -0
- package/lib/auth/idle.types.d.ts +10 -0
- package/lib/auth/lbop.service.d.ts +91 -0
- package/lib/auth/life-ready-auth.service.d.ts +59 -0
- package/lib/auth/password.service.d.ts +78 -0
- package/lib/auth/register.service.d.ts +25 -0
- package/lib/auth/two-factor.service.d.ts +15 -0
- package/lib/category/category-meta.service.d.ts +23 -0
- package/lib/category/category.gql.d.ts +45 -0
- package/lib/category/category.service.d.ts +67 -0
- package/lib/category/category.types.d.ts +79 -0
- package/lib/cryptography/cryptography.types.d.ts +83 -0
- package/lib/cryptography/encryption.service.d.ts +41 -0
- package/lib/cryptography/key-factory.service.d.ts +38 -0
- package/lib/cryptography/key-graph.service.d.ts +33 -0
- package/lib/cryptography/key-meta.service.d.ts +44 -0
- package/lib/cryptography/key.service.d.ts +36 -0
- package/lib/cryptography/slip39.service.d.ts +43 -0
- package/lib/cryptography/web-crypto.service.d.ts +5 -0
- package/lib/life-ready.config.d.ts +14 -0
- package/lib/life-ready.module.d.ts +5 -0
- package/lib/plan/plan.gql.d.ts +11 -0
- package/lib/plan/plan.service.d.ts +33 -0
- package/lib/plan/plan.types.d.ts +31 -0
- package/lib/record/record-attachment.service.d.ts +16 -0
- package/lib/record/record.gql.d.ts +14 -0
- package/lib/record/record.service.d.ts +25 -0
- package/lib/record/record.types.d.ts +57 -0
- package/lib/record-type/record-type.service.d.ts +11 -0
- package/lib/record-type/record-type.types.d.ts +50 -0
- package/lib/scenario/approvals/scenario-approval.gql.d.ts +7 -0
- package/lib/scenario/approvals/scenario-approval.types.d.ts +63 -0
- package/lib/scenario/approvals/scenario-approver.service.d.ts +32 -0
- package/lib/scenario/claimants/scenario-claimant.gql.d.ts +5 -0
- package/lib/scenario/claimants/scenario-claimant.service.d.ts +17 -0
- package/lib/scenario/claimants/scenario-claimant.types.d.ts +18 -0
- package/lib/scenario/receivers/scenario-receiver.gql.d.ts +8 -0
- package/lib/scenario/receivers/scenario-receiver.service.d.ts +30 -0
- package/lib/scenario/receivers/scenario-receiver.types.d.ts +54 -0
- package/lib/scenario/scenario-setup.service.d.ts +22 -0
- package/lib/scenario/scenario.gql.d.ts +34 -0
- package/lib/scenario/scenario.service.d.ts +58 -0
- package/lib/scenario/scenario.types.d.ts +217 -0
- package/lib/search/search.gql.d.ts +1 -0
- package/lib/search/search.service.d.ts +25 -0
- package/lib/search/search.types.d.ts +20 -0
- package/lib/trusted-parties/tp-password-reset-request.service.d.ts +20 -0
- package/lib/trusted-parties/tp-password-reset-user.service.d.ts +35 -0
- package/lib/trusted-parties/tp-password-reset.constants.d.ts +3 -0
- package/lib/trusted-parties/tp-password-reset.gql.d.ts +218 -0
- package/lib/trusted-parties/tp-password-reset.service.d.ts +130 -0
- package/lib/trusted-parties/trusted-party.gql.d.ts +9 -0
- package/lib/trusted-parties/trusted-party.service.d.ts +44 -0
- package/lib/trusted-parties/trusted-party.types.d.ts +102 -0
- package/lib/trusted-parties/trusted-party2.gql.d.ts +79 -0
- package/lib/trusted-parties/trusted-party2.service.d.ts +114 -0
- package/lib/users/profile-details.service.d.ts +21 -0
- package/lib/users/profile.gql.d.ts +11 -0
- package/lib/users/profile.service.d.ts +35 -0
- package/lib/users/profile.types.d.ts +96 -0
- package/lib/users/user.gql.d.ts +9 -0
- package/lib/users/user.service.d.ts +12 -0
- package/lib/users/user.types.d.ts +23 -0
- package/lifeready-core.d.ts +9 -0
- package/lifeready-core.metadata.json +1 -0
- package/package.json +29 -21
- package/{src/public-api.ts → public-api.d.ts} +0 -19
- package/karma.conf.js +0 -32
- package/ng-package.json +0 -26
- package/src/lib/_common/ast.ts +0 -75
- package/src/lib/_common/deferred-promise.ts +0 -35
- package/src/lib/_common/exceptions.ts +0 -189
- package/src/lib/_common/queries.gql.ts +0 -200
- package/src/lib/_common/run-outside-angular.ts +0 -125
- package/src/lib/_common/tests.ts +0 -82
- package/src/lib/_common/utils.ts +0 -57
- package/src/lib/api/api-mutation.spec.ts +0 -547
- package/src/lib/api/api-query.spec.ts +0 -40
- package/src/lib/api/contact-card.gql.ts +0 -85
- package/src/lib/api/contact-card.service.spec.ts +0 -249
- package/src/lib/api/contact-card.service.ts +0 -228
- package/src/lib/api/contact-card2.gql.ts +0 -93
- package/src/lib/api/contact-card2.service.spec.ts +0 -297
- package/src/lib/api/contact-card2.service.ts +0 -139
- package/src/lib/api/file.service.spec.ts +0 -14
- package/src/lib/api/file.service.ts +0 -81
- package/src/lib/api/item2.gql.ts +0 -211
- package/src/lib/api/item2.service.spec.ts +0 -1043
- package/src/lib/api/item2.service.ts +0 -481
- package/src/lib/api/key-exchange.gql.ts +0 -196
- package/src/lib/api/key-exchange.service.spec.ts +0 -470
- package/src/lib/api/key-exchange.service.ts +0 -731
- package/src/lib/api/key-exchange.types.ts +0 -235
- package/src/lib/api/key-exchange2.gql.ts +0 -310
- package/src/lib/api/key-exchange2.service.spec.ts +0 -892
- package/src/lib/api/key-exchange2.service.ts +0 -875
- package/src/lib/api/lock.gql.ts +0 -67
- package/src/lib/api/lock.service.spec.ts +0 -549
- package/src/lib/api/lock.service.ts +0 -57
- package/src/lib/api/lr-apollo.service.spec.ts +0 -27
- package/src/lib/api/lr-apollo.service.ts +0 -43
- package/src/lib/api/lr-graphql/lr-graphql.service.ts +0 -313
- package/src/lib/api/lr-graphql/lr-merged-mutation.ts +0 -377
- package/src/lib/api/lr-graphql/lr-mutation-base.ts +0 -67
- package/src/lib/api/lr-graphql/lr-mutation.ts +0 -74
- package/src/lib/api/lr-graphql/lr.service.ts +0 -28
- package/src/lib/api/message.service.spec.ts +0 -20
- package/src/lib/api/message.service.ts +0 -210
- package/src/lib/api/persist.service.spec.ts +0 -209
- package/src/lib/api/persist.service.ts +0 -220
- package/src/lib/api/query-processor/common-processors.service.ts +0 -148
- package/src/lib/api/query-processor/query-processor.service.ts +0 -240
- package/src/lib/api/query-processor/tp-password-reset-processor.service.ts +0 -177
- package/src/lib/api/shared-contact-card.service.ts +0 -156
- package/src/lib/api/shared-contact-card2.gql.ts +0 -76
- package/src/lib/api/shared-contact-card2.service.ts +0 -154
- package/src/lib/api/time.service.spec.ts +0 -48
- package/src/lib/api/time.service.ts +0 -155
- package/src/lib/api/types/graphql.types.ts +0 -48
- package/src/lib/api/types/lr-graphql.types.ts +0 -467
- package/src/lib/auth/auth.config.ts +0 -83
- package/src/lib/auth/auth.gql.ts +0 -62
- package/src/lib/auth/auth.types.ts +0 -79
- package/src/lib/auth/idle.service.spec.ts +0 -119
- package/src/lib/auth/idle.service.ts +0 -208
- package/src/lib/auth/idle.types.ts +0 -11
- package/src/lib/auth/lbop.service.spec.ts +0 -56
- package/src/lib/auth/lbop.service.ts +0 -539
- package/src/lib/auth/life-ready-auth.service.spec.ts +0 -70
- package/src/lib/auth/life-ready-auth.service.ts +0 -454
- package/src/lib/auth/password.service.spec.ts +0 -51
- package/src/lib/auth/password.service.ts +0 -438
- package/src/lib/auth/register.service.spec.ts +0 -31
- package/src/lib/auth/register.service.ts +0 -181
- package/src/lib/auth/two-factor.service.spec.ts +0 -21
- package/src/lib/auth/two-factor.service.ts +0 -69
- package/src/lib/category/category-meta.service.spec.ts +0 -28
- package/src/lib/category/category-meta.service.ts +0 -125
- package/src/lib/category/category.gql.ts +0 -449
- package/src/lib/category/category.service.spec.ts +0 -26
- package/src/lib/category/category.service.ts +0 -498
- package/src/lib/category/category.types.ts +0 -89
- package/src/lib/cryptography/cryptography.types.ts +0 -108
- package/src/lib/cryptography/encryption.service.spec.ts +0 -125
- package/src/lib/cryptography/encryption.service.ts +0 -243
- package/src/lib/cryptography/key-factory.service.spec.ts +0 -15
- package/src/lib/cryptography/key-factory.service.ts +0 -303
- package/src/lib/cryptography/key-graph.service.spec.ts +0 -16
- package/src/lib/cryptography/key-graph.service.ts +0 -354
- package/src/lib/cryptography/key-meta.service.spec.ts +0 -40
- package/src/lib/cryptography/key-meta.service.ts +0 -254
- package/src/lib/cryptography/key.service.spec.ts +0 -16
- package/src/lib/cryptography/key.service.ts +0 -154
- package/src/lib/cryptography/slip39.service.spec.ts +0 -44
- package/src/lib/cryptography/slip39.service.ts +0 -204
- package/src/lib/cryptography/web-crypto.service.ts +0 -22
- package/src/lib/life-ready.config.ts +0 -127
- package/src/lib/life-ready.module.ts +0 -81
- package/src/lib/plan/plan.gql.ts +0 -133
- package/src/lib/plan/plan.service.spec.ts +0 -294
- package/src/lib/plan/plan.service.ts +0 -198
- package/src/lib/plan/plan.types.ts +0 -37
- package/src/lib/record/record-attachment.service.spec.ts +0 -31
- package/src/lib/record/record-attachment.service.ts +0 -101
- package/src/lib/record/record.gql.ts +0 -192
- package/src/lib/record/record.service.spec.ts +0 -598
- package/src/lib/record/record.service.ts +0 -236
- package/src/lib/record/record.types.ts +0 -86
- package/src/lib/record-type/record-type.service.spec.ts +0 -16
- package/src/lib/record-type/record-type.service.ts +0 -71
- package/src/lib/record-type/record-type.types.ts +0 -58
- package/src/lib/scenario/approvals/scenario-approval.gql.ts +0 -112
- package/src/lib/scenario/approvals/scenario-approval.types.ts +0 -85
- package/src/lib/scenario/approvals/scenario-approver.service.spec.ts +0 -16
- package/src/lib/scenario/approvals/scenario-approver.service.ts +0 -422
- package/src/lib/scenario/claimants/scenario-claimant.gql.ts +0 -56
- package/src/lib/scenario/claimants/scenario-claimant.service.spec.ts +0 -16
- package/src/lib/scenario/claimants/scenario-claimant.service.ts +0 -100
- package/src/lib/scenario/claimants/scenario-claimant.types.ts +0 -21
- package/src/lib/scenario/receivers/scenario-receiver.gql.ts +0 -157
- package/src/lib/scenario/receivers/scenario-receiver.service.spec.ts +0 -16
- package/src/lib/scenario/receivers/scenario-receiver.service.ts +0 -278
- package/src/lib/scenario/receivers/scenario-receiver.types.ts +0 -66
- package/src/lib/scenario/scenario-setup.service.spec.ts +0 -22
- package/src/lib/scenario/scenario-setup.service.ts +0 -369
- package/src/lib/scenario/scenario.gql.ts +0 -404
- package/src/lib/scenario/scenario.service.spec.ts +0 -1586
- package/src/lib/scenario/scenario.service.ts +0 -811
- package/src/lib/scenario/scenario.types.ts +0 -258
- package/src/lib/search/search.gql.ts +0 -62
- package/src/lib/search/search.service.spec.ts +0 -57
- package/src/lib/search/search.service.ts +0 -174
- package/src/lib/search/search.types.ts +0 -24
- package/src/lib/trusted-parties/tp-password-reset-request.service.ts +0 -140
- package/src/lib/trusted-parties/tp-password-reset-user.service.ts +0 -359
- package/src/lib/trusted-parties/tp-password-reset.gql.ts +0 -453
- package/src/lib/trusted-parties/tp-password-reset.service.spec.ts +0 -602
- package/src/lib/trusted-parties/tp-password-reset.service.ts +0 -482
- package/src/lib/trusted-parties/trusted-party.gql.ts +0 -159
- package/src/lib/trusted-parties/trusted-party.service.spec.ts +0 -1008
- package/src/lib/trusted-parties/trusted-party.service.ts +0 -394
- package/src/lib/trusted-parties/trusted-party.types.ts +0 -119
- package/src/lib/trusted-parties/trusted-party2.gql.ts +0 -165
- package/src/lib/trusted-parties/trusted-party2.service.spec.ts +0 -1782
- package/src/lib/trusted-parties/trusted-party2.service.ts +0 -272
- package/src/lib/users/profile-details.service.spec.ts +0 -45
- package/src/lib/users/profile-details.service.ts +0 -278
- package/src/lib/users/profile.gql.ts +0 -108
- package/src/lib/users/profile.service.spec.ts +0 -97
- package/src/lib/users/profile.service.ts +0 -224
- package/src/lib/users/profile.types.ts +0 -101
- package/src/lib/users/user.gql.ts +0 -69
- package/src/lib/users/user.service.spec.ts +0 -161
- package/src/lib/users/user.service.ts +0 -72
- package/src/lib/users/user.types.ts +0 -27
- package/src/test.ts +0 -21
- package/tsconfig.lib.json +0 -21
- package/tsconfig.lib.prod.json +0 -6
- package/tsconfig.spec.json +0 -10
- package/tslint.json +0 -17
- /package/{src/lib/api/lr-graphql/index.ts → lib/api/lr-graphql/index.d.ts} +0 -0
- /package/{src/lib/api/query-processor/index.ts → lib/api/query-processor/index.d.ts} +0 -0
- /package/{src/lib/api/types/index.ts → lib/api/types/index.d.ts} +0 -0
|
@@ -1,438 +0,0 @@
|
|
|
1
|
-
import { HttpClient } from '@angular/common/http';
|
|
2
|
-
import { Inject, Injectable } from '@angular/core';
|
|
3
|
-
import { CognitoUser } from '@aws-amplify/auth';
|
|
4
|
-
import { AuthClass } from '@aws-amplify/auth/lib-esm/Auth';
|
|
5
|
-
import { JWK, JWS } from 'node-jose';
|
|
6
|
-
import { ProfileService } from '../users/profile.service';
|
|
7
|
-
import { EncryptionService } from '../cryptography/encryption.service';
|
|
8
|
-
import { KeyGraphService } from '../cryptography/key-graph.service';
|
|
9
|
-
import { LifeReadyConfig, LR_CONFIG } from '../life-ready.config';
|
|
10
|
-
import { LrAuthException, LrBadArgumentException } from '../_common/exceptions';
|
|
11
|
-
import { LrApolloService } from './../api/lr-apollo.service';
|
|
12
|
-
import {
|
|
13
|
-
PasswordChangeMutation,
|
|
14
|
-
PasswordChangeRequestMutation,
|
|
15
|
-
PasswordChangeConfigQuery,
|
|
16
|
-
} from './auth.gql';
|
|
17
|
-
import { PassKeyBundle } from './auth.types';
|
|
18
|
-
import { WebCryptoService } from '../cryptography/web-crypto.service';
|
|
19
|
-
import { Duration } from 'moment';
|
|
20
|
-
import * as moment_ from 'moment';
|
|
21
|
-
import { ApiCurrentUser } from '../users/profile.types';
|
|
22
|
-
import { IdleService } from '../auth/idle.service';
|
|
23
|
-
import { KeyFactoryService as KFS } from '../cryptography/key-factory.service';
|
|
24
|
-
|
|
25
|
-
// "why?" you ask: https://stackoverflow.com/questions/59735280/angular-8-moment-error-cannot-call-a-namespace-moment
|
|
26
|
-
const moment = moment_;
|
|
27
|
-
|
|
28
|
-
interface PasswordChangeRequestMutation {
|
|
29
|
-
passwordChangeRequest: {
|
|
30
|
-
challenge: {
|
|
31
|
-
serverNonce: string;
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface PasswordChangeMutation {
|
|
37
|
-
passwordChange: {
|
|
38
|
-
token: string;
|
|
39
|
-
newPassKey: {
|
|
40
|
-
id: string;
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface PasswordChangeConfig {
|
|
46
|
-
maxAuthAgeSeconds: number;
|
|
47
|
-
authTime: string | Date;
|
|
48
|
-
serverTime: string | Date;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export class PasswordCheck {
|
|
52
|
-
length?: number;
|
|
53
|
-
timeToCrack?: Duration;
|
|
54
|
-
passwordExposed?: number;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
@Injectable({
|
|
58
|
-
providedIn: 'root',
|
|
59
|
-
})
|
|
60
|
-
export class PasswordService {
|
|
61
|
-
private readonly CLIENT_NONCE_LENGTH = 32;
|
|
62
|
-
|
|
63
|
-
constructor(
|
|
64
|
-
@Inject(LR_CONFIG) private config: LifeReadyConfig,
|
|
65
|
-
private http: HttpClient,
|
|
66
|
-
private apollo: LrApolloService,
|
|
67
|
-
private auth: AuthClass,
|
|
68
|
-
private profileService: ProfileService,
|
|
69
|
-
private keyFactory: KFS,
|
|
70
|
-
private encryptionService: EncryptionService,
|
|
71
|
-
private keyGraph: KeyGraphService,
|
|
72
|
-
private webCryptoService: WebCryptoService,
|
|
73
|
-
private idleService: IdleService
|
|
74
|
-
) {}
|
|
75
|
-
|
|
76
|
-
public async checkPassword(password: string): Promise<PasswordCheck> {
|
|
77
|
-
const { years } = this.passwordStrength(password);
|
|
78
|
-
|
|
79
|
-
return {
|
|
80
|
-
length: password.length,
|
|
81
|
-
timeToCrack: moment.duration({ years }),
|
|
82
|
-
passwordExposed: await this.getExposureCount(password),
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
public async getExposureCount(password: string): Promise<number> {
|
|
87
|
-
const sha1Password = await this.webCryptoService.stringDigest(
|
|
88
|
-
'SHA-1',
|
|
89
|
-
password
|
|
90
|
-
);
|
|
91
|
-
const first5sha1 = sha1Password.substring(0, 5);
|
|
92
|
-
|
|
93
|
-
const response = await this.http
|
|
94
|
-
.get(`https://api.pwnedpasswords.com/range/${first5sha1}`, {
|
|
95
|
-
responseType: 'text',
|
|
96
|
-
})
|
|
97
|
-
.toPromise();
|
|
98
|
-
|
|
99
|
-
const results = new RegExp(
|
|
100
|
-
`^(?:${sha1Password.substring(5)}:)(?<count>\\d+)$`,
|
|
101
|
-
'im'
|
|
102
|
-
).exec(response);
|
|
103
|
-
|
|
104
|
-
if (results) {
|
|
105
|
-
return +results.groups.count;
|
|
106
|
-
}
|
|
107
|
-
return 0;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
public getPassIdpString(passIdp: JWK.Key) {
|
|
111
|
-
return (passIdp.toJSON(true) as any).k;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
public async createPassKeyBundle(password: string): Promise<PassKeyBundle> {
|
|
115
|
-
const passIdpParams = await this.keyFactory.createPassIdpParams();
|
|
116
|
-
const passIdp = (
|
|
117
|
-
await this.keyFactory.derivePassIdp({
|
|
118
|
-
password,
|
|
119
|
-
...passIdpParams,
|
|
120
|
-
})
|
|
121
|
-
).jwk;
|
|
122
|
-
|
|
123
|
-
const passKeyParams = await this.keyFactory.createPassKeyParams();
|
|
124
|
-
const passKey = (
|
|
125
|
-
await this.keyFactory.derivePassKey({
|
|
126
|
-
password,
|
|
127
|
-
...passKeyParams,
|
|
128
|
-
})
|
|
129
|
-
).jwk;
|
|
130
|
-
|
|
131
|
-
const passIdpVerifier = await this.keyFactory.createPkcSignKey();
|
|
132
|
-
|
|
133
|
-
const wrappedPassIdpVerifierPrk = await this.encryptionService.encrypt(
|
|
134
|
-
passKey,
|
|
135
|
-
passIdpVerifier.toJSON(true)
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
// There are two formats that the private key can be represented in JWK:
|
|
139
|
-
// https://tools.ietf.org/html/rfc8017#page-9
|
|
140
|
-
// The second form is an optimization:
|
|
141
|
-
// https://crypto.stackexchange.com/questions/19413/what-are-dp-and-dq-in-encryption-by-rsa-in-c
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
passKeyParams,
|
|
145
|
-
passKey,
|
|
146
|
-
passIdpParams,
|
|
147
|
-
passIdp,
|
|
148
|
-
passIdpVerifier,
|
|
149
|
-
wrappedPassIdpVerifierPrk,
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* We need to allow for interruption of the process at any point. Each API call can be considered
|
|
155
|
-
* atomic and either succeeds or fails.
|
|
156
|
-
*
|
|
157
|
-
* The LR server APIs use semaphore tokens for locking critical operations, so concurrent calls will
|
|
158
|
-
* fail.
|
|
159
|
-
*
|
|
160
|
-
* We assume the worst case for IdP API calls. So we use the semaphore token from LR to prevent
|
|
161
|
-
* concurrent calls to IdP APIs, but we have to assume that the IdP API calls will either succeed or
|
|
162
|
-
* fail within a reasonable amount of time.
|
|
163
|
-
*
|
|
164
|
-
* Each location where the server state changes can be a potential point of interruption.
|
|
165
|
-
* Potential points of interruption are marked with: --Potential Failure Point--
|
|
166
|
-
*
|
|
167
|
-
* Places for timeout:
|
|
168
|
-
* - Login age too old at call to: verifyPassword()
|
|
169
|
-
* - Login age too old at call to: changePasswordMutation()
|
|
170
|
-
* - Semaphore token expires at call to: changePasswordComplete()
|
|
171
|
-
*
|
|
172
|
-
* Tests:
|
|
173
|
-
* - Potential Failure Point 1: should be able to restart the process, user remains signed in.
|
|
174
|
-
* - Potential Failure Point 2: should enter recovery flow
|
|
175
|
-
* - Potential Failure Point 3: should enter recovery flow
|
|
176
|
-
* - Potential Failure Point 4: should enter recovery flow
|
|
177
|
-
*
|
|
178
|
-
*/
|
|
179
|
-
|
|
180
|
-
public async isLoginRequired(): Promise<boolean> {
|
|
181
|
-
const changePasswordConfig = await this.getChangePasswordConfig();
|
|
182
|
-
const authTime = moment(changePasswordConfig.authTime);
|
|
183
|
-
const serverTime = moment(changePasswordConfig.serverTime);
|
|
184
|
-
const duration = moment.duration(serverTime.diff(authTime));
|
|
185
|
-
const seconds = duration.asSeconds();
|
|
186
|
-
if (seconds > changePasswordConfig.maxAuthAgeSeconds) {
|
|
187
|
-
return true;
|
|
188
|
-
} else {
|
|
189
|
-
return false;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
public async changePassword(password: string, newPassword: string) {
|
|
194
|
-
const cognitoUser: CognitoUser = await this.auth.currentAuthenticatedUser();
|
|
195
|
-
|
|
196
|
-
// Validation
|
|
197
|
-
// todo: Add this back in
|
|
198
|
-
// Note the passIdp will always have a random salt, so will always be different to the current passIdp.
|
|
199
|
-
if (password === newPassword) {
|
|
200
|
-
throw new LrBadArgumentException(
|
|
201
|
-
'New password is the same as the current one.'
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const { currentUser } = await this.profileService.getCurrentUser();
|
|
206
|
-
|
|
207
|
-
const { passIdp, signedChallenge } = await this.verifyPassword(
|
|
208
|
-
password,
|
|
209
|
-
currentUser
|
|
210
|
-
);
|
|
211
|
-
|
|
212
|
-
// --Potential Failure Point 1--
|
|
213
|
-
// verifyPassword() asks for a current password challenge hence changes server state.
|
|
214
|
-
// Place break points here to test the failure scenarios.
|
|
215
|
-
|
|
216
|
-
// Generate the new passIdp
|
|
217
|
-
const newPassKey = await this.createPassKeyBundle(newPassword);
|
|
218
|
-
|
|
219
|
-
// Re-encrypt master key with new key
|
|
220
|
-
const masterKey = await this.keyGraph.getKey(
|
|
221
|
-
currentUser.currentUserKey.masterKey.id
|
|
222
|
-
);
|
|
223
|
-
const newWrappedMasterKey = await this.encryptionService.encrypt(
|
|
224
|
-
newPassKey.passKey,
|
|
225
|
-
masterKey.jwk.toJSON(true)
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
// If the IdP change password failed, we need to go into recovery mode by forcing
|
|
229
|
-
// a login. We can't logout the user just yet since the IdP password change needs
|
|
230
|
-
// the user to be logged in. We _can_ removed any persisted session values for the IdP
|
|
231
|
-
// but that seems like too much trouble.
|
|
232
|
-
|
|
233
|
-
const { token, newPassKeyId } = await this.changePasswordMutation(
|
|
234
|
-
signedChallenge,
|
|
235
|
-
currentUser.currentUserKey.masterKey.id,
|
|
236
|
-
newWrappedMasterKey,
|
|
237
|
-
newPassKey
|
|
238
|
-
);
|
|
239
|
-
|
|
240
|
-
// --Potential Failure Point 2--
|
|
241
|
-
// changePasswordMutation() uploads new keys and obtains a semaphore lock to prevent any other
|
|
242
|
-
// clients from performing IdP password change.
|
|
243
|
-
|
|
244
|
-
// Now we can do the IdP password change.
|
|
245
|
-
// todo: Add this back in
|
|
246
|
-
await this.auth.changePassword(
|
|
247
|
-
cognitoUser,
|
|
248
|
-
this.getPassIdpString(passIdp),
|
|
249
|
-
this.getPassIdpString(newPassKey.passIdp)
|
|
250
|
-
);
|
|
251
|
-
|
|
252
|
-
// --Potential Failure Point 3--
|
|
253
|
-
// IdP password change
|
|
254
|
-
|
|
255
|
-
// Note that changePassword() could throw an exception for a number of reason. It could throw
|
|
256
|
-
// a network timeout for example. But we don't know if it's the response that timed out and
|
|
257
|
-
// the idp password change was actually carried out. So we have to be extra conservative and
|
|
258
|
-
// only act on a clear success. Otherwise we go into recover mode.
|
|
259
|
-
await this.changePasswordComplete(
|
|
260
|
-
cognitoUser.getSignInUserSession().getAccessToken().getJwtToken(),
|
|
261
|
-
true,
|
|
262
|
-
token
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
public async changePasswordComplete(
|
|
267
|
-
accessToken: string,
|
|
268
|
-
useNewPassword: boolean,
|
|
269
|
-
token: string = null
|
|
270
|
-
): Promise<any> {
|
|
271
|
-
return this.http
|
|
272
|
-
.post(
|
|
273
|
-
`${this.config.authUrl}users/password-change-complete/`,
|
|
274
|
-
{
|
|
275
|
-
use_new_password: useNewPassword,
|
|
276
|
-
...(token && { token }),
|
|
277
|
-
},
|
|
278
|
-
{
|
|
279
|
-
headers: {
|
|
280
|
-
Authorization: `Bearer ${accessToken}`,
|
|
281
|
-
},
|
|
282
|
-
}
|
|
283
|
-
)
|
|
284
|
-
.toPromise();
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
private async getVerifierPrK(
|
|
288
|
-
passKey: JWK.Key,
|
|
289
|
-
wrappedPrK: object
|
|
290
|
-
): Promise<JWK.Key> {
|
|
291
|
-
try {
|
|
292
|
-
const prkJson = await this.encryptionService.decrypt(passKey, wrappedPrK);
|
|
293
|
-
return KFS.asKey(prkJson);
|
|
294
|
-
} catch (error) {
|
|
295
|
-
throw new LrAuthException('Wrong current password');
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
private async verifyPassword(
|
|
300
|
-
password: string,
|
|
301
|
-
currentUser: ApiCurrentUser
|
|
302
|
-
): Promise<{ passIdp: JWK.Key; signedChallenge: JWS.CreateSignResult }> {
|
|
303
|
-
// Get information from the server to prepare for password change.
|
|
304
|
-
const passwordRequest = await this.apollo.mutate<PasswordChangeRequestMutation>(
|
|
305
|
-
{
|
|
306
|
-
mutation: PasswordChangeRequestMutation,
|
|
307
|
-
variables: {},
|
|
308
|
-
}
|
|
309
|
-
);
|
|
310
|
-
|
|
311
|
-
// Get the old passKey so we can decrypt the old password verifier
|
|
312
|
-
const passKeyResult = await this.keyFactory.derivePassKey({
|
|
313
|
-
password,
|
|
314
|
-
...currentUser.currentUserKey.passKey.passKeyParams,
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
const verifierPrK = await this.getVerifierPrK(
|
|
318
|
-
passKeyResult.jwk,
|
|
319
|
-
currentUser.currentUserKey.passKey.wrappedPassIdpVerifierPrk
|
|
320
|
-
);
|
|
321
|
-
|
|
322
|
-
// Sign the server challenge to prove to the server we can decrypt the password verifier.
|
|
323
|
-
// Generate
|
|
324
|
-
const clientNonce = this.keyFactory.randomString(this.CLIENT_NONCE_LENGTH);
|
|
325
|
-
|
|
326
|
-
const signedChallenge = await this.encryptionService.sign(verifierPrK, {
|
|
327
|
-
serverNonce: passwordRequest.passwordChangeRequest.challenge.serverNonce,
|
|
328
|
-
clientNonce,
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
const passIdpResult = await this.keyFactory.derivePassIdp({
|
|
332
|
-
password,
|
|
333
|
-
...currentUser.currentUserKey.passKey.passIdpParams,
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
return {
|
|
337
|
-
passIdp: passIdpResult.jwk,
|
|
338
|
-
signedChallenge,
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
private async changePasswordMutation(
|
|
343
|
-
signedChallenge: JWS.CreateSignResult,
|
|
344
|
-
masterKeyId: string,
|
|
345
|
-
newWrappedMasterKey: object,
|
|
346
|
-
passKeyBundle: PassKeyBundle
|
|
347
|
-
): Promise<{ token: string; newPassKeyId: string }> {
|
|
348
|
-
const response = await this.apollo.mutate<PasswordChangeMutation>({
|
|
349
|
-
mutation: PasswordChangeMutation,
|
|
350
|
-
variables: {
|
|
351
|
-
input: {
|
|
352
|
-
signedChallenge: JSON.stringify(signedChallenge),
|
|
353
|
-
masterKeyId,
|
|
354
|
-
newWrappedMasterKey: JSON.stringify(newWrappedMasterKey),
|
|
355
|
-
newPassKey: {
|
|
356
|
-
passIdpParams: JSON.stringify(passKeyBundle.passIdpParams),
|
|
357
|
-
passIdpVerifierPbk: JSON.stringify(
|
|
358
|
-
passKeyBundle.passIdpVerifier.toJSON()
|
|
359
|
-
),
|
|
360
|
-
wrappedPassIdpVerifierPrk: JSON.stringify(
|
|
361
|
-
passKeyBundle.wrappedPassIdpVerifierPrk
|
|
362
|
-
),
|
|
363
|
-
passKeyParams: JSON.stringify(passKeyBundle.passKeyParams),
|
|
364
|
-
},
|
|
365
|
-
},
|
|
366
|
-
},
|
|
367
|
-
});
|
|
368
|
-
return {
|
|
369
|
-
token: response.passwordChange.token,
|
|
370
|
-
newPassKeyId: response.passwordChange.newPassKey.id,
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
async getChangePasswordConfig(): Promise<PasswordChangeConfig> {
|
|
375
|
-
const res = await this.apollo.query<any>({
|
|
376
|
-
query: PasswordChangeConfigQuery,
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
const ret = res.passwordChangeConfig as PasswordChangeConfig;
|
|
380
|
-
|
|
381
|
-
ret.authTime = new Date(ret.authTime);
|
|
382
|
-
ret.serverTime = new Date(ret.serverTime);
|
|
383
|
-
return ret;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
public passwordStrength(password): { years: number; bits: number } {
|
|
387
|
-
const upper = /[A-Z]/g;
|
|
388
|
-
const lower = /[a-z]/g;
|
|
389
|
-
const digit = /[0-9]/g;
|
|
390
|
-
|
|
391
|
-
const upperChoices = 26;
|
|
392
|
-
const lowerChoices = 26;
|
|
393
|
-
const digitChoices = 10;
|
|
394
|
-
const specialChoices = 30; // /[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/g
|
|
395
|
-
|
|
396
|
-
function instanceCount(str, re) {
|
|
397
|
-
return ((str || '').match(re) || []).length;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
const uppers = instanceCount(password, upper);
|
|
401
|
-
const lowers = instanceCount(password, lower);
|
|
402
|
-
const digits = instanceCount(password, digit);
|
|
403
|
-
const specials = password.length - uppers - lowers - digits;
|
|
404
|
-
|
|
405
|
-
let choices = 0;
|
|
406
|
-
if (uppers) {
|
|
407
|
-
choices += upperChoices;
|
|
408
|
-
}
|
|
409
|
-
if (lowers) {
|
|
410
|
-
choices += lowerChoices;
|
|
411
|
-
}
|
|
412
|
-
if (digits) {
|
|
413
|
-
choices += digitChoices;
|
|
414
|
-
}
|
|
415
|
-
if (specials) {
|
|
416
|
-
choices += specialChoices;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
if (password.length === 0) {
|
|
420
|
-
return {
|
|
421
|
-
years: 0,
|
|
422
|
-
// bits of entropy
|
|
423
|
-
bits: 0,
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
const permutations = Math.pow(choices, password.length);
|
|
428
|
-
|
|
429
|
-
const years =
|
|
430
|
-
(54000 * permutations) /
|
|
431
|
-
Math.pow(upperChoices + lowerChoices + digitChoices, 12);
|
|
432
|
-
return {
|
|
433
|
-
years,
|
|
434
|
-
// bits of entropy
|
|
435
|
-
bits: Math.round(Math.log2(permutations)),
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { TestBed } from '@angular/core/testing';
|
|
2
|
-
import { lrConfigureTestingModule, lrit } from '../_common/tests';
|
|
3
|
-
import { RegisterService } from './register.service';
|
|
4
|
-
|
|
5
|
-
const TIMEOUT = 1000 * 60 * 10;
|
|
6
|
-
|
|
7
|
-
describe('RegisterService', () => {
|
|
8
|
-
let service: RegisterService;
|
|
9
|
-
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
lrConfigureTestingModule();
|
|
12
|
-
service = TestBed.inject(RegisterService);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('should be created', () => {
|
|
16
|
-
expect(service).toBeTruthy();
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
lrit(
|
|
20
|
-
'should check hibp',
|
|
21
|
-
async () => {
|
|
22
|
-
let res = await service.hibpBreachedAccounts('test@example.com');
|
|
23
|
-
expect(res.length).toBeGreaterThan(0);
|
|
24
|
-
|
|
25
|
-
// Should not have any breaches.
|
|
26
|
-
res = await service.hibpBreachedAccounts('test@xthsygdsdocs.com');
|
|
27
|
-
expect(res).toBe(null);
|
|
28
|
-
},
|
|
29
|
-
TIMEOUT
|
|
30
|
-
);
|
|
31
|
-
});
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { HttpClient } from '@angular/common/http';
|
|
2
|
-
import { Inject, Injectable } from '@angular/core';
|
|
3
|
-
import { AuthClass } from '@aws-amplify/auth/lib-esm/Auth';
|
|
4
|
-
import { EncryptionService } from '../cryptography/encryption.service';
|
|
5
|
-
import { KeyFactoryService } from '../cryptography/key-factory.service';
|
|
6
|
-
import { LifeReadyConfig, LR_CONFIG } from '../life-ready.config';
|
|
7
|
-
import { PasswordService } from './password.service';
|
|
8
|
-
import { RegisterResult } from './auth.types';
|
|
9
|
-
|
|
10
|
-
@Injectable({
|
|
11
|
-
providedIn: 'root',
|
|
12
|
-
})
|
|
13
|
-
export class RegisterService {
|
|
14
|
-
constructor(
|
|
15
|
-
@Inject(LR_CONFIG) private config: LifeReadyConfig,
|
|
16
|
-
private auth: AuthClass,
|
|
17
|
-
private http: HttpClient,
|
|
18
|
-
private keyFactory: KeyFactoryService,
|
|
19
|
-
private encryptionService: EncryptionService,
|
|
20
|
-
private passwordService: PasswordService
|
|
21
|
-
) {}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Request a verification code to be sent out to an email.
|
|
25
|
-
* @return Info needed to be submitted along with the verification code
|
|
26
|
-
*/
|
|
27
|
-
public async verifyEmail(email: string): Promise<string> {
|
|
28
|
-
const { claim_id } = await this.http
|
|
29
|
-
.post<{ claim_id }>(`${this.config.authUrl}cove/claim/email/`, {
|
|
30
|
-
address: email,
|
|
31
|
-
context: 'signup',
|
|
32
|
-
})
|
|
33
|
-
.toPromise();
|
|
34
|
-
return claim_id;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
public async verifyPhone(phoneNumber: string): Promise<string> {
|
|
38
|
-
const { claim_id } = await this.http
|
|
39
|
-
.post<{ claim_id }>(`${this.config.authUrl}cove/claim/sms/`, {
|
|
40
|
-
address: phoneNumber,
|
|
41
|
-
context: 'signup',
|
|
42
|
-
})
|
|
43
|
-
.toPromise();
|
|
44
|
-
return claim_id;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
public async confirmVerificationCode(
|
|
48
|
-
verificationId: string,
|
|
49
|
-
verificationCode: string
|
|
50
|
-
): Promise<string> {
|
|
51
|
-
const { token } = await this.http
|
|
52
|
-
.post<{ token }>(`${this.config.authUrl}cove/respond/`, {
|
|
53
|
-
claim_id: verificationId,
|
|
54
|
-
v_code: verificationCode,
|
|
55
|
-
})
|
|
56
|
-
.toPromise();
|
|
57
|
-
return token;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
public async register(
|
|
61
|
-
email: string,
|
|
62
|
-
password: string,
|
|
63
|
-
verificationId: string,
|
|
64
|
-
verificationToken: string,
|
|
65
|
-
verificationType: 'email' | 'phone' = 'email'
|
|
66
|
-
): Promise<RegisterResult> {
|
|
67
|
-
// Generate the key material needed for PassIdp which will be the password used for Cognito.
|
|
68
|
-
const passKeyBundle = await this.passwordService.createPassKeyBundle(
|
|
69
|
-
password
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
const masterKey = await this.keyFactory.createKey();
|
|
73
|
-
const wrappedMasterKey = await this.encryptionService.encrypt(
|
|
74
|
-
passKeyBundle.passKey,
|
|
75
|
-
masterKey.toJSON(true)
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
const rootKey = await this.keyFactory.createKey();
|
|
79
|
-
const wrappedRootKey = await this.encryptionService.encrypt(
|
|
80
|
-
masterKey,
|
|
81
|
-
rootKey.toJSON(true)
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
// Encryption PKC key
|
|
85
|
-
const prk = await this.keyFactory.createPkcKey();
|
|
86
|
-
const wrappedPrk = await this.encryptionService.encrypt(
|
|
87
|
-
rootKey,
|
|
88
|
-
prk.toJSON(true)
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
// Signing PKC key
|
|
92
|
-
const sigPrk = await this.keyFactory.createPkcSignKey();
|
|
93
|
-
const wrappedSigPrk = await this.encryptionService.encrypt(
|
|
94
|
-
rootKey,
|
|
95
|
-
sigPrk.toJSON(true)
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
// API call to setup profile
|
|
99
|
-
const user = await this.http
|
|
100
|
-
.post<any>(`${this.config.authUrl}users/`, {
|
|
101
|
-
claims: [
|
|
102
|
-
{
|
|
103
|
-
type: verificationType,
|
|
104
|
-
token: verificationToken,
|
|
105
|
-
claim_id: verificationId,
|
|
106
|
-
},
|
|
107
|
-
],
|
|
108
|
-
pass_idp_params: passKeyBundle.passIdpParams,
|
|
109
|
-
pass_idp_verifier_pbk: passKeyBundle.passIdpVerifier.toJSON(),
|
|
110
|
-
wrapped_pass_idp_verifier_prk: passKeyBundle.wrappedPassIdpVerifierPrk,
|
|
111
|
-
pass_key_params: passKeyBundle.passKeyParams,
|
|
112
|
-
wrapped_master_key: wrappedMasterKey,
|
|
113
|
-
wrapped_root_key: wrappedRootKey,
|
|
114
|
-
pbk: prk.toJSON(), // public encryption key
|
|
115
|
-
wrapped_prk: wrappedPrk,
|
|
116
|
-
sig_pbk: sigPrk.toJSON(), // public signing key
|
|
117
|
-
wrapped_sig_prk: wrappedSigPrk,
|
|
118
|
-
})
|
|
119
|
-
.toPromise();
|
|
120
|
-
|
|
121
|
-
// API call to create user on cognito
|
|
122
|
-
const attributes = {};
|
|
123
|
-
user.claims.forEach((claim) => {
|
|
124
|
-
attributes[claim.type] = claim.value;
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
// Random suffix for uniqueness. If there's a duplicate, then used just needs to
|
|
128
|
-
// sign up again. But chances of collision is low.
|
|
129
|
-
const suffix = this.keyFactory.randomDigitsNoZeros(4);
|
|
130
|
-
|
|
131
|
-
const cognitoUser = await this.auth.signUp({
|
|
132
|
-
username: `${email.split('@')[0]}.${suffix}`,
|
|
133
|
-
password: this.passwordService.getPassIdpString(passKeyBundle.passIdp),
|
|
134
|
-
attributes,
|
|
135
|
-
// Unfortunately, validationData is not passed to the post
|
|
136
|
-
// confirmation cognito trigger. So can can't do the association there.
|
|
137
|
-
// The current workflow will create a new user on LR before signing up
|
|
138
|
-
// with Cognito. Then Cognito can use the user.id and user.pre_sign_up_token to
|
|
139
|
-
// do the validation of the attributes.
|
|
140
|
-
// validationData: [
|
|
141
|
-
// new CognitoUserAttribute({
|
|
142
|
-
// Name: "user_id",
|
|
143
|
-
// Value: String(user.id)
|
|
144
|
-
// }),
|
|
145
|
-
// new CognitoUserAttribute({
|
|
146
|
-
// Name: "user_pre_sign_up_token",
|
|
147
|
-
// Value: user.pre_sign_up_token
|
|
148
|
-
// })
|
|
149
|
-
// ]
|
|
150
|
-
clientMetadata: {
|
|
151
|
-
user_id: String(user.id),
|
|
152
|
-
user_pre_sign_up_token: String(user.pre_sign_up_token),
|
|
153
|
-
},
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
return {
|
|
157
|
-
username: cognitoUser.user.getUsername(),
|
|
158
|
-
userId: user.id,
|
|
159
|
-
preSignUpToken: user.pre_sign_up_token,
|
|
160
|
-
userSub: cognitoUser.userSub,
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
public async hibpBreachedAccounts(account: string): Promise<any> {
|
|
165
|
-
// The account is just the email
|
|
166
|
-
try {
|
|
167
|
-
const response = await this.http
|
|
168
|
-
.get(
|
|
169
|
-
`${this.config.authUrl}users/hibp/breachedaccount/${account}/?truncateResponse=false`
|
|
170
|
-
)
|
|
171
|
-
.toPromise();
|
|
172
|
-
return response;
|
|
173
|
-
} catch (error) {
|
|
174
|
-
if (error.status === 404) {
|
|
175
|
-
return null;
|
|
176
|
-
} else {
|
|
177
|
-
throw error;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { TestBed } from '@angular/core/testing';
|
|
2
|
-
|
|
3
|
-
import { TwoFactorService } from './two-factor.service';
|
|
4
|
-
import { AuthClass } from '@aws-amplify/auth/lib-esm/Auth';
|
|
5
|
-
|
|
6
|
-
const auth = jasmine.createSpyObj('AuthClass', ['']);
|
|
7
|
-
|
|
8
|
-
describe('TwoFactorService', () => {
|
|
9
|
-
let service: TwoFactorService;
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
TestBed.configureTestingModule({
|
|
13
|
-
providers: [{ provide: AuthClass, useValue: auth }],
|
|
14
|
-
});
|
|
15
|
-
service = TestBed.inject(TwoFactorService);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('should be created', () => {
|
|
19
|
-
expect(service).toBeTruthy();
|
|
20
|
-
});
|
|
21
|
-
});
|