Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for round-tripping the user through Unified Ecommerce on login #2515

Merged
merged 4 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
"filename": "frontend/public/src/lib/auth.js",
"hashed_secret": "e3c328a97de7239b3f60eecda765a69535205744",
"is_verified": false,
"line_number": 23
"line_number": 25
}
],
"frontend/public/src/lib/test_constants.js": [
Expand Down Expand Up @@ -240,5 +240,5 @@
}
]
},
"generated_at": "2024-11-05T12:32:12Z"
"generated_at": "2025-01-22T20:35:24Z"
}
4 changes: 4 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,10 @@
"description": "Token to access the status API.",
"required": false
},
"UNIFIED_ECOMMERCE_URL": {
"description": "The base URL for Unified Ecommerce.",
"required": false
},
"USE_X_FORWARDED_HOST": {
"description": "Set HOST header to original domain accessed by user",
"required": false
Expand Down
3 changes: 2 additions & 1 deletion frontend/public/src/flow/declarations.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ declare type Settings = {
digital_credentials: boolean,
digital_credentials_supported_runs: Array<string>,
posthog_api_token: ?string,
posthog_api_host: ?string
posthog_api_host: ?string,
unified_ecommerce_url: ?string,
}
declare var SETTINGS: Settings

Expand Down
21 changes: 20 additions & 1 deletion frontend/public/src/lib/auth.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// @flow
/* global SETTINGS: false */
import qs from "query-string"
import { isEmpty, includes, has } from "ramda"

import { routes } from "../lib/urls"
import { checkFeatureFlag } from "../lib/util"

import type { RouterHistory } from "react-router"
import type { AuthResponse, AuthStates } from "../flow/authTypes"
Expand Down Expand Up @@ -77,14 +79,31 @@ export const handleAuthResponse = (
) => {
/* eslint-disable camelcase */
const { state, redirect_url, partial_token, errors, field_errors } = response
// This is pre-login so we won't be able to flag this out for individual users.
// The use of "anonymousUser" is historical - see usage in PR #2064 for instance
const sendThruEcommerce = checkFeatureFlag(
"enable_unified_ecommerce",
"anonymousUser"
)

// If a specific handler function was passed in for this response state, invoke it
if (has(state, handlers)) {
handlers[state](response)
}

if (state === STATE_SUCCESS) {
window.location = redirect_url || routes.dashboard
const end_location = redirect_url || routes.dashboard
if (SETTINGS.unified_ecommerce_url && sendThruEcommerce) {
const ecommerce = new URL(`${SETTINGS.unified_ecommerce_url}`)

ecommerce.pathname = "establish_session/"
ecommerce.searchParams.set("next", end_location)
ecommerce.searchParams.set("system", "mitxonline")

window.location = ecommerce.href
} else {
window.location = end_location
}
} else if (state === STATE_LOGIN_PASSWORD) {
history.push(routes.login.password)
} else if (state === STATE_REGISTER_DETAILS) {
Expand Down
27 changes: 27 additions & 0 deletions frontend/public/src/lib/auth_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
import { routes } from "../lib/urls"
import { makeRegisterAuthResponse } from "../factories/auth"

const util = require("../lib/util")

describe("auth lib function", () => {
it("generateLoginRedirectUrl should generate a url to redirect to after login", () => {
window.location = "/protected/route?var=abc"
Expand Down Expand Up @@ -47,5 +49,30 @@ describe("auth lib function", () => {
sinon.assert.calledWith(handler, response)
})
})
;[true, false].forEach(flagState => {
it(`redirects through Unified Ecommerce properly if the feature flag is ${
flagState ? "enabled" : "disabled"
}`, () => {
const response = makeRegisterAuthResponse({
state: "success",
redirect_url: "/"
})
const handlers = {}
global.SETTINGS = {
unified_ecommerce_url: "http://ecommerce"
}

sandbox.stub(util, "checkFeatureFlag").returns(flagState)

assert.equal(
util.checkFeatureFlag("enable_unified_ecommerce", "anonymousUser"),
flagState
)

handleAuthResponse(history, response, handlers)

assert.equal(window.location.hostname, flagState ? "ecommerce" : "fake")
})
})
})
})
8 changes: 8 additions & 0 deletions main/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1199,3 +1199,11 @@
default="",
description="Hubspot Portal ID",
)

# Unified Ecommerce integration

UNIFIED_ECOMMERCE_URL = get_string(
name="UNIFIED_ECOMMERCE_URL",
default="http://ue.odl.local:9080/",
description="The base URL for Unified Ecommerce.",
)
1 change: 1 addition & 0 deletions main/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def get_js_settings(request: HttpRequest): # noqa: ARG001
"features": {},
"posthog_api_token": settings.POSTHOG_PROJECT_API_KEY,
"posthog_api_host": settings.POSTHOG_API_HOST,
"unified_ecommerce_url": settings.UNIFIED_ECOMMERCE_URL,
}


Expand Down
1 change: 1 addition & 0 deletions main/utils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def test_get_js_settings(settings, rf):
"features": {},
"posthog_api_token": settings.POSTHOG_PROJECT_API_KEY,
"posthog_api_host": settings.POSTHOG_API_HOST,
"unified_ecommerce_url": settings.UNIFIED_ECOMMERCE_URL,
}


Expand Down
Loading