@mindful-web/marko-web-identity-x 1.0.0

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.
Files changed (138) hide show
  1. package/.eslintignore +1 -0
  2. package/LICENSE +21 -0
  3. package/README.md +200 -0
  4. package/api/fragment-types.json +1 -0
  5. package/api/fragments/active-user.js +108 -0
  6. package/api/mutations/add-external-user-id.js +24 -0
  7. package/api/mutations/create-app-user.js +11 -0
  8. package/api/mutations/delete-app-user-for-current-application.js +7 -0
  9. package/api/mutations/impersonate-app-user.js +12 -0
  10. package/api/mutations/logout-app-user.js +11 -0
  11. package/api/mutations/send-change-email-link.js +7 -0
  12. package/api/mutations/send-login-link.js +7 -0
  13. package/api/mutations/set-custom-attributes.js +15 -0
  14. package/api/queries/check-content-access.js +19 -0
  15. package/api/queries/get-active-context.js +45 -0
  16. package/api/queries/load-user-by-external-id.js +14 -0
  17. package/api/queries/load-user-by-id.js +11 -0
  18. package/api/queries/load-user.js +11 -0
  19. package/browser/.eslintrc.js +11 -0
  20. package/browser/access.vue +377 -0
  21. package/browser/authenticate.vue +278 -0
  22. package/browser/change-email-confirm.vue +120 -0
  23. package/browser/change-email-init.vue +179 -0
  24. package/browser/comments/create.vue +107 -0
  25. package/browser/comments/post.vue +151 -0
  26. package/browser/comments/stream.vue +319 -0
  27. package/browser/custom-column.vue +314 -0
  28. package/browser/dayjs.js +6 -0
  29. package/browser/download-related.vue +120 -0
  30. package/browser/download.vue +380 -0
  31. package/browser/errors/authentication.js +7 -0
  32. package/browser/errors/feature.js +7 -0
  33. package/browser/errors/form.js +7 -0
  34. package/browser/errors/logout.js +7 -0
  35. package/browser/form/address-block.vue +131 -0
  36. package/browser/form/common/checkbox-group.vue +140 -0
  37. package/browser/form/common/form-group.vue +24 -0
  38. package/browser/form/common/form-label.vue +17 -0
  39. package/browser/form/consent.vue +121 -0
  40. package/browser/form/fields/address-extra.vue +68 -0
  41. package/browser/form/fields/city.vue +68 -0
  42. package/browser/form/fields/comment-body.vue +63 -0
  43. package/browser/form/fields/country.vue +94 -0
  44. package/browser/form/fields/custom-boolean.vue +58 -0
  45. package/browser/form/fields/custom-select-group.vue +25 -0
  46. package/browser/form/fields/custom-select-multiple.vue +97 -0
  47. package/browser/form/fields/custom-select-write-in-inline.vue +39 -0
  48. package/browser/form/fields/custom-select-write-in.vue +66 -0
  49. package/browser/form/fields/custom-select.vue +191 -0
  50. package/browser/form/fields/custom-text.vue +62 -0
  51. package/browser/form/fields/display-name.vue +64 -0
  52. package/browser/form/fields/email.vue +62 -0
  53. package/browser/form/fields/family-name.vue +68 -0
  54. package/browser/form/fields/given-name.vue +68 -0
  55. package/browser/form/fields/organization-title.vue +68 -0
  56. package/browser/form/fields/organization.vue +68 -0
  57. package/browser/form/fields/phone-number.vue +68 -0
  58. package/browser/form/fields/postal-code.vue +68 -0
  59. package/browser/form/fields/receive-email.vue +58 -0
  60. package/browser/form/fields/region.vue +106 -0
  61. package/browser/form/fields/regional-policy.vue +59 -0
  62. package/browser/form/fields/street.vue +68 -0
  63. package/browser/graphql/create-client.js +65 -0
  64. package/browser/graphql/parse.js +1 -0
  65. package/browser/graphql/queries/download-related-content.js +38 -0
  66. package/browser/index.js +110 -0
  67. package/browser/login-fields.vue +214 -0
  68. package/browser/login.vue +331 -0
  69. package/browser/logout.vue +68 -0
  70. package/browser/mixins/global-auto-signup-event-emitter.js +18 -0
  71. package/browser/mixins/global-event-emitter.js +28 -0
  72. package/browser/profile.vue +688 -0
  73. package/browser/service.js +32 -0
  74. package/browser/utils/clean-path.js +1 -0
  75. package/browser/utils/cookies-enabled.js +10 -0
  76. package/browser/utils/get-as-array.js +6 -0
  77. package/browser/utils/get-referring-page.js +7 -0
  78. package/browser/utils/get.js +8 -0
  79. package/browser/utils/post.js +10 -0
  80. package/browser/utils/redirect.js +7 -0
  81. package/browser/utils/region-country-codes.js +1 -0
  82. package/components/access.marko +24 -0
  83. package/components/access.marko.js +61 -0
  84. package/components/comment-stream.marko +31 -0
  85. package/components/comment-stream.marko.js +71 -0
  86. package/components/context.marko +15 -0
  87. package/components/context.marko.js +52 -0
  88. package/components/form-access.marko +60 -0
  89. package/components/form-access.marko.js +111 -0
  90. package/components/form-authenticate.marko +32 -0
  91. package/components/form-authenticate.marko.js +73 -0
  92. package/components/form-change-email.marko +27 -0
  93. package/components/form-change-email.marko.js +68 -0
  94. package/components/form-login.marko +32 -0
  95. package/components/form-login.marko.js +72 -0
  96. package/components/form-logout.marko +7 -0
  97. package/components/form-logout.marko.js +36 -0
  98. package/components/form-profile.marko +38 -0
  99. package/components/form-profile.marko.js +78 -0
  100. package/components/form-register.marko +2 -0
  101. package/components/form-register.marko.js +32 -0
  102. package/components/identify.marko +17 -0
  103. package/components/identify.marko.js +59 -0
  104. package/components/marko.json +90 -0
  105. package/components/non-auth-identify.marko +15 -0
  106. package/components/non-auth-identify.marko.js +53 -0
  107. package/config.js +161 -0
  108. package/hooks.js +20 -0
  109. package/index.js +30 -0
  110. package/marko.json +6 -0
  111. package/middleware/content-access-state.js +31 -0
  112. package/middleware/content-download-state.js +27 -0
  113. package/middleware.js +32 -0
  114. package/package.json +40 -0
  115. package/routes/access.js +29 -0
  116. package/routes/authenticate.js +58 -0
  117. package/routes/change-email-confirm.js +60 -0
  118. package/routes/change-email-init.js +16 -0
  119. package/routes/comment-count.js +19 -0
  120. package/routes/comments.js +43 -0
  121. package/routes/countries.js +19 -0
  122. package/routes/create-comment.js +25 -0
  123. package/routes/download.js +29 -0
  124. package/routes/flag-comment.js +21 -0
  125. package/routes/index.js +40 -0
  126. package/routes/login-fields.js +35 -0
  127. package/routes/login.js +95 -0
  128. package/routes/logout.js +19 -0
  129. package/routes/profile.js +183 -0
  130. package/routes/regions.js +22 -0
  131. package/service.js +483 -0
  132. package/utils/call-hooks-for.js +28 -0
  133. package/utils/context-cookie.js +30 -0
  134. package/utils/create-client.js +48 -0
  135. package/utils/create-identity-builder.js +33 -0
  136. package/utils/get-as-array.js +6 -0
  137. package/utils/json-error-handler.js +41 -0
  138. package/utils/token-cookie.js +30 -0
@@ -0,0 +1,110 @@
1
+ import IdentityX from './service';
2
+ import createGraphqlClient from './graphql/create-client';
3
+
4
+ const Access = () => import(/* webpackChunkName: "identity-x-form-access" */ './access.vue');
5
+ const Authenticate = () => import(/* webpackChunkName: "identity-x-authenticate" */ './authenticate.vue');
6
+ const ChangeEmailConfirm = () => import(/* webpackChunkName: "identity-x-change-email-confirm" */ './change-email-confirm.vue');
7
+ const ChangeEmailInit = () => import(/* webpackChunkName: "identity-x-change-email-init" */ './change-email-init.vue');
8
+ const Download = () => import(/* webpackChunkName: "identity-x-download" */ './download.vue');
9
+ const Logout = () => import(/* webpackChunkName: "identity-x-logout" */ './logout.vue');
10
+ const Login = () => import(/* webpackChunkName: "identity-x-login" */ './login.vue');
11
+ const Profile = () => import(/* webpackChunkName: "identity-x-profile" */ './profile.vue');
12
+ const CommentStream = () => import(/* webpackChunkName: "identity-x-comment-stream" */ './comments/stream.vue');
13
+
14
+ const $graphql = createGraphqlClient({ uri: '/__graphql' });
15
+
16
+ const { log } = console;
17
+
18
+ export default (Browser, {
19
+ CustomAccessComponent,
20
+ CustomAuthenticateComponent,
21
+ CustomChangeEmailConfirmComponent,
22
+ CustomChangeEmailInitComponent,
23
+ CustomCommentStreamComponent,
24
+ CustomDownloadComponent,
25
+ CustomLoginComponent,
26
+ CustomLogoutComponent,
27
+ CustomProfileComponent,
28
+ } = {}) => {
29
+ const AccessComponent = CustomAccessComponent || Access;
30
+ const AuthenticateComponent = CustomAuthenticateComponent || Authenticate;
31
+ const ChangeEmailConfirmComponent = CustomChangeEmailConfirmComponent || ChangeEmailConfirm;
32
+ const ChangeEmailInitComponent = CustomChangeEmailInitComponent || ChangeEmailInit;
33
+ const CommentStreamComponent = CustomCommentStreamComponent || CommentStream;
34
+ const DownloadComponent = CustomDownloadComponent || Download;
35
+ const LoginComponent = CustomLoginComponent || Login;
36
+ const LogoutComponent = CustomLogoutComponent || Logout;
37
+ const ProfileComponent = CustomProfileComponent || Profile;
38
+
39
+ window.IdentityX = new IdentityX();
40
+
41
+ const { EventBus } = Browser;
42
+ Browser.register('IdentityXAccess', AccessComponent, { provide: { EventBus, $graphql } });
43
+ Browser.register('IdentityXAuthenticate', AuthenticateComponent, { provide: { EventBus } });
44
+ Browser.register('IdentityXChangeEmailConfirm', ChangeEmailConfirmComponent, { provide: { EventBus } });
45
+ Browser.register('IdentityXChangeEmailInit', ChangeEmailInitComponent, { provide: { EventBus } });
46
+ Browser.register('IdentityXCommentStream', CommentStreamComponent, { provide: { EventBus } });
47
+ Browser.register('IdentityXDownload', DownloadComponent, { provide: { EventBus, $graphql } });
48
+ Browser.register('IdentityXLogin', LoginComponent, { provide: { EventBus } });
49
+ Browser.register('IdentityXLogout', LogoutComponent, { provide: { EventBus } });
50
+ Browser.register('IdentityXProfile', ProfileComponent, { provide: { EventBus } });
51
+
52
+ // Ensure the client-side IdX context is refreshed when the authentication event occurs
53
+ EventBus.$on('identity-x-authenticated', () => window.IdentityX.refreshContext());
54
+
55
+ // Send emitted IdentityX events to the datalayer
56
+ window.dataLayer = window.dataLayer || [];
57
+ [
58
+ // Views
59
+ 'identity-x-access-mounted',
60
+ 'identity-x-authenticate-mounted',
61
+ 'identity-x-change-email-mounted',
62
+ 'identity-x-comment-create-mounted',
63
+ 'identity-x-comment-post-mounted',
64
+ 'identity-x-comment-stream-mounted',
65
+ 'identity-x-download-mounted',
66
+ 'identity-x-login-mounted',
67
+ 'identity-x-logout-mounted',
68
+ 'identity-x-profile-mounted',
69
+ // Actions/submissions
70
+ 'identity-x-access-submitted',
71
+ 'identity-x-authenticated',
72
+ 'identity-x-auto-signup',
73
+ 'identity-x-change-email',
74
+ 'identity-x-comment-post-submitted',
75
+ 'identity-x-comment-report-submitted',
76
+ 'identity-x-comment-stream-loaded',
77
+ 'identity-x-comment-stream-loaded-more',
78
+ 'identity-x-download-submitted',
79
+ 'identity-x-login-link-sent',
80
+ 'identity-x-logout',
81
+ 'identity-x-profile-updated',
82
+ // Errors
83
+ 'identity-x-access-errored',
84
+ 'identity-x-authenticate-errored',
85
+ 'identity-x-change-email-errored',
86
+ 'identity-x-comment-post-errored',
87
+ 'identity-x-comment-report-errored',
88
+ 'identity-x-comment-stream-errored',
89
+ 'identity-x-download-errored',
90
+ 'identity-x-login-errored',
91
+ 'identity-x-logout-errored',
92
+ 'identity-x-profile-errored',
93
+ ].forEach((event) => {
94
+ EventBus.$on(event, (args) => {
95
+ if (!window.IdentityX) return;
96
+ const payload = {
97
+ event,
98
+ 'identity-x': {
99
+ ...args,
100
+ event,
101
+ },
102
+ };
103
+ const { searchParams } = new URL(window.location.href);
104
+ if (searchParams.has('idxDebugger')) {
105
+ log(`identity-x event: ${event} `, payload);
106
+ }
107
+ window.dataLayer.push(payload);
108
+ });
109
+ });
110
+ };
@@ -0,0 +1,214 @@
1
+ <template>
2
+ <form @submit.prevent="$emit('submit', values)">
3
+ <p>{{ callToAction }}</p>
4
+ <fieldset :disabled="disabled">
5
+ <div class="row">
6
+ <!-- common, loopable fields -->
7
+ <div
8
+ v-for="fieldKey in componentFields"
9
+ :key="fieldKey"
10
+ class="col-md-6"
11
+ >
12
+ <component
13
+ :is="components[fieldKey]"
14
+ v-model="values[fieldKey]"
15
+ required
16
+ />
17
+ </div>
18
+
19
+ <!-- locale dependent fields -->
20
+ <div v-if="displayCountryField" class="col-md-6">
21
+ <country-code v-model="values.countryCode" required />
22
+ </div>
23
+ <div v-if="displayRegionField" class="col-md-6">
24
+ <region-code v-model="values.regionCode" :country-code="values.countryCode" required />
25
+ </div>
26
+ <div v-if="displayPostalCodeField" class="col-md-6">
27
+ <postal-code v-model="values.postalCode" required />
28
+ </div>
29
+ </div>
30
+
31
+ <div v-if="regionalPolicyFields.length" class="row mt-3">
32
+ <div class="col-12">
33
+ <regional-policy
34
+ v-for="policy in regionalPolicyFields"
35
+ :id="policy.id"
36
+ :key="policy.id"
37
+ :message="policy.message"
38
+ :required="policy.required"
39
+ :value="getRegionalPolicyAnswerValue(policy.id)"
40
+ @input="setPolicyAnswer(policy.id, $event)"
41
+ />
42
+ </div>
43
+ </div>
44
+
45
+ <small
46
+ v-if="consentPolicy"
47
+ class="text-muted mb-3"
48
+ v-html="consentPolicy"
49
+ />
50
+
51
+ <button
52
+ type="submit"
53
+ class="btn btn-primary"
54
+ >
55
+ {{ buttonLabel }}
56
+ </button>
57
+ </fieldset>
58
+ </form>
59
+ </template>
60
+
61
+ <script>
62
+ import GivenName from './form/fields/given-name.vue';
63
+ import FamilyName from './form/fields/family-name.vue';
64
+ import Organization from './form/fields/organization.vue';
65
+ import OrganizationTitle from './form/fields/organization-title.vue';
66
+ import CountryCode from './form/fields/country.vue';
67
+ import RegionCode from './form/fields/region.vue';
68
+ import PostalCode from './form/fields/postal-code.vue';
69
+
70
+ import RegionalPolicy from './form/fields/regional-policy.vue';
71
+
72
+ import regionCountryCodes from './utils/region-country-codes';
73
+
74
+ export default {
75
+ components: {
76
+ CountryCode,
77
+ RegionCode,
78
+ PostalCode,
79
+ RegionalPolicy,
80
+ },
81
+
82
+ props: {
83
+ /**
84
+ * The field keys to display on the pre-login form.
85
+ * All will be set as required.
86
+ *
87
+ * Example:
88
+ * [
89
+ * 'countryCode',
90
+ * 'regionCode',
91
+ * ]
92
+ */
93
+ fields: {
94
+ type: Array,
95
+ required: true,
96
+ },
97
+
98
+ /**
99
+ * The form button label
100
+ */
101
+ buttonLabel: {
102
+ type: String,
103
+ default: 'Submit',
104
+ },
105
+
106
+ /**
107
+ * The form call-to-action
108
+ */
109
+ callToAction: {
110
+ type: String,
111
+ default: 'To complete your login/registration, please fill out the fields below.',
112
+ },
113
+
114
+ /**
115
+ * The form submit consent policy, if present.
116
+ */
117
+ consentPolicy: {
118
+ type: String,
119
+ default: null,
120
+ },
121
+
122
+ /**
123
+ * Whether the form's fieldset is disabled
124
+ */
125
+ disabled: {
126
+ type: Boolean,
127
+ default: false,
128
+ },
129
+
130
+ /**
131
+ * Regional consent policies to display, if any.
132
+ */
133
+ regionalConsentPolicies: {
134
+ type: Array,
135
+ default: () => [],
136
+ },
137
+ },
138
+
139
+ data: () => ({
140
+ components: {
141
+ givenName: GivenName,
142
+ familyName: FamilyName,
143
+ organization: Organization,
144
+ organizationTitle: OrganizationTitle,
145
+ },
146
+ values: { regionalConsentAnswers: [] },
147
+ }),
148
+
149
+ computed: {
150
+ /**
151
+ * Returns fields that have a matching, loopable component.
152
+ */
153
+ componentFields() {
154
+ return this.fields.filter((field) => this.components[field]);
155
+ },
156
+
157
+ /**
158
+ *
159
+ */
160
+ displayCountryField() {
161
+ return this.fields.includes('countryCode');
162
+ },
163
+
164
+ /**
165
+ *
166
+ */
167
+ displayRegionField() {
168
+ const { countryCode } = this.values;
169
+ return this.fields.includes('regionCode') && regionCountryCodes.includes(countryCode);
170
+ },
171
+
172
+ /**
173
+ *
174
+ */
175
+ displayPostalCodeField() {
176
+ return this.fields.includes('postalCode') && this.displayRegionField;
177
+ },
178
+
179
+ /**
180
+ *
181
+ */
182
+ regionalPolicyFields() {
183
+ const { regionalConsentPolicies } = this;
184
+ const { countryCode } = this.values;
185
+ if (!regionalConsentPolicies.length || !countryCode) return [];
186
+ return regionalConsentPolicies.filter((policy) => {
187
+ const countryCodes = policy.countries.map((country) => country.id);
188
+ return countryCodes.includes(countryCode);
189
+ });
190
+ },
191
+ },
192
+
193
+ methods: {
194
+ getRegionalPolicyAnswer(policyId) {
195
+ return this.values.regionalConsentAnswers.find((a) => a.id === policyId);
196
+ },
197
+
198
+ getRegionalPolicyAnswerValue(policyId) {
199
+ const answer = this.getRegionalPolicyAnswer(policyId);
200
+ if (answer) return answer.given;
201
+ return false;
202
+ },
203
+
204
+ setPolicyAnswer(policyId, given) {
205
+ const answer = this.getRegionalPolicyAnswer(policyId);
206
+ if (answer) {
207
+ answer.given = given;
208
+ } else {
209
+ this.values.regionalConsentAnswers.push({ id: policyId, given });
210
+ }
211
+ },
212
+ },
213
+ };
214
+ </script>
@@ -0,0 +1,331 @@
1
+ <template>
2
+ <div v-if="hasActiveUser">
3
+ <p>You are currently logged in as {{ activeUser.email }}.</p>
4
+ <a
5
+ :href="endpoints.profile"
6
+ class="btn btn-secondary mb-2 mr-2"
7
+ role="button"
8
+ >
9
+ {{ buttonLabels.profile || "Modify Profile" }}
10
+ </a>
11
+ <a
12
+ :href="endpoints.logout"
13
+ class="btn btn-primary mb-2 mr-2"
14
+ role="button"
15
+ >
16
+ {{ buttonLabels.logout || "Log out" }}
17
+ </a>
18
+ </div>
19
+ <div v-else-if="complete" v-html="almostDoneVerbiage" />
20
+ <div v-else>
21
+ <form @submit.prevent="handleSubmit">
22
+ <email
23
+ :id="loginEmailId"
24
+ v-model="email"
25
+ :placeholder="loginEmailPlaceholder"
26
+ :disabled="loading"
27
+ :label="loginEmailLabel"
28
+ @focus="$emit('focus')"
29
+ />
30
+
31
+ <p v-if="requiresUserInput">
32
+ Thanks! Additional information is required to continue:
33
+ </p>
34
+ <div v-if="requiresUserInput" class="row form-group">
35
+ <div v-if="requiredCreateFields.includes('givenName')" class="col">
36
+ <given-name
37
+ v-model="givenName"
38
+ :required="true"
39
+ :disabled="loading"
40
+ :label="defaultFieldLabels.givenName || 'First Name'"
41
+ />
42
+ </div>
43
+ <div v-if="requiredCreateFields.includes('familyName')" class="col">
44
+ <family-name
45
+ v-model="familyName"
46
+ :required="true"
47
+ :disabled="loading"
48
+ :label="defaultFieldLabels.familyName || 'Last Name'"
49
+ />
50
+ </div>
51
+ </div>
52
+
53
+ <small
54
+ v-if="emailConsentRequestEnabled && emailConsentRequest"
55
+ class="text-muted mb-1 d-block"
56
+ v-html="emailConsentRequest"
57
+ />
58
+
59
+ <small
60
+ v-if="consentPolicyEnabled && consentPolicy"
61
+ class="text-muted mb-1 d-block"
62
+ v-html="consentPolicy"
63
+ />
64
+ <button
65
+ type="submit"
66
+ class="btn btn-primary"
67
+ :disabled="loading"
68
+ >
69
+ {{ buttonLabels.continue || "Continue" }}
70
+ </button>
71
+ <p v-if="error" class="mt-3 text-danger">
72
+ An error occurred: {{ error.message }}
73
+ </p>
74
+ </form>
75
+ </div>
76
+ </template>
77
+
78
+ <script>
79
+ import Email from './form/fields/email.vue';
80
+ import GivenName from './form/fields/given-name.vue';
81
+ import FamilyName from './form/fields/family-name.vue';
82
+
83
+ import cleanPath from './utils/clean-path';
84
+ import post from './utils/post';
85
+ import cookiesEnabled from './utils/cookies-enabled';
86
+ import FormError from './errors/form';
87
+ import FeatureError from './errors/feature';
88
+ import AutoSignupEventEmitter from './mixins/global-auto-signup-event-emitter';
89
+ import EventEmitter from './mixins/global-event-emitter';
90
+
91
+ export default {
92
+ /**
93
+ *
94
+ */
95
+ components: {
96
+ Email,
97
+ GivenName,
98
+ FamilyName,
99
+ },
100
+
101
+ /**
102
+ *
103
+ */
104
+ mixins: [EventEmitter, AutoSignupEventEmitter],
105
+
106
+ /**
107
+ *
108
+ */
109
+ props: {
110
+ source: {
111
+ type: String,
112
+ default: 'default',
113
+ },
114
+ activeUser: {
115
+ type: Object,
116
+ default: () => {},
117
+ },
118
+ endpoints: {
119
+ type: Object,
120
+ required: true,
121
+ },
122
+ buttonLabels: {
123
+ type: Object,
124
+ default: () => ({
125
+ continue: 'Continue',
126
+ profile: 'Modify Profile',
127
+ logout: 'Logout',
128
+ }),
129
+ },
130
+ defaultFieldLabels: {
131
+ type: Object,
132
+ default: () => {},
133
+ },
134
+ consentPolicy: {
135
+ type: String,
136
+ default: null,
137
+ },
138
+ consentPolicyEnabled: {
139
+ type: Boolean,
140
+ default: false,
141
+ },
142
+ emailConsentRequest: {
143
+ type: String,
144
+ default: null,
145
+ },
146
+ emailConsentRequestEnabled: {
147
+ type: Boolean,
148
+ default: false,
149
+ },
150
+ redirect: {
151
+ type: String,
152
+ default: null,
153
+ },
154
+ appContextId: {
155
+ type: String,
156
+ default: null,
157
+ },
158
+ loginEmailPlaceholder: {
159
+ type: String,
160
+ default: null,
161
+ },
162
+ senderEmailAddress: {
163
+ type: String,
164
+ default: 'noreply@identity-x.parameter1.com',
165
+ },
166
+ actionText: {
167
+ type: String,
168
+ default: 'logging in',
169
+ },
170
+ loginEmailId: {
171
+ type: String,
172
+ default: 'sign-on-email',
173
+ },
174
+ loginEmailLabel: {
175
+ type: String,
176
+ default: 'Email Address',
177
+ },
178
+
179
+ /**
180
+ * Regional consent polices to display (if/when a user selects a country on login)
181
+ * if enabled.
182
+ */
183
+ regionalConsentPolicies: {
184
+ type: Array,
185
+ default: () => [],
186
+ },
187
+
188
+ requiredCreateFields: {
189
+ type: Array,
190
+ default: () => [],
191
+ },
192
+
193
+ lang: {
194
+ type: String,
195
+ default: 'en',
196
+ },
197
+ },
198
+
199
+ /**
200
+ *
201
+ */
202
+ data: () => ({
203
+ email: null,
204
+ givenName: null,
205
+ familyName: null,
206
+ complete: false,
207
+ error: null,
208
+ loading: false,
209
+ requiresUserInput: false,
210
+ }),
211
+
212
+ /**
213
+ *
214
+ */
215
+ computed: {
216
+ /**
217
+ *
218
+ */
219
+ authUrl() {
220
+ return `${window.location.origin}/${cleanPath(this.endpoints.authenticate)}`;
221
+ },
222
+
223
+ /**
224
+ *
225
+ */
226
+ hasActiveUser() {
227
+ return this.activeUser && this.activeUser.email;
228
+ },
229
+
230
+ almostDoneVerbiage() {
231
+ if (this.lang === 'es') {
232
+ return `<h4>Falta muy poco!</h4>
233
+ <p>
234
+ Enviamos un correo a <em>${this.email}</em> con su enlace de inicio de sesión único (caduca en una hora).
235
+ Para terminar de ${this.actionText || 'logging in'}, abra el mensaje de correo electrónico y haga clic en el enlace que contiene.
236
+ </p>
237
+ <p>
238
+ Nota: por favor revise sus carpetas de spam/basura.
239
+ Si no recibe este correo electrónico, es probable que su firewall o ISP lo haya bloqueado.
240
+ Agregue ${this.senderEmailAddress} a su lista blanca e intente registrarse nuevamente.
241
+ </p>`;
242
+ }
243
+ return `<h4>Almost Done!</h4>
244
+ <p>
245
+ We just sent an email to <em>${this.email}</em> with your one-time login link (expires in one hour).
246
+ To finish ${this.actionText || 'logging in'}, open the email message and click the link within.
247
+ </p>
248
+ <p>
249
+ Note: please check your spam/junk folders.
250
+ If you do not receive this email, your firewall or ISP has likely blocked it.
251
+ Please add ${this.senderEmailAddress} to your whitelist and try registering again.
252
+ </p>`;
253
+ },
254
+
255
+ /**
256
+ *
257
+ */
258
+ redirectTo() {
259
+ const { redirect } = this;
260
+ if (redirect) return redirect;
261
+ const { pathname, search, hash } = window.location;
262
+ return `${pathname}${search}${hash}`;
263
+ },
264
+ },
265
+
266
+ /**
267
+ *
268
+ */
269
+ mounted() {
270
+ if (cookiesEnabled()) {
271
+ this.emit('login-mounted', { actionSource: this.source });
272
+ } else {
273
+ this.error = new FeatureError('Your browser does not support cookies. Please enable cookies to use this feature.');
274
+ this.emit('login-errored', { message: this.error.message });
275
+ }
276
+ },
277
+
278
+ /**
279
+ *
280
+ */
281
+ methods: {
282
+ /**
283
+ *
284
+ */
285
+ async handleSubmit() {
286
+ try {
287
+ this.error = null;
288
+ this.loading = true;
289
+ const res = await post('/login', {
290
+ email: this.email,
291
+ // Append any additional required fields
292
+ ...(this.requiredCreateFields.reduce((obj, key) => ({ ...obj, [key]: this[key] }), {})),
293
+ source: this.source,
294
+ redirectTo: this.redirectTo,
295
+ authUrl: this.authUrl,
296
+ appContextId: this.appContextId,
297
+ additionalEventData: {
298
+ ...this.additionalEventData,
299
+ actionSource: this.source,
300
+ },
301
+ });
302
+ const data = await res.json();
303
+ const { entity } = data;
304
+ if (!res.ok) {
305
+ if (data.requiresUserInput) {
306
+ this.requiresUserInput = true;
307
+ return;
308
+ }
309
+ throw new FormError(data.message, res.status);
310
+ }
311
+ this.complete = true;
312
+ this.emitAutoSignup(data);
313
+ this.emit('login-link-sent', {
314
+ data,
315
+ email: this.email,
316
+ source: this.source,
317
+ additionalEventData: {
318
+ ...(this.additionalEventData || {}),
319
+ ...(data.additionalEventData || {}),
320
+ },
321
+ }, entity);
322
+ } catch (e) {
323
+ this.error = e;
324
+ this.emit('login-errored', { message: e.message });
325
+ } finally {
326
+ this.loading = false;
327
+ }
328
+ },
329
+ },
330
+ };
331
+ </script>