From 285a99e0c133c8b8f150a3c8a453be629175c568 Mon Sep 17 00:00:00 2001
From: Roger Gutierrez
Date: Wed, 19 Feb 2025 13:46:13 -0600
Subject: [PATCH 1/3] feat: guest username passed to auth flow
---
server/auth-router.js | 5 +++++
.../Checkout/CheckoutDropInPaymentWrapper.vue | 2 +-
src/components/Forms/GuestAccountCreation.vue | 12 +++++++++--
src/components/Thanks/CommentAsk.vue | 8 +++++++-
src/components/Thanks/MyKiva/ThanksBadges.vue | 5 +++++
.../SingleVersion/AccountReceiptShare.vue | 5 +++++
.../Thanks/ThanksPageCommentAndShare.vue | 5 +++++
.../Thanks/ThanksPageSingleVersion.vue | 8 +++++++-
src/components/Thanks/WhatIsNextTemplate.vue | 6 ++++++
src/pages/Checkout/CheckoutPage.vue | 6 +++++-
src/pages/Checkout/PostPurchase.vue | 5 +++++
.../LoginAndRegister/GuestAccountRedirect.vue | 20 +++++++++++++------
src/pages/Thanks/ThanksPage.vue | 6 ++++++
13 files changed, 81 insertions(+), 12 deletions(-)
diff --git a/server/auth-router.js b/server/auth-router.js
index 9b871bf7c9..00d5a018fb 100644
--- a/server/auth-router.js
+++ b/server/auth-router.js
@@ -135,6 +135,11 @@ export default function authRouter(config = {}) {
options.login_hint = 'signUp';
}
+ // Guest Username
+ if (req.query.username) {
+ options.username = req.query.username;
+ }
+
info(`LoginUI: attempt login, session id:${req.sessionID}, cookie:${getSyncCookie(req)}, done url:${req.query.doneUrl}`); // eslint-disable-line max-len
passport.authenticate('auth0', options)(req, res, next);
});
diff --git a/src/components/Checkout/CheckoutDropInPaymentWrapper.vue b/src/components/Checkout/CheckoutDropInPaymentWrapper.vue
index 4b9b07263f..025efdb4b8 100644
--- a/src/components/Checkout/CheckoutDropInPaymentWrapper.vue
+++ b/src/components/Checkout/CheckoutDropInPaymentWrapper.vue
@@ -455,7 +455,7 @@ export default {
transactionId
);
// Complete transaction handles additional analytics + redirect
- this.$emit('complete-transaction', transactionId);
+ this.$emit('complete-transaction', { transactionId, username: this.email });
}
},
handleFailedCheckout(kivaBraintreeResponse) {
diff --git a/src/components/Forms/GuestAccountCreation.vue b/src/components/Forms/GuestAccountCreation.vue
index f01ef72f7a..2bfc3386d0 100644
--- a/src/components/Forms/GuestAccountCreation.vue
+++ b/src/components/Forms/GuestAccountCreation.vue
@@ -86,7 +86,11 @@ export default {
eventValue: {
type: Number,
default: 0
- }
+ },
+ guestUsername: {
+ type: String,
+ default: ''
+ },
},
data() {
return {
@@ -129,10 +133,14 @@ export default {
if (result?.errors?.length > 0) {
throw result.errors;
}
- const resetUrl = result?.data?.general?.startGuestAccountClaim;
+ let resetUrl = result?.data?.general?.startGuestAccountClaim;
if (!resetUrl) {
throw new Error('Missing reset url');
}
+ if (this.guestUsername) {
+ resetUrl += `?username=${this.guestUsername}`;
+ }
+
window.location = resetUrl;
}).catch(err => {
this.serverError = true;
diff --git a/src/components/Thanks/CommentAsk.vue b/src/components/Thanks/CommentAsk.vue
index 06b4645aff..e73605e239 100644
--- a/src/components/Thanks/CommentAsk.vue
+++ b/src/components/Thanks/CommentAsk.vue
@@ -112,7 +112,9 @@
-
+
@@ -155,6 +157,10 @@ export default {
type: Boolean,
default: false
},
+ guestUsername: {
+ type: String,
+ default: '',
+ },
},
data() {
return {
diff --git a/src/components/Thanks/MyKiva/ThanksBadges.vue b/src/components/Thanks/MyKiva/ThanksBadges.vue
index 46581b4207..f7cac99424 100644
--- a/src/components/Thanks/MyKiva/ThanksBadges.vue
+++ b/src/components/Thanks/MyKiva/ThanksBadges.vue
@@ -163,6 +163,7 @@
event-label="create-new-account"
event-property="guest"
:event-value="numberOfBadges"
+ :guest-username="guestUsername"
/>
@@ -226,6 +227,10 @@ const props = defineProps({
type: Object,
default: () => ({}),
},
+ guestUsername: {
+ type: String,
+ default: '',
+ },
});
const {
diff --git a/src/components/Thanks/SingleVersion/AccountReceiptShare.vue b/src/components/Thanks/SingleVersion/AccountReceiptShare.vue
index 134dfdac06..17c60e9f09 100644
--- a/src/components/Thanks/SingleVersion/AccountReceiptShare.vue
+++ b/src/components/Thanks/SingleVersion/AccountReceiptShare.vue
@@ -30,6 +30,7 @@
event-label="create-new-account-from-drawer"
:event-property="userType"
:event-value="numberOfBadges"
+ :guest-username="guestUsername"
/>
@@ -131,6 +132,10 @@ const props = defineProps({
type: Boolean,
default: false,
},
+ guestUsername: {
+ type: String,
+ default: ''
+ },
});
const POST_CHECKOUT_EVENT_CATEGORY = 'post-checkout';
diff --git a/src/components/Thanks/ThanksPageCommentAndShare.vue b/src/components/Thanks/ThanksPageCommentAndShare.vue
index 5af69d9800..95607ae411 100644
--- a/src/components/Thanks/ThanksPageCommentAndShare.vue
+++ b/src/components/Thanks/ThanksPageCommentAndShare.vue
@@ -114,6 +114,7 @@
:loan-name="loan.name"
:loan-id="loan.id"
:is-guest="isGuest"
+ :guest-username="guestUsername"
/>
@@ -273,6 +274,10 @@ export default {
type: Boolean,
default: false,
},
+ guestUsername: {
+ type: String,
+ default: '',
+ },
},
mixins: [socialSharingMixin],
head() {
diff --git a/src/components/Thanks/ThanksPageSingleVersion.vue b/src/components/Thanks/ThanksPageSingleVersion.vue
index 82ef69f614..d8471a1cdd 100644
--- a/src/components/Thanks/ThanksPageSingleVersion.vue
+++ b/src/components/Thanks/ThanksPageSingleVersion.vue
@@ -58,6 +58,7 @@
:loans="loans"
:show-receipt="showReceipt"
:only-donations="onlyDonations"
+ :guest-username="guestUsername"
/>
@@ -131,7 +133,11 @@ const props = defineProps({
myKivaEnabled: {
type: Boolean,
default: false,
- }
+ },
+ guestUsername: {
+ type: String,
+ default: '',
+ },
});
const receiptSection = ref(null);
diff --git a/src/components/Thanks/WhatIsNextTemplate.vue b/src/components/Thanks/WhatIsNextTemplate.vue
index f9cce382b4..29caab109b 100644
--- a/src/components/Thanks/WhatIsNextTemplate.vue
+++ b/src/components/Thanks/WhatIsNextTemplate.vue
@@ -85,6 +85,7 @@
class="tw-pt-3 account-creation"
event-category="thanks"
event-label="open-account-creation-drawer"
+ :guest-username="guestUsername"
/>
@@ -175,6 +176,7 @@
class="tw-pt-3 account-creation"
event-category="thanks"
event-label="open-account-creation-drawer"
+ :guest-username="guestUsername"
/>
@@ -309,6 +311,10 @@ export default {
type: Boolean,
default: false
},
+ guestUsername: {
+ type: String,
+ default: '',
+ },
},
data() {
return {
diff --git a/src/pages/Checkout/CheckoutPage.vue b/src/pages/Checkout/CheckoutPage.vue
index 53619ef6b5..7ac0327293 100644
--- a/src/pages/Checkout/CheckoutPage.vue
+++ b/src/pages/Checkout/CheckoutPage.vue
@@ -850,7 +850,8 @@ export default {
this.setUpdatingTotals(false);
});
},
- completeTransaction(transactionId) {
+ completeTransaction(payload) {
+ const transactionId = typeof payload === 'object' ? payload.transactionId : payload;
// compile transaction data
const transactionData = formatTransactionData(
numeral(transactionId).value(),
@@ -875,6 +876,9 @@ export default {
if (this.checkingOutAsGuest) {
checkoutAdditionalQueryParams += `&optedIn=${this.userOptedIn}`;
}
+ if (payload.username) {
+ checkoutAdditionalQueryParams += `&username=${payload.username}`;
+ }
// redirect to thanks
window.setTimeout(
diff --git a/src/pages/Checkout/PostPurchase.vue b/src/pages/Checkout/PostPurchase.vue
index 8a66ef1284..63f56f54c4 100644
--- a/src/pages/Checkout/PostPurchase.vue
+++ b/src/pages/Checkout/PostPurchase.vue
@@ -21,6 +21,7 @@ export default {
const transactionId = numeral(currentRoute.query?.kiva_transaction_id).value();
const valetInviter = currentRoute.query?.valet_inviter ?? '';
const optedIn = currentRoute.query?.optedIn ?? '';
+ const username = currentRoute.query?.username ?? '';
if (!transactionId) {
// redirect to thanks page if no transaction id was provided
// currently resolves to portfolio via ThanksView getCheckoutId method
@@ -54,6 +55,10 @@ export default {
successRoute.query.optedIn = optedIn;
}
+ if (username) {
+ successRoute.query.username = username;
+ }
+
// track the transaction event
client.mutate({
mutation: trackTransactionMutation,
diff --git a/src/pages/LoginAndRegister/GuestAccountRedirect.vue b/src/pages/LoginAndRegister/GuestAccountRedirect.vue
index 3065a4a791..149deaa7c9 100644
--- a/src/pages/LoginAndRegister/GuestAccountRedirect.vue
+++ b/src/pages/LoginAndRegister/GuestAccountRedirect.vue
@@ -9,9 +9,10 @@ import { GUEST_COMMENT_COMMENT, GUEST_COMMENT_LOANID } from '#src/plugins/guest-
export default {
name: 'GuestAccountRedirect',
apollo: {
- preFetch(config, client, { cookieStore }) {
- return client.query({
- query: gql`query guestRedirect($basketId: String) {
+ preFetch(config, client, { cookieStore, route }) {
+ return Promise.all([
+ client.query({
+ query: gql`query guestRedirect($basketId: String) {
shop (basketId: $basketId) {
id
nonTrivialItemCount
@@ -23,7 +24,10 @@ export default {
}
}
}`,
- }).then(({ data }) => {
+ }),
+ route,
+ ]).then(data => {
+ const dataQuery = data[0].data;
// Add claimed=1 to the url to show a confirmation tip message on the page
const query = { claimed: 1 };
@@ -31,7 +35,7 @@ export default {
// Redirect to loan page if there is a pending guest comment
// Otherwise /portfolio
let path = '';
- if (data?.shop?.nonTrivialItemCount > 0) {
+ if (dataQuery?.shop?.nonTrivialItemCount > 0) {
path = '/checkout';
} else if (cookieStore.get(GUEST_COMMENT_COMMENT) && cookieStore.get(GUEST_COMMENT_LOANID)) {
path = `/lend/${cookieStore.get(GUEST_COMMENT_LOANID)}`;
@@ -44,7 +48,10 @@ export default {
.join('&');
// Check to see if user is authenticated
- if (!data?.my?.userAccount?.id) {
+ if (!dataQuery?.my?.userAccount?.id) {
+ const currentRoute = data[1].value ?? data[1] ?? {};
+ const username = currentRoute.query?.username ?? '';
+
return Promise.reject({
path: '/ui-login',
query: {
@@ -52,6 +59,7 @@ export default {
guest: true,
})}`,
doneUrl: `${path}?${queryString}`,
+ username,
},
});
}
diff --git a/src/pages/Thanks/ThanksPage.vue b/src/pages/Thanks/ThanksPage.vue
index 934dc19d52..0410431c0f 100644
--- a/src/pages/Thanks/ThanksPage.vue
+++ b/src/pages/Thanks/ThanksPage.vue
@@ -13,6 +13,7 @@
:monthly-donation-amount="monthlyDonationAmount"
:badges-achieved="badgesAchieved"
:my-kiva-enabled="myKivaExperimentEnabled"
+ :guest-username="guestUsername"
/>
@@ -30,6 +31,7 @@
:receipt="receipt"
:badges-achieved="badgesAchieved"
:router="$router"
+ :guest-username="guestUsername"
/>
@@ -40,6 +42,7 @@
:lender="lender"
:is-guest="isGuest"
:opted-in="optedIn"
+ :guest-username="guestUsername"
/>
@@ -164,6 +167,7 @@
:ftd-credit-amount="ftdCreditAmount"
@guest-create-account="createGuestAccount"
:ask-for-comments="askForComments"
+ :guest-username="guestUsername"
/>
@@ -291,6 +295,7 @@ export default {
badgesAchieved: [],
thanksSingleVersionEnabled: false,
SINGLE_VERSION_VIEW,
+ guestUsername: '',
};
},
apollo: {
@@ -612,6 +617,7 @@ export default {
this.enableMayChallengeHeader = shareChallengeExpData?.version === 'b';
this.optedIn = data?.my?.communicationSettings?.lenderNews || this.$route.query?.optedIn === 'true';
+ this.guestUsername = this.$route.query?.username ?? '';
// MyKiva Badges Experiment
this.myKivaExperimentEnabled = getIsMyKivaEnabled(
From 0d6dea05855d0597f3a00e57e41d75ee5547a8df Mon Sep 17 00:00:00 2001
From: Roger Gutierrez
Date: Wed, 19 Feb 2025 17:16:05 -0600
Subject: [PATCH 2/3] fix: optional chaining added to payload
---
src/components/Forms/GuestAccountCreation.vue | 2 +-
src/pages/Checkout/CheckoutPage.vue | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/Forms/GuestAccountCreation.vue b/src/components/Forms/GuestAccountCreation.vue
index 2bfc3386d0..e5b0941a69 100644
--- a/src/components/Forms/GuestAccountCreation.vue
+++ b/src/components/Forms/GuestAccountCreation.vue
@@ -138,7 +138,7 @@ export default {
throw new Error('Missing reset url');
}
if (this.guestUsername) {
- resetUrl += `?username=${this.guestUsername}`;
+ resetUrl += `&username=${this.guestUsername}`;
}
window.location = resetUrl;
diff --git a/src/pages/Checkout/CheckoutPage.vue b/src/pages/Checkout/CheckoutPage.vue
index 7ac0327293..28ff4544c5 100644
--- a/src/pages/Checkout/CheckoutPage.vue
+++ b/src/pages/Checkout/CheckoutPage.vue
@@ -876,7 +876,7 @@ export default {
if (this.checkingOutAsGuest) {
checkoutAdditionalQueryParams += `&optedIn=${this.userOptedIn}`;
}
- if (payload.username) {
+ if (payload?.username) {
checkoutAdditionalQueryParams += `&username=${payload.username}`;
}
From 3c5a4df27ef8c3fcf9d241622e4759fb8bf89bd6 Mon Sep 17 00:00:00 2001
From: Roger Gutierrez
Date: Wed, 19 Feb 2025 17:27:20 -0600
Subject: [PATCH 3/3] fix: router call fixed
---
.../LoginAndRegister/GuestAccountRedirect.vue | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/src/pages/LoginAndRegister/GuestAccountRedirect.vue b/src/pages/LoginAndRegister/GuestAccountRedirect.vue
index 149deaa7c9..1f0d6eb406 100644
--- a/src/pages/LoginAndRegister/GuestAccountRedirect.vue
+++ b/src/pages/LoginAndRegister/GuestAccountRedirect.vue
@@ -10,9 +10,8 @@ export default {
name: 'GuestAccountRedirect',
apollo: {
preFetch(config, client, { cookieStore, route }) {
- return Promise.all([
- client.query({
- query: gql`query guestRedirect($basketId: String) {
+ return client.query({
+ query: gql`query guestRedirect($basketId: String) {
shop (basketId: $basketId) {
id
nonTrivialItemCount
@@ -24,10 +23,7 @@ export default {
}
}
}`,
- }),
- route,
- ]).then(data => {
- const dataQuery = data[0].data;
+ }).then(({ data }) => {
// Add claimed=1 to the url to show a confirmation tip message on the page
const query = { claimed: 1 };
@@ -35,7 +31,7 @@ export default {
// Redirect to loan page if there is a pending guest comment
// Otherwise /portfolio
let path = '';
- if (dataQuery?.shop?.nonTrivialItemCount > 0) {
+ if (data?.shop?.nonTrivialItemCount > 0) {
path = '/checkout';
} else if (cookieStore.get(GUEST_COMMENT_COMMENT) && cookieStore.get(GUEST_COMMENT_LOANID)) {
path = `/lend/${cookieStore.get(GUEST_COMMENT_LOANID)}`;
@@ -48,8 +44,8 @@ export default {
.join('&');
// Check to see if user is authenticated
- if (!dataQuery?.my?.userAccount?.id) {
- const currentRoute = data[1].value ?? data[1] ?? {};
+ if (!data?.my?.userAccount?.id) {
+ const currentRoute = route.value ?? route ?? {};
const username = currentRoute.query?.username ?? '';
return Promise.reject({