#aaron_api

1 messages ยท Page 1 of 1 (latest)

zinc ploverBOT
#

๐Ÿ‘‹ Welcome to your new thread!

โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

๐Ÿ”— This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1279086989140033658

๐Ÿ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.

fresh jetty
#

Re: previous thread

#

Is there any way an account gets deauthorized without a double code consumption?

#

I'm not saying our code isn't duplicate consuming, it very well could be, but in our current system we're rejecting the second attempt at consuming the key

#

Sometimes our code runs twice in different containers (this itself is not fixable for us), so we save the code to a database which rejects any other inserts with the same ID

    static async #validateAuthCode(authCode) {
        try {
            await weivData.insert("Router", { _id: authCode });
            console.log("validateAuthCode PASSED", authCode);
            return true;
        } catch (error) {
            console.log("validateAuthCode REJECTED", authCode);
            return false;
        }
    }```
#

which the second attempt (in the console log pic above) gets rejected then returns

#
    static async connectStripeAccount(request) {
        try {
            const authCode = request.query.code;
            if (!await this.#validateAuthCode(authCode)) {
                return redirect("/dashboard");
            }
            const user = await Users.getCurrentUser();
            if (!user) {
                throw new Error("Priceable user not found.");
            }
            // redirect if user is already connected
            if (user.stripeRefreshToken) {
                return redirect("/dashboard");
            } else {
                // build request
                const secretKey = await keys.stripeSecretKey;
                const headers = {
                    "Authorization": "Basic " + Buffer.from(`${secretKey}:`).toString("base64"),
                    "Content-Type": "application/x-www-form-urlencoded"
                };
                const bodyParams = {
                    code: authCode,
                    grant_type: "authorization_code"
                };
                const accessTokenExpiresAt = new Date(Date.now() + ONE_HOUR);
                const response = await fetch(StripeUrls.stripeRefreshUrl(), {
                    method: "POST",
                    headers: headers,
                    body: new URLSearchParams(bodyParams).toString()
                });
                // save stripe user id and refresh token
                const responseData = await response.json();
                if (responseData["error"] === "access_denied") {
                    this.logger.error(`User ${user.id} denied Stripe access.`);
                    return redirect("/onboard");
                }
                if (responseData["error"] === "invalid_grant") {
                    throw new StripeInvalidGrantError(responseData["error_description"]);
                }
                const refreshToken = responseData["refresh_token"];
                const accessToken = responseData["access_token"];
                const stripeUserId = responseData["stripe_user_id"];
                if (refreshToken && stripeUserId && accessToken) {
                    const priceableUser = await Users.getPriceableUser();
                    // const client = new StripeClient(priceableUser);
                    // const customer = await client.createCustomer({
                    //     data: {
                    //         email: user.loginEmail,
                    //         metadata: {
                    //             priceable_user_id: user._id
                    //         }
                    //     }
                    // });
                    await weivData.update("Users", {
                        ...user,
                        // stripeCustomerId: customer.id,
                        stripeUserId: stripeUserId,
                        stripeRefreshToken: await crypto.encrypt(refreshToken),
                        stripeAccessToken: await crypto.encrypt(accessToken),
                        stripeAccessTokenExpiresAt: accessTokenExpiresAt,
                        stripeConnectedAt: new Date()
                    })
                    console.log("refreshToken", refreshToken);
                    console.log("accessToken", accessToken);
                    EmailClient.sendStripeConnectedEmail(user);
                    return redirect("/");
                } else {
                    throw new Error("Stripe account not found.");
                }
            }
        } catch (error) {
            this.logger.fromErrors(error);
            return notFound("Encountered an error when trying to connect Stripe account.");
        }
    }```
upbeat nest
#

Hi there ๐Ÿ‘‹ sorry for the delay, the server is quite busy at the moment. Yes, I believe it's possible for an account to disconnect from your app without you disconnecting them, but I'm not certain about that.

fresh jetty
#

hmm

#

we keep getting the Expired API key provided: Platform access may have been revolked error

#

And in the Stripe account events, you can see immediately after an authentication event a deauthentication event is fired

#

and I know that happens from trying to consume the code multiple times, which could be the issue here

#

but we've got logic to handle that case, and still hitting this issue

upbeat nest
#

Hm, if those Events are happening back-to-back, then it does sound most likely that the authorization code is being used more than once.

fresh jetty
#

hmm

#

maybe our logic is flawed somewhere

#

I only see our key consuming once, RAAAAH

upbeat nest
#

Yeah, I mean it looked like you were rejecting the second use

fresh jetty
#

yeah exactly

#

Just reuploading here without sensitive data

#

OH MY GOD I FIGURED IT OUT

#

When it gets rejected ONCE the installed app only provides "expired" API keys

#

so it got rejected once, and every time I tried to re-connect the app, it technically was still unaothorized

#

so I completely removed the app from my Stripe account, tried again, and boom!

upbeat nest
#

Oohh, nice spot!!

fresh jetty
#

This will be hard to explain to customers if they hit this situation hahaha

#

EIther way we're good now!

#

Thank you for your help my dude

upbeat nest
#

Haha, happy to be a rubber duck, but you did all the hard work here!