-
Notifications
You must be signed in to change notification settings - Fork 3
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
Non-iOS Purple checkout flows (server-side) #11
Conversation
Add OTP authentication endpoints for the lightning checkout process, to allow users without Damus iOS to buy Purple Changelog-Added: Add OTP authentication support to the Purple LN checkout process Signed-off-by: Daniel D’Aquino <[email protected]>
Signed-off-by: Daniel D’Aquino <[email protected]>
14abd87
to
03e1e90
Compare
Actually, @jb55, give me a moment, I will double-check this PR on node.js 18 and our CI/nix configuration. Node v22.x is not LTS, so we might want to stay in v18.x |
Signed-off-by: Daniel D’Aquino <[email protected]>
Signed-off-by: Daniel D’Aquino <[email protected]>
03e1e90
to
8bdbd17
Compare
Restored Node 18 compatibility. Re-tested and updated all test reports. |
On Mon, Sep 30, 2024 at 01:16:22PM -0700, Daniel D’Aquino wrote:
Add OTP authentication endpoints for the lightning checkout process, to
allow users without Damus iOS to buy Purple
Changelog-Added: Add OTP authentication support to the Purple LN checkout process
Signed-off-by: Daniel D’Aquino ***@***.***>
Closes: #11
---
looks good!
Reviewed-by: William Casarin ***@***.***>
… src/router_config.js | 82 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 81 insertions(+), 1 deletion(-)
diff --git a/src/router_config.js b/src/router_config.js
index bcb7f89..22c531c 100644
--- a/src/router_config.js
+++ b/src/router_config.js
@@ -305,7 +305,87 @@ function config_router(app) {
}
})
- // MARK: OTP routes
+ // MARK: OTP lightning checkout routes
+
+ /**
+ * This route is used to request an OTP code for a specific checkout.
+ *
+ * @param {string} req.params.checkout_id - The ID of the checkout object.
+ * @param {string} req.params.pubkey - The public key of the user verifying the OTP.
+ *
+ * @returns {Object} - A JSON response indicating whether the OTP code was sent successfully
+ */
+ router.post('/ln-checkout/:checkout_id/request-otp/:pubkey', async (req, res) => {
+ const pubkey = req.params.pubkey
+ if (!pubkey) {
+ invalid_request(res, 'Could not parse account pubkey')
+ return
+ }
+
+ const checkout_id = req.params.checkout_id
+ if (!checkout_id) {
+ error_response(res, 'Could not parse checkout_id')
+ return
+ }
+
+ const otp_code = await app.web_auth_manager.generate_otp(pubkey)
+ await app.web_auth_manager.send_otp(pubkey, otp_code)
+ json_response(res, { success: true })
+ });
+
+ /**
+ * This route is used to verify an OTP code for a specific checkout.
+ *
+ * @param {string} req.params.checkout_id - The ID of the checkout object.
+ * @param {string} req.params.pubkey - The public key of the user verifying the OTP.
+ * @param {string} req.body.otp_code - The OTP code to verify.
+ *
+ * @returns {Object} - A JSON response containing the checkout object if the OTP is valid, or an error message if invalid.
+ */
+ router.put('/ln-checkout/:checkout_id/verify-otp/:pubkey', async (req, res) => {
+ const pubkey = req.params.pubkey
+ if (!pubkey) {
+ invalid_request(res, 'Could not parse account pubkey')
+ return
+ }
+
+ const checkout_id = req.params.checkout_id
+ if (!checkout_id) {
+ error_response(res, 'Could not parse checkout_id')
+ return
+ }
+
+ const otp_code = req.body.otp_code
+ if (!otp_code) {
+ invalid_request(res, 'Missing otp_code')
+ return
+ }
+
+ const is_valid = await app.web_auth_manager.validate_otp(pubkey, otp_code)
+ if(!is_valid) {
+ unauthorized_response(res, { valid: false })
+ return
+ }
+
+ try {
+ const response = await app.invoice_manager.verify_checkout_object(checkout_id, pubkey)
+ if (response.request_error) {
+ invalid_request(res, response.request_error)
+ }
+ if (response.checkout_object) {
+ const session_token = await app.web_auth_manager.create_session(pubkey)
+ json_response(res, {
+ checkout_object: response.checkout_object,
+ otp: { valid: true, session_token: session_token }
+ })
+ }
+ } catch (e) {
+ error("%s", e.toString())
+ invalid_request(res, e.toString())
+ }
+ })
+
+ // MARK: OTP login routes
router.post('/accounts/:pubkey/request-otp', async (req, res) => {
const pubkey = req.params.pubkey
|
Thanks! Merged! |
@danieldaquino I tried to do a purchase with an account with no profile, and I did not receive a DM |
Summary
This PR adds the following:
Checklist
Closes:
orFixes:
tags in the commit messages wherever applicable, or made sure those are not needed. See Submitting patches — Not needed, the related issue also depends on Non-iOS Purple checkout flows (client-side) website#28Test report
Test 1
damus-api:
8bdbd179536da01c3a74b1c8cb5cd7427437c672
Node: v18.20.4, running on NixOS
Steps: Run unit tests
Setup: Move
.env
file away to avoid env-dependent behaviorResults:
Test 2
See test report in damus-io/website#28
Other notes