Svelte: Hooks.js file is not getting recently created cookies - node.js

Someone knows why my hooks.js file not getting recently created cookies
When I do login with discord api in my svelte website, the cookies are created and the hooks only get it minutes after.
Someone can help me please?.....
I'm using parts of the medium discord Oauth2 svelte example
import cookie from 'cookie';
const DISCORD_API_URL = import.meta.env.VITE_DISCORD_API_URL;
const HOST = import.meta.env.VITE_HOST;
/** #type {import('#sveltejs/kit').GetSession} */
export async function getSession(req) {
const cookies = cookie.parse(req.request.headers.get("cookie") || '');
console.log(cookies)
// if only refresh token is found, then access token has expired. perform a refresh on it.
if (cookies.disco_refresh_token && !cookies.disco_access_token) {
console.log("Tem o refresh mas não tem o acess")
const discord_request = await fetch(`${HOST}/api/refresh?code=${cookies.disco_refresh_token}`);
const discord_response = await discord_request.json();
if (discord_response.disco_access_token) {
console.log('setting discord user via refresh token..')
const request = await fetch(`${DISCORD_API_URL}/users/#me`, {
headers: { 'Authorization': `Bearer ${discord_response.disco_access_token}` }
});
const response = await request.json();
if (response.id) {
return {
user: {
// only include properties needed client-side —
// exclude anything else attached to the user
// like access tokens etc
...response
}
}
}
}
}
if (cookies.disco_access_token) {
console.log('setting discord user via access token..')
const request = await fetch(`${DISCORD_API_URL}/users/#me`, {
headers: { 'Authorization': `Bearer ${cookies.disco_access_token}`}
});
// returns a discord user if JWT was valid
const response = await request.json();
if (response.id) {
return {
user: {
...response
}
}
}
}
// not authenticated, return empty user object
return {
user: false
}
}
My Auth callback file:
const DISCORD_CLIENT_ID = import.meta.env.VITE_DISCORD_CLIENT_ID;
const DISCORD_CLIENT_SECRET = import.meta.env.VITE_DISCORD_CLIENT_SECRET;
const DISCORD_REDIRECT_URI = import.meta.env.VITE_DISCORD_REDIRECT_URI;
/**
* #type {import('#sveltejs/kit').RequestHandler}
*/
export async function get({ url }) {
// fetch returnCode set in the URL parameters.
const returnCode = url.searchParams.get("code");
console.log('returnCode =>', returnCode);
// initializing data object to be pushed to Discord's token endpoint.
// the endpoint returns access & refresh tokens for the user.
const dataObject = {
client_id: DISCORD_CLIENT_ID,
client_secret: DISCORD_CLIENT_SECRET,
grant_type: 'authorization_code',
redirect_uri: DISCORD_REDIRECT_URI,
code: returnCode,
scope: 'identify email guilds'
};
// performing a Fetch request to Discord's token endpoint
const request = await fetch('https://discord.com/api/oauth2/token', {
method: 'POST',
body: new URLSearchParams(dataObject),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
const response = await request.json();
console.log(response)
if (response.error) {
console.log('redirect to / due error');
return {
headers: { Location: '/' },
status: 302
}
}
// redirect user to front page with cookies set
const access_token_expires_in = new Date(Date.now() + response.expires_in); // 10 minutes
const refresh_token_expires_in = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000); // 30 days
console.log('redirect to /logged with cookies');
return {
headers: {
'set-cookie': [
`disco_access_token=${response.access_token}; Path=/; HttpOnly; SameSite=Strict; Expires=${access_token_expires_in}}`,
`disco_refresh_token=${response.refresh_token}; Path=/; HttpOnly; SameSite=Strict; Expires=${refresh_token_expires_in}`,
],
Location: '/'
},
status: 302
}
}

Related

Implementation of rxjs BehaviourSubject in Next.js for state management not working

Trying to store jwt token on login using rxjs behavioursubject
Then creating a http request with Authorization: Bearer ${user.jwtToken} in the
I believe I need to have
a) initial value,
b) a source that can be turned into an observable
c) a public variable that can be subscribed
On log in the user is correctly added to the user subject here "userSubject.next(user);"
But whenever I try to create the bearer token its always null
// The Accounts Service
// initialise and set initial value
const userSubject = new BehaviorSubject(null);
const authApiUrl = "https:testApi";
export const accountService = {
` user: userSubject.asObservable(), get userValue() { return userSubject.value },
login,
getAllUsers
};
function login(email, password) {
return fetchWrapper.post(process.env.AuthApiUrl + '/accounts/authenticate', { email, password })
.then(user => {
userSubject.next(user);
localStorage.setItem('user', JSON.stringify(user));
return user;
});
}
function getAllUsers() {
return await fetchWrapper.get(process.env.AuthApiUrl + '/accounts/get-all-users');
}
}
// The fetchwrapper
export const fetchWrapper = {
get,
post
};
function post(url, body) {
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json', ...authHeader(url) },
credentials: 'include',
body: JSON.stringify(body)
};
return fetch(url, requestOptions).then(handleResponse);
}
function get(url) {
const requestOptions = {
method: 'GET',
headers: authHeader(url)
};
return fetch(url, requestOptions).then(handleResponse);
}
function authHeader(url) {
// return auth header with basic auth credentials if user is logged in and request is to the api url
// THE accountService.userValue IS ALWAYS NULL???
const user = accountService.userValue;
const isLoggedIn = user && user.jwtToken;
const isApiUrl = url.startsWith(process.env.AuthApiUrl);
if (isLoggedIn && isApiUrl) {
return { Authorization: `Bearer ${user.jwtToken}` };
} else {
return {};
}
}
function handleResponse(response) {
return response.text().then(text => {
const data = text && JSON.parse(text);
if (!response.ok) {
if ([401, 403].includes(response.status) && accountService.userValue) {
// auto logout if 401 Unauthorized or 403 Forbidden response returned from api
accountService.logout();
}
const error = (data && data.message) || response.statusText;
return Promise.reject(error);
}
return data;
});
}

axios post request getting error 500 fdretdrgfdg

A post request with axios get http error 500.
This is the code:
async function getUserTokenByRefresh(refreshToken) {
const encodedStr = base64Encode(`${process.env.EBAY_SANDBOX_APPID}:${process.env.EBAY_SANDBOX_CERTID}`);
const auth = `Basic ${encodedStr}`;
const options = {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Authorization: auth
}
};
const data = {
grant_type: "refresh_token",
refresh_token: refreshToken
};
const testing = true;
const url = testing
? "https://api.sandbox.ebay.com/identity/v1/oauth2/token"
: "https://api.ebay.com/identity/v1/oauth2/token";
try {
const response = await axios.post(
url,
data,
options
);
console.log(JSON.stringify(response));
}
catch (e) {
console.log(JSON.stringify(e));
}
}
This is the error message:
{
"message": "Request failed with status code 500",
"code": "ERR_BAD_RESPONSE",
"status": 500
}
This is the error message in json format.
I don't know what's wrong in the code.
Can you check it?
Data should be encoded.
async function getUserTokenByRefresh(refreshToken) {
const encodedStr = base64Encode(`${process.env.EBAY_SANDBOX_APPID}:${process.env.EBAY_SANDBOX_CERTID}`);
const auth = `Basic ${encodedStr}`;
const options = {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Authorization: auth
}
};
const data = {
grant_type: "refresh_token",
refresh_token: refreshToken
};
const testing = true;
const url = testing
? "https://api.sandbox.ebay.com/identity/v1/oauth2/token"
: "https://api.ebay.com/identity/v1/oauth2/token";
try {
const response = await axios.post(
url,
//ENCODED DATA
new URLSearchParams(data),
options
);
console.log(JSON.stringify(response));
}
catch (e) {
console.log(JSON.stringify(e));
}
}

Axios - How to get the Cookies from the response?

I need to get an authentication cookie from a website, while performing my request using Axios.
var axios = require('axios');
const authentication = async(login, password) => {
var data = `MYPAYLOAD${login}[...]${password}`;
var config = {
method: 'post',
url: 'https://mywebsite.com/login.aspx',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data : data,
};
try {
return await axios(config, {withCredentials: true});
} catch (error) {
console.log('Error: cannot authenticate...')
}
}
const init = async() => {
const login = 'LOGIN';
const password = 'PASSWORD';
const response = await authentication(login, password);
console.log(response);
}
init()
I'm receiving some Cookies that I need, but the one including the auth token is missing.
If I use exactly the same settings in Postman, I'm receiving the AUTH_TOKEN I'm looking for.
Where am I wrong?
Thanks

SyntaxError: Unexpected end of JSON input - Passport-local

I am using passport local and I already got the user data using req.session.passport.user
But for some reason I am having trouble receiving the user data by using Ajax or fetch request.
Any ideas?
app.get('/api/student/compose', function(req, res) {
if (req.isAuthenticated()) {
res.json({
data: req.session.passport.user
});
} else {
res.json({data: "Not logged in!"});
}
});
The following code is on the client side:
/**
* Get the user data
*
* #returns {Object} Return the user data
*/
async userData() {
let url = `http://localhost:3000/api/student/compose`;
let receivingData = {};
await fetch(url, {
method: "get",
mode: "cors",
headers: {
Accept: "application/json", // expected data sent back
}
}).then((data) => {
receivingData.data = data;
receivingData.err = false;
})
.catch((error) => {
receivingData.err = true;
receivingData.errMessage = error;
});
return receivingData;
}

How do I store JWT Token after receiving from Cognito? Logging in via the Cognito Hosted UI

Architecture: front end Angular, backend nodejs/express.
Currently the setup works as follow:
Login to the site via the Cognito Hosted UI
This redirects to our home page and sends us a code in the URL
I pull down this code in Angular
import { Component, OnInit } from '#angular/core';
import { DbService } from '../db.service';
import { Iss } from '../db.service';
import { Router, ActivatedRoute } from '#angular/router';
import { Http, Response, RequestOptions, Headers} from '#angular/http';
#Component({
selector: 'app-dashboard'
})
export class GroupSelectionComponent implements OnInit {
cognitoCode: string;
constructor(
private DbService: DbService,
private route: ActivatedRoute,
private router: Router
) {}
ngOnInit() {
this.route.queryParams
.subscribe(params => {
console.log(params);
console.log(params.code);
this.cognitoCode = params.code;
});
this.DbService.getIss(this.cognitoCode).subscribe(
iss => this.iss = iss
);
}
In the code you will see I am passing the congitocode to the dbservice for getIss.
db.service
getIss(cognitoCode ): Observable<Issuer[]> {
const url = hosturl +'i_l';
// let header: HttpHeaders = new HttpHeaders();
const httpOptions = {
headers: new HttpHeaders({
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
'Authorization': cognitoCode
})
};
let params = new HttpParams()
console.log(httpOptions.headers);
return this._http.get(url, httpOptions)
.pipe(
map((res) => {
console.log(res);
return <Issuer[]> res;
})
);
}
I then send the code as part of the headers of my GET request to the backend.
The GET then hits my backend router with these settings.
var authMiddleware = require('../middleware/AuthMiddleware.js');
router.get('/i_l', authMiddleware.Validate, i_l.get);
This will then call my authMiddleware which takes the code provided by Cognito Hosted UI and use a POST against oauth2/token to get my JWT token.
That token is then parsed used to compare to the https://cognito-idp.us-east-2.amazonaws.com/REMOVED/.well-known/jwks.json for congnito.
Once validated the request continues and I get data back from the backend.
// POST that trades the code for a token with cognito
var options = {
'method': 'POST',
'url': 'https://REMOVED.amazoncognito.com/oauth2/token',
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
},
form: {
'grant_type': 'authorization_code',
'client_id': 'CLIENTIDREMOVED',
'code': req.headers['authorization'],
'redirect_uri': 'http://localhost/group-selection'
}
};
// First request gets the JSON request of the token using the POST above
request(options, function (error, response) {
if (error) throw new Error(error);
token = JSON.parse(response.body).access_token;
//localStorage.setItem('token', token);
// request pull down status based on validitiy of token
request({
url : `https://cognito-idp.us-east-2.amazonaws.com/REMOVED/.well-known/jwks.json`,
json : true
}, function(error, response, body){
console.log('token: ' + token);
if (!error && response.statusCode === 200) {
pems = {};
var keys = body['keys'];
for(var i = 0; i < keys.length; i++) {
var key_id = keys[i].kid;
var modulus = keys[i].n;
var exponent = keys[i].e;
var key_type = keys[i].kty;
var jwk = { kty: key_type, n: modulus, e: exponent};
var pem = jwkToPem(jwk);
pems[key_id] = pem;
}
var decodedJwt = jwt.decode(token, {complete: true});
if (!decodedJwt) {
console.log("Not a valid JWT token");
res.status(401);
return res.send("Not a valid JWT token");
}
var kid = decodedJwt.header.kid;
var pem = pems[kid];
if (!pem) {
console.log('Invalid token - decodedJwt.header.kid');
res.status(401);
return res.send("Invalid token - decodedJwt.header.kid");
}
jwt.verify(token, pem, function(err, payload) {
if(err) {
console.log("Invalid Token - verify");
res.status(401);
return res.send("Invalid token - verify");
} else {
console.log("Valid Token.");
return next();
}
});
} else {
console.log("Error! Unable to download JWKs");
res.status(500);
return res.send("Error! Unable to download JWKs");
}
});
});
Quesiton -- how I set this up so that the Token I get back continues for the user?
If I understand your question properly then you are trying to validate all your apis through cognito user right?
Then you just need to do two things.
Add in header JWT token once you are getting after login. Just store into your application scope and pass everytime whenever any API is calling.
Auth.signIn(data.username, data.password)
.then(user => {
let jwkToken = user.getSignInUserSession().getAccessToken().getJwtToken();
// Store above value in singletone object or application scope.
})
.catch(err => {
//error
});
Now When API is calling pass jwkToken as header.
Then Go AWS ApiGateWay Console and add into Authorizers.

Resources