You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? Keep it simple and clear!
I want my application to successfully log a user in. -
What is the issue? Include screenshots / videos if possible!
“Argument does not respect the defined limits”
-
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I tried using the sample code but it didn’t work. The code couldn’t even import the values from the env file.
I have attached the relevant pieces of code along with the explorer view.
app.js
const crypto = require('crypto');
const axios = require('axios')
const express = require('express')
const app = express()
app.use(express.static('public'))
let redirectURI = "https://holocafe.nwygo.com/authorize" // Note to self: Would redirect them to /authorize?code={code} | I can then access the code using params with express or smth ig
function base64URLEncode(str) {
return str.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
console.log("1")
function sha256(buffer) {
return crypto.createHash('sha256').update(buffer).digest(`base64`);
}
var code_verifier = base64URLEncode(crypto.randomBytes(32));
// generate a challenge from the code verifier
var code_challenge = base64URLEncode(sha256(code_verifier));
console.log("2")
console.log("3")
function exchangeWithCode(code) {
const data = new URLSearchParams();
data.append('grant_type', "authorization_code");
data.append('client_id', process.env["clientID"]);
data.append('client_secret', process.env["clientSecret"]);
data.append('code', code)
axios.post('https://apis.roblox.com/oauth/v1/token', data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
return response
})
.catch(error => {
console.error(error);
return `Failed. Error: ${error}`
});
}
console.log("4")
function exchangeWithRefreshToken(refreshToken) {
const data = new URLSearchParams();
data.append('grant_type', "authorization_code");
data.append('client_id', process.env["clientID"]);
data.append('client_secret', process.env["clientSecret"]);
data.append('refresh_token', refreshToken)
axios.post('https://apis.roblox.com/oauth/v1/token', data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
return response
})
.catch(error => {
console.error(error);
return `Failed. Error: ${error}`
});
}
console.log("5")
function getUserInfo(authCode) { // https://create.roblox.com/docs/cloud/reference/oauth2#get-v1userinfo
axios.get('https://apis.roblox.com/oauth/v1/userinfo', {
headers: {
'Authorization': `Bearer ${authCode}`
}
})
.then(response => {
return response
})
.catch(error => {
console.error(error);
});
}
console.log("6")
console.log("7")
app.get('/authorize', (req, res) => {
if (req.query.method = "code") {
if (req.query.code) {
// Successfully authorized. Run code to exchange for token
let request = exchangeWithCode(req.query.code)
let token = request.query.access_token
let refreshToken = request.query.refresh_token
let userInfo = getUserInfo(token)
// Add code to store new refreshToken
res.send({userInfo})
} else {
console.log(`Failed to authorize. Error: ${req.error}. Description: ${req.error_description}. State: ${req.state}`)
res.send("Failed")
}
} else if (req.query.method == "rf") {
if (req.query.rf) {
// Successfully authorized. Run code to exchange for token
let request = exchangeWithRefreshToken(req.query.rf)
let token = request.query.access_token
let refreshToken = request.query.refresh_token
// Add code to store new refreshToken
} else {
console.log(req)
console.log(`Failed to authorize. Error: ${req.error}. Description: ${req.error_description}. State: ${req.state}`)
res.send("Failed")
}
} else {
res.send("Invalid method")
}
})
console.log("8")
app.get('/logout', (req, res) => {
// will do later -- https://create.roblox.com/docs/cloud/reference/oauth2#post-v1tokenrevoke
})
console.log("9")
app.listen(25024)
console.log("10")
script.js
var scopes = ["openid", "profile", "group:read"]; // Replace with all the scopes
function generateRandomString(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
function base64URLEncode(str) {
return btoa(str)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
async function sha256(plain) {
// Returns the SHA-256 hash of the input string
const encoder = new TextEncoder();
const data = encoder.encode(plain);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join('');
return hashHex;
}
// Generate code verifier and challenge
var code_verifier = generateRandomString(128);
var code_challenge = base64URLEncode(sha256(code_verifier));
let redirectURI = "https://holocafe.nwygo.com/authorize" // Note to self: Would redirect them to /authorize?code={code} | I can then access the code using params with express or smth ig
var OAuthURL = "https://apis.roblox.com/oauth/v1/authorize" +
"?client_id=2969482479946332042" +
"&code_challenge=" + code_challenge +
"&code_challenge_method=S256" +
"&redirect_uri=" + redirectURI +
"&scope=" + scopes.join("%20") +
"&response_type=code" +
"&state=abc123";
console.log("OAuthURL:", OAuthURL);
let authButton = document.getElementById('authButton')
authButton.href = OAuthURL
Please help