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

a year 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

a year ago

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


a year ago

please provide the exact query you are using


swiftdev12
HOBBYOP

a year ago

wym?


swiftdev12
HOBBYOP

a year ago

this is what I am using


a year 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

a year ago

oh


a year ago

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


swiftdev12
HOBBYOP

a year ago

ok


swiftdev12
HOBBYOP

a year 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 } }
        """
    ]
}

a year ago

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


a year 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

a year ago

ok


a year ago

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


swiftdev12
HOBBYOP

a year ago

hi lol


swiftdev12
HOBBYOP

a year 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?

a year 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

a year 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

a year ago

Like GitHub but also have railway

1380942138174603374


swiftdev12
HOBBYOP

a year ago

Like this

1380942213302718627


a year ago

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


swiftdev12
HOBBYOP

a year ago

where do you find this?


a year ago

1380942429934325851



swiftdev12
HOBBYOP

a year ago

I did this but it didn't work


swiftdev12
HOBBYOP

a year ago

I tried both


swiftdev12
HOBBYOP

a year ago

When I try no workspace

1380943007477530764


a year ago

I'm going to test this locally


swiftdev12
HOBBYOP

a year ago

ok


a year ago

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


swiftdev12
HOBBYOP

a year ago

lol


a year ago

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


swiftdev12
HOBBYOP

a year ago

nope.


swiftdev12
HOBBYOP

a year ago

fresh token.


swiftdev12
HOBBYOP

a year ago

literally created one


a year ago

And it says no workspace.


swiftdev12
HOBBYOP

a year ago

yh


swiftdev12
HOBBYOP

a year ago

I can send a video


a year ago

impossible


a year ago

are you passing it to the method correctly?


a year ago

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


swiftdev12
HOBBYOP

a year ago

shall i provide video?


swiftdev12
HOBBYOP

a year ago

ye


swiftdev12
HOBBYOP

a year ago

it matches.


a year ago

nuh uh


swiftdev12
HOBBYOP

a year ago

let me do it again, and show the print


swiftdev12
HOBBYOP

a year 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

a year ago

[ACTION] Token saved ✓

[TEST] Validating token (36 chars)...

[TEST] ❌ Invalid token, status code: 404

this is all I get with unscoped..


a year ago

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


a year ago

are they the same.


swiftdev12
HOBBYOP

a year ago

I will check.


a year ago

no spaces, make sure you trim it


swiftdev12
HOBBYOP

a year ago

ok


swiftdev12
HOBBYOP

a year ago

will reply in a moment


swiftdev12
HOBBYOP

a year ago

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

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


a year ago

Don't send your token 🙏


a year ago

But I get it


swiftdev12
HOBBYOP

a year ago

I can revoke np


a year ago

So does it work trimmed?


swiftdev12
HOBBYOP

a year ago

yh


a year ago

Because I see a \n at the end there!


a year ago

HOOOrah


swiftdev12
HOBBYOP

a year ago

yuo


swiftdev12
HOBBYOP

a year ago

but it still says invalid


swiftdev12
HOBBYOP

a year ago

in the app


a year ago

oh


swiftdev12
HOBBYOP

a year ago

trying to figure it out


a year ago

It must be an issue with your swift


a year ago

Because it works totally fine for me


a year ago

With that token


a year ago

1380949616937275392


swiftdev12
HOBBYOP

a year ago

Ill check


a year ago

how'd the checking go


swiftdev12
HOBBYOP

a year ago

im waiting


swiftdev12
HOBBYOP

a year 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.

a year ago

heh


swiftdev12
HOBBYOP

a year ago

the token is currently matched. just this issue.


a year ago

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


a year ago

If so have you enabled network connections


a year ago

1381074814713987092


swiftdev12
HOBBYOP

a year ago

maybe.. I will check tomorrow.


a year ago

Sounds good


a year ago

Unless you set it as not such it is running sandboxed


a year ago

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


a year ago

It's clearly getting a response


a year ago

My app returned access denied


a year ago

The os acts like a proxy and manually rejects the req


a year ago

Sus.


a year ago

Safe <:picassoface:1281722225593946123>


swiftdev12
HOBBYOP

a year ago

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


swiftdev12
HOBBYOP

a year ago

[TEST] ✅ Token is valid


swiftdev12
HOBBYOP

a year ago

[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

a year ago

Next part is fetching projects.


swiftdev12
HOBBYOP

a year 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

a year ago

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

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


a year ago

What was the solution?


swiftdev12
HOBBYOP

a year ago

before?


a year ago

Yeah


swiftdev12
HOBBYOP

a year ago

this is what I was getting before


a year ago

And how did you fix it


swiftdev12
HOBBYOP

a year 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

a year ago

let me see if I can go back to old code


swiftdev12
HOBBYOP

a year ago

and show difference


swiftdev12
HOBBYOP

a year 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

a year ago

@Loudbook


Welcome!

Sign in to your Railway account to join the conversation.

Loading...