i am making an iOS application that requires Railway hosting
swiftdev12
HOBBYOP

10 months ago

i need help because the token for railway is not fetching the data

[DEBUG] Token check errors: [["message": Not Authorized, "locations": <__NSSingleObjectArrayI 0x3008ad2c0>(
{
    column = 3;
    line = 1;
}
)
, "extensions": {
    code = "INTERNAL_SERVER_ERROR";
}, "traceId": 8832626437516036942, "path": <__NSSingleObjectArrayI 0x3008ad1e0>(
me
)
]]
[DEBUG] Token check errors: [["extensions": {
    code = "INTERNAL_SERVER_ERROR";
}, "path": <__NSSingleObjectArrayI 0x3008a9d00>(
me
)
, "locations": <__NSSingleObjectArrayI 0x3008a9cb0>(
{
    column = 3;
    line = 1;
}

for validating the token

    @MainActor
    func validateToken(_ token: String) async {
        do {
            let url = URL(string: "https://backboard.railway.com/graphql/v2")!
            var request = URLRequest(url: url)
            request.httpMethod = "POST"
            request.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
            request.addValue("application/json", forHTTPHeaderField: "Content-Type")
            let query = [
                "query": "{ me { id } }"
            ]
            request.httpBody = try JSONSerialization.data(withJSONObject: query)
            let (data, _) = try await URLSession.shared.data(for: request)
            let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
            if let errors = json?["errors"] as? [[String: Any]] {
                print("[DEBUG] Token check errors: \(errors)")
                self.tokenIsValid = false
            } else {
                self.tokenIsValid = true
            }
        } catch {
            print("[DEBUG] Token check failed: \(error)")
            self.tokenIsValid = false
        }
    }
$10 Bounty

104 Replies

swiftdev12
HOBBYOP

10 months ago

c0b1c5d4-96ca-4b6e-afa2-008f3212532a


9 months ago

please provide the exact query you are using


swiftdev12
HOBBYOP

9 months ago

wym?


swiftdev12
HOBBYOP

9 months ago

this is what I am using


9 months ago

i'm sorry but i dont see the graphql query you are making, you have not provided it in your code examples


swiftdev12
HOBBYOP

9 months ago

oh


9 months ago

i have bountied this thread so that the community can help you


swiftdev12
HOBBYOP

9 months ago

ok


swiftdev12
HOBBYOP

9 months ago

// ────────── Static GraphQL queries
private enum GraphQLQuery {
    static let me: [String: String] = [
        "query":
        """
        {
          me {
            projects {
              edges { node { id name } }
            }
          }
        }
        """
    ]

    static let validate: [String: String] = [
        "query":
        """
        { me { id } }
        """
    ]
}

9 months ago

i will step out and let the community involve themselves in this thread


9 months ago

Hey.

You can only retrieve account data (such as your ID) with an authorization token that is not assigned to any workspace.

As stated in the documentation:

Note: This query cannot be used with a team or project token because the data returned is scoped to your personal account.

swiftdev12
HOBBYOP

9 months ago

ok


9 months ago

Did not realize this was a Discord thread, but hi.


swiftdev12
HOBBYOP

9 months ago

hi lol


swiftdev12
HOBBYOP

9 months ago

So I cannot allow users to upload their website to railway? like they create a project within my app, .html, .css, .js.. and upload to railway and begin hosting?


swiftdev12

So I cannot allow users to upload their website to railway? like they create a project within my app, .html, .css, .js.. and upload to railway and begin hosting?

9 months ago

You absolutely can. Are you looking to have it create one in a specific project that the user selects over on Railway?


swiftdev12
HOBBYOP

9 months ago

Basically, what I am trying to do is in side of settings allow users to see all of t heir projects in real time, but also in the main app, they have a projects area where they can create a project, name it, open it, select .html, .css, .js files, what ever they want.. and once they have done they can review it or, if they want to host it they can. if this makes sense


swiftdev12
HOBBYOP

9 months ago

Like GitHub but also have railway

1380942138174603300


swiftdev12
HOBBYOP

9 months ago

Like this

1380942213302718700


9 months ago

You'll need to have the user provide an account unscoped token then


swiftdev12
HOBBYOP

9 months ago

where do you find this?


9 months ago

1380942429934325800



swiftdev12
HOBBYOP

9 months ago

I did this but it didn't work


swiftdev12
HOBBYOP

9 months ago

I tried both


swiftdev12
HOBBYOP

9 months ago

When I try no workspace

1380943007477531000


9 months ago

I'm going to test this locally


swiftdev12
HOBBYOP

9 months ago

ok


9 months ago

Okay I can't even resolve the DNS so I'm not going to spend time trying to figure thatout


swiftdev12
HOBBYOP

9 months ago

lol


9 months ago

Literally the only possible option here is you provided an invalid unscoped account token


swiftdev12
HOBBYOP

9 months ago

nope.


swiftdev12
HOBBYOP

9 months ago

fresh token.


swiftdev12
HOBBYOP

9 months ago

literally created one


9 months ago

And it says no workspace.


swiftdev12
HOBBYOP

9 months ago

yh


swiftdev12
HOBBYOP

9 months ago

I can send a video


9 months ago

impossible


9 months ago

are you passing it to the method correctly?


9 months ago

have you tried printing the token before sending the request to make sure it matches?


swiftdev12
HOBBYOP

9 months ago

shall i provide video?


swiftdev12
HOBBYOP

9 months ago

ye


swiftdev12
HOBBYOP

9 months ago

it matches.


9 months ago

nuh uh


swiftdev12
HOBBYOP

9 months ago

let me do it again, and show the print


swiftdev12
HOBBYOP

9 months ago

when I do a no workspace one

[ACTION] Token saved 
[TEST] Validating token (36 chars)...
[TEST] Trying validation with header 'Authorization'
[ERROR] Validation with header 'Authorization' failed: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0., NSJSONSerializationErrorIndex=0}
[TEST] Trying validation with header 'Team-Access-Token'
[ERROR] Validation with header 'Team-Access-Token' failed: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0., NSJSONSerializationErrorIndex=0}
[TEST] Token is NOT valid for either token type.
[ACTION] Token saved 
[TEST] Validating token (36 chars)...
[TEST] Trying validation with header 'Authorization'
[ERROR] Validation with header 'Authorization' failed: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0., NSJSONSerializationErrorIndex=0}
[TEST] Trying validation with header 'Team-Access-Token'
[ERROR] Validation with header 'Team-Access-Token' failed: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0., NSJSONSerializationErrorIndex=0}
[TEST] Token is NOT valid for either token type.

swiftdev12
HOBBYOP

9 months ago

[ACTION] Token saved ✓
[TEST] Validating token (36 chars)…
[TEST] ❌ Invalid token, status code: 404

this is all I get with unscoped..


9 months ago

yeah but if you literally print the token and compare it to the unscoped token in the railway dashboard


9 months ago

are they the same.


swiftdev12
HOBBYOP

9 months ago

I will check.


9 months ago

no spaces, make sure you trim it


swiftdev12
HOBBYOP

9 months ago

ok


swiftdev12
HOBBYOP

9 months ago

will reply in a moment


swiftdev12
HOBBYOP

9 months ago

[DEBUG] Raw token: ' 8203e817-a94c-4dc6-90d4-c5c78b593d73\n'
[DEBUG] Trimmed token: '8203e817-a94c-4dc6-90d4-c5c78b593d73'


9 months ago

Don't send your token 🙏


9 months ago

But I get it


swiftdev12
HOBBYOP

9 months ago

I can revoke np


9 months ago

So does it work trimmed?


swiftdev12
HOBBYOP

9 months ago

yh


9 months ago

Because I see a \n at the end there!


9 months ago

HOOOrah


swiftdev12
HOBBYOP

9 months ago

yuo


swiftdev12
HOBBYOP

9 months ago

but it still says invalid


swiftdev12
HOBBYOP

9 months ago

in the app


9 months ago

oh


swiftdev12
HOBBYOP

9 months ago

trying to figure it out


9 months ago

It must be an issue with your swift


9 months ago

Because it works totally fine for me


9 months ago

With that token


9 months ago

1380949616937275400


swiftdev12
HOBBYOP

9 months ago

Ill check


9 months ago

how'd the checking go


swiftdev12
HOBBYOP

9 months ago

im waiting


swiftdev12
HOBBYOP

9 months ago

<title>Access denied | backboard.railway.com used Cloudflare to restrict acces
[ERROR] Received HTML response from Cloudflare. Probably rate limited or blocked.
[RAW] HTTP 429: &lt;!DOCTYPE html&gt;
&lt;!--[if lt IE 7]&gt; &lt;html class="no-js ie6 oldie" lang="en-US"&gt; &lt;![endif]--&gt;
&lt;!--[if IE 7]&gt;    &lt;html class="no-js ie7 oldie" lang="en-US"&gt; &lt;![endif]--&gt;
&lt;!--[if IE 8]&gt;    &lt;html class="no-js ie8 oldie" lang="en-US"&gt; &lt;![endif]--&gt;
&lt;!--[if gt IE 8]&gt;&lt;!--&gt; &lt;html class="no-js" lang="en-US"&gt; &lt;!--&lt;![endif]--&gt;
&lt;head&gt;
&lt;title&gt;Access denied | backboard.railway.com used Cloudflare to restrict acces
[ERROR] Received HTML response from Cloudflare. Probably rate limited or blocked.

9 months ago

heh


swiftdev12
HOBBYOP

9 months ago

the token is currently matched. just this issue.


9 months ago

If this is an IOS app is your app in sandbox?


9 months ago

If so have you enabled network connections


9 months ago

1381074814713987000


swiftdev12
HOBBYOP

9 months ago

maybe.. I will check tomorrow.


9 months ago

Sounds good


9 months ago

Unless you set it as not such it is running sandboxed


9 months ago

Why would it be able to establish the connection at all?


9 months ago

It's clearly getting a response


9 months ago

My app returned access denied


9 months ago

The os acts like a proxy and manually rejects the req


9 months ago

Sus.


9 months ago

Safe <:picassoface:1281722225593946123>


swiftdev12
HOBBYOP

9 months ago

this is macOS app. as on iOS app, I don't have an option for App Sandbox


swiftdev12
HOBBYOP

9 months ago

[TEST] ✅ Token is valid


swiftdev12
HOBBYOP

9 months ago

```swift
[RAW] HTTP Response: {"data":{"me":{"id":"3b0f4a67-a410","name":null}}}

[TEST] ✅ Token is valid (Account token, user id 3b0f4a67-a410)
[ACTION] Token saved ✓ → 'b4142c1d-4660'
[DEBUG] Raw token: 'b4142c1d-4660'
[DEBUG] Trimmed token: 'b4142c1d-4660'
[RAW] HTTP Response: {"data":{"me":{"id":"3b0f4a67-a410","name":null}}}

[TEST] ✅ Token is valid (Account token, user id 3b0f4a67-a410)
```


swiftdev12
HOBBYOP

9 months ago

Next part is fetching projects.


swiftdev12
HOBBYOP

9 months ago

I fixed the token check by using Railway’s official GraphQL API, so now it always works and gives error messages, when needed.


swiftdev12
HOBBYOP

9 months ago

[SUCCESS] Fetched 0 Railway project(s) for user.

i have been using github for my projects.. lol.


9 months ago

What was the solution?


swiftdev12
HOBBYOP

9 months ago

before?


9 months ago

Yeah


swiftdev12
HOBBYOP

9 months ago

this is what I was getting before


9 months ago

And how did you fix it


swiftdev12
HOBBYOP

9 months ago

I fixed the token check by using Railway’s official GraphQL API, so now it always works and gives error messages, when needed.


swiftdev12
HOBBYOP

9 months ago

let me see if I can go back to old code


swiftdev12
HOBBYOP

9 months ago

and show difference


swiftdev12
HOBBYOP

9 months ago

Old code

// Possibly wrong endpoint
request.httpBody = try JSONSerialization.data(withJSONObject: [
    "query": "{ me { projects { edges { node { id name } } } } }"
])

new code

@MainActor
func validateToken(_ token: String) async {
    let trimmed = token.trimmingCharacters(in: .whitespacesAndNewlines)
    Logger.debug("[DEBUG] Raw token: '\(token)'")
    Logger.debug("[DEBUG] Trimmed token: '\(trimmed)'")

    guard !trimmed.isEmpty else {
        Logger.error("[ERROR] Token is empty after trimming.")
        tokenIsValid = false
        errorMessage = "Token is empty."
        return
    }

    guard let url = URL(string: endpoint) else {
        Logger.error("[ERROR] Invalid endpoint URL")
        tokenIsValid = false
        errorMessage = "Internal error: bad endpoint."
        return
    }

    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("Bearer \(trimmed)", forHTTPHeaderField: "Authorization")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue("VisionCode/1.0 (iPhone; iOS 17.0; Scale/3.00)", forHTTPHeaderField: "User-Agent")

    do {
        // Use minimal GraphQL query for token validation!
        request.httpBody = try JSONSerialization.data(withJSONObject: [
            "query": "{ me { id } }"
        ])
    } catch {
        Logger.error("[ERROR] Failed to encode GraphQL query: \(error)")
        tokenIsValid = false
        errorMessage = "Internal error (query encode fail)."
        return
    }

    do {
        let (data, response) = try await URLSession.shared.data(for: request)
        let raw = String(data: data, encoding: .utf8) ?? ""
        Logger.success("[RAW] HTTP Response: \(raw.prefix(400))")

        guard let http = response as? HTTPURLResponse else {
            Logger.error("[ERROR] No HTTP response received.")
            tokenIsValid = false
            errorMessage = "No HTTP response received."
            return
        }

        if http.statusCode == 200 {
            if let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
               let dataField = json["data"] as? [String: Any],
               let me = dataField["me"] as? [String: Any],
               let id = me["id"] as? String {
                Logger.success("[TEST] ✅ Token is valid (Account token, user id \(id))")
                tokenIsValid = true
                errorMessage = nil
                usedHeaderKey = "Authorization"
                return
            } else if let errors = (try? JSONSerialization.jsonObject(with: data) as? [String: Any])?["errors"] as? [[String: Any]],
                      let errorMsg = errors.first?["message"] as? String {
                Logger.error("[TEST] ❌ Token invalid: \(errorMsg)")
                tokenIsValid = false
                errorMessage = errorMsg
                return
            } else {
                Logger.error("[ERROR] No user data returned.")
                tokenIsValid = false
                errorMessage = "No user data returned."
                return
            }
        } else {
            Logger.error("[ERROR] HTTP \(http.statusCode): \(raw.prefix(120))")
            tokenIsValid = false
            errorMessage = "HTTP error \(http.statusCode)."
            return
        }
    } catch {
        Logger.error("[ERROR] Validation failed with error: \(error)")
        tokenIsValid = false
        errorMessage = "Network error: \(error.localizedDescription)"
        return
    }
}

swiftdev12
HOBBYOP

9 months ago

@Loudbook


Loading...