Different User Roles from Different Firebase Collections Node js - javascript

I am trying to understand how I can present two different views for each type of user that I have via Node js. I have 2 different types of users, 'restaurants' and 'customers'. Both users need to login in. However, the profile page of each type of user is a little different. Currently, both 'restaurants' and 'customers' are in different collections. I'd like to redirect the restaurant users to 'restaurant.hbs' and the customers to 'customer.hbs' with their corresponding information from the database.
Here is the Firebase functionality which enables the login of a user for either customer or restaurant owner.
firebase.auth().signInWithEmailAndPassword(email, password).then(({user}) => {
// Get the user's ID token as it is needed to exchange for a session cookie.
console.log(user)
return user.getIdToken().then(idToken => {
// Session login endpoint is queried and the session cookie is set.
// CSRF protection should be taken into account.
// ...
console.log(idToken)
return fetch("/sessionLogin", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"CSRF-Token": Cookies.get("XSRF-TOKEN"),
},
body: JSON.stringify({ idToken }),
});
});
}).then(() => {
// A page redirect would suffice as the persistence is set to NONE.
return firebase.auth().signOut();
}).then(() => {
window.location.assign('/profile');
});
Here is what I have written for the page redirect for restaurants
function renderRestaurantPage(restaurantId, res) {
getRestaurant(restaurantId).then(data => {
let ambassadorPromise = getAmbassadorInfo(restaurantId)
let activityPromise = getActivityFeed(restaurantId)
var restaurantName = data['name']
var totalScans = data['total_scans']
Promise.all([ambassadorPromise, activityPromise]).then(values => {
let ambassadorInfo = values[0]
let activityInfo = values[1]
let ambassadorList = []
let activityList = []
ambassadorInfo.forEach(element => {
ambassadorList.push(element.data())
})
activityInfo.forEach(element => {
activityList.push(element.data())
});
res.render('index', {restaurantName, totalScans, ambassadorList, activityList})
})
})
}
app.get("/profile", function (req, res) {
console.log("We are about to look at session cookie")
const sessionCookie = req.cookies.session || "";
console.log("Printing session cookie")
console.log(sessionCookie)
admin
.auth()
.verifySessionCookie(sessionCookie, true /** checkRevoked */)
.then((decodedClaims) => {
console.log(decodedClaims.user_id)
renderRestaurantPage(decodedClaims.user_id, res)
})
.catch((error) => {
console.log(error)
});
});
app.post('/sessionLogin', (req, res) => {
console.log("in session login")
console.log(req.body)
const idToken = req.body.idToken;
// Guard against CSRF attacks.
// if (csrfToken !== req.cookies.csrfToken) {
// res.status(401).send('UNAUTHORIZED REQUEST!');
// return;
// }
// Set session expiration to 5 days.
const expiresIn = 60 * 60 * 24 * 5 * 1000;
// Create the session cookie. This will also verify the ID token in the process.
// The session cookie will have the same claims as the ID token.
// To only allow session cookie setting on recent sign-in, auth_time in ID token
// can be checked to ensure user was recently signed in before creating a session cookie.
admin
.auth()
.createSessionCookie(idToken, { expiresIn })
.then(
(sessionCookie) => {
// Set cookie policy for session cookie.
const options = { maxAge: expiresIn, httpOnly: true, secure: true };
res.cookie('session', sessionCookie, options);
res.end(JSON.stringify({ status: 'success' }));
console.log("cookie created")
},
(error) => {
res.status(401).send('UNAUTHORIZED REQUEST!');
}
);
});

You should be managing the users 'type' from the users custom claims, this allows you to assign a user type as 'user' vs 'restaurant' that is accessible within your app and within your database.
For example, if the user is a restaurant, you would show buttons that allow the user to access a restaurant management panel, etc. The same would be done within Security Rules, where if the user's token.restaurant == true or token.type == "restaurant"
Custom Claims can only be edited from the admin-sdk, and you can read about them from here and how to use them within Security Rules here.

Related

Set custom expires in time expo-auth-session, for Fitbit API in react native, expo

I want to add custom expires time for fitbit implicit auth flow the default expires time is a day you can customize it I want to make it for a year. If you are using the web version you can change it by directly changing the expires_in params in the url.
As shown in this below url.
https://www.fitbit.com/oauth2/authorize?response_type=token&client_id=randomid&redirect_uri=https%3A%2F%2Fauth.expo.io%2F%40albert%2Fyourapp&scope=activity%20heartrate%20location%20nutrition%20profile%20settings%20sleep%20social%20weight%20oxygen_saturation%20respiratory_rate%20temperature&expires_in=31536000
WebBrowser.maybeCompleteAuthSession();
const useProxy = Platform.select({ web: false, default: true });
// Endpoint
const discovery = {
authorizationEndpoint: 'https://www.fitbit.com/oauth2/authorize',
tokenEndpoint: 'https://api.fitbit.com/oauth2/token',
revocationEndpoint: 'https://api.fitbit.com/oauth2/revoke',
};
const [request, response, promptAsync] = useAuthRequest(
{
responseType: ResponseType.Token,
clientId: 'randomid',
scopes: ['activity', 'profile'],
redirectUri: makeRedirectUri({
useProxy,
scheme: 'nudge://',
}),
},
discovery
);
const loginFitbit = async (token) => {
if (token) {
try {
await signInFitbit(token, dispatch);
await storeFitbitToken(token);
setLoggedIn(true);
} catch (e) {
setLoggedIn(false);
addError('Could not login Fitbit. Please try agian later.');
}
}
};
React.useEffect(() => {
if (response?.type === 'success') {
const { access_token } = response.params;
console.log("res",response)
loginFitbit(access_token);
} else {
console.log('error', response);
}
}, [response]);
React.useEffect(() => {
const fetchData = async () => {
let token;
try {
token = await getFitbitToken();
setLoggedIn(true);
} catch (e) {
setLoggedIn(false);
console.error(e);
}
dispatch({ type: 'RESTORE_FITBIT_TOKEN', token: token });
};
fetchData();
}, [dispatch])
If your application type is currently set to using the Authorization Code Grant Flow, access tokens have a default expiration of 8 hours (28800 seconds). This cannot be changed.
However, if you'd like your users to be able to select how long your application can access their data, you will need to change your application settings to the Implicit Grant Flow. This authorization flow allows users to select how long they give consent to your application (1 day, 1 week, 30 days, or 1 year).
https://community.fitbit.com/t5/Web-API-Development/Query-parameter-expires-in-not-working/td-p/3522818
If you want to add extra query params for your auth request you need to add extraParams object with your custom fields.
https://docs.expo.dev/versions/latest/sdk/auth-session/#authrequestconfig
const [request, response, promptAsync] = useAuthRequest(
{
responseType: ResponseType.Token,
clientId: "randomid",
scopes: ["activity", "profile"],
redirectUri: makeRedirectUri({
useProxy,
scheme: "nudge://",
}),
extraParams: {
expires_in: 3600, // <--- new value
},
},
discovery
);

How do I set specific roles to redirect from specific routes with Custom Claims?

I am using NodeJS, Express and plain vanilla javascript/html. Not React or anything else.
With firebase I made it to when the user registers, they will automatically be called a customer (on the server-side). As shown:
server.js
app.post('/register', (req,res) => {
let {first_name, last_name, email, uid} = req.body;
db.collection('users').doc(uid).set(req.body)
.then(data => {
res.json({
uid: req.body.uid,
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
seller: req.body.seller
})
})
admin.auth()
.setCustomUserClaims(uid, {
type: "customer",
})
.then(() => console.log('done'))
})
But now, I would like to make this route to where it will redirect if the type is a customer.
if(idToken.claim.type === 'customer') {redirect('/') }
app.get('/seller', (req,res) => {
res.sendFile(path.join(staticPath, "seller.html"));
})
So I thought, what if I were to get the Token from the user and the type as soon as they log in, and send it back to the client. This will work.
login.js
firebase.auth().currentUser.getIdTokenResult()
.then((idTokenResult) => {
fetch('/getMyClaims', {
method: 'post',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({uid: user.uid,
idToken: idTokenResult.claims.type}),
})
.then(() => res.json)
.catch(err => console.log(err));
});
and now my server.js now includes:
app.post('/getMyClaims', async(req,res) => {
let {uid,idToken} = req.body;
admin.auth()
.getUser(uid)
.then((userRecord) => console.log(userRecord))
})
and this is where I get stuck, because I am trying to find out how can I call the results of '/getMyClaims' to redirect a user, if they are a customer and are trying to access the '/seller' URL.
I did read the documents as given https://firebase.google.com/docs/auth/admin/custom-claims, but it does not really show how to re-route if claim has a specific type in the backend.
I've figured things out after hours of this!
server.js
var block;
var blockware = (req,res,next) => {
if(block == true || block == undefined){
console.log("deny access", block);
return res.sendStatus(401);
}
console.log("allow",block);
next();
}
app.post('/getMyClaims', async(req,res) => {
let {uid,idToken} = req.body;
if(idToken === 'customer'){
block = true;
} else if(idToken === 'admin'){
block = false;
} else {
block = true;
}
admin.auth()
.getUser(uid)
.then((userRecord) => console.log(userRecord))
})
app.get(['/seller', '/products', '/'], blockware, (req,res) => {
res.sendFile(path.join(staticPath, ""));
})
So now if user has a customer type claim then they are blocked from accessing seller. Otherwise, admin can access seller.
Even when user is logged out since it is automatically set to true, everyone will be blocked from it.
referenced this: express.js - single routing handler for multiple routes in a single line

Next-Auth : How the registration is handled with a email + password credential provider?

How the registration is handled with a custom credential provider ( email + password)?
Currently my [...nextauth].js looks like this:
import NextAuth from 'next-auth'
import Providers from 'next-auth/providers'
import axios from 'axios'
import jwt from "next-auth/jwt";
const YOUR_API_ENDPOINT = process.env.NEXT_PUBLIC_API_ROOT + 'auth/store'
const providers = [
Providers.Credentials({
name: 'Credentials',
authorize: async (credentials) => {
try {
const user = await axios.post(YOUR_API_ENDPOINT,
{
password: credentials.password,
username: credentials.email
},
{
headers: {
accept: '*/*',
'Content-Type': 'application/json'
}
})
console.log('ACCESS TOKEN ----> ' + JSON.stringify(user.data.access_token, null, 2));
if (user) {
return {status: 'success', data: user.data}
}
} catch (e) {
const errorMessage = e.response.data.message
// Redirecting to the login page with error messsage in the URL
throw new Error(errorMessage + '&email=' + credentials.email)
}
}
})
]
const callbacks = {
/*
|--------------------------------------------------------------------------
| Callback : JWT
|--------------------------------------------------------------------------
*/
async jwt(token, user, account, profile, isNewUser) {
if (user) {
token.accessToken = user.data.access_token
}
return token
},
/*
|--------------------------------------------------------------------------
| Callback : Session
|--------------------------------------------------------------------------
*/
async session(session, token) {
// Store Access Token to Session
session.accessToken = token.accessToken
/*
|--------------------------------------------------------------------------
| Get User Data
|--------------------------------------------------------------------------
*/
const API_URL = 'http://localhost:3000/api';
const config = {
headers: { Authorization: `Bearer ${token.accessToken}` }
};
let userData;
await axios.get(`${API_URL}/user`, config)
.then(response => {
userData = {
id: response.data.id,
uuid: response.data.uuid,
username: response.data.username,
avatar_location: response.data.avatar_location,
gender_id: response.data.gender_id,
date_of_birth: response.data.date_of_birth,
country_id: response.data.country_id,
location: response.data.location,
about_me: response.data.about_me,
interests: response.data.interests,
website: response.data.website,
timezone: response.data.timezone,
full_name: response.data.full_name,
formatted_created_at: response.data.formatted_created_at,
formatted_last_seen: response.data.formatted_last_seen,
album_count: response.data.album_count,
total_unread_message_count: response.data.total_unread_message_count,
};
// Store userData to Session
session.user = userData
}).catch((error) => {
// Error
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
// console.log(error.response.data);
// console.log(error.response.status);
// console.log(error.response.headers);
console.log('error.response: ' + error.request);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the
// browser and an instance of
// http.ClientRequest in node.js
console.log('error.request: ' + error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error', error.message);
}
console.log(error.config);
});
return session
}
}
const options = {
providers,
callbacks,
session: {
// Use JSON Web Tokens for session instead of database sessions.
// This option can be used with or without a database for users/accounts.
// Note: `jwt` is automatically set to `true` if no database is specified.
jwt: true,
// Seconds - How long until an idle session expires and is no longer valid.
maxAge: 30 * 24 * 60 * 60, // 30 days
// Seconds - Throttle how frequently to write to database to extend a session.
// Use it to limit write operations. Set to 0 to always update the database.
// Note: This option is ignored if using JSON Web Tokens
updateAge: 24 * 60 * 60, // 24 hours
},
secret: process.env.SECRET,
jwt: {
// signingKey: process.env.JWT_SIGNING_PRIVATE_KEY,
//
// // You can also specify a public key for verification if using public/private key (but private only is fine)
// verificationKey: process.env.JWT_SIGNING_PUBLIC_KEY,
//
// // If you want to use some key format other than HS512 you can specify custom options to use
// // when verifying (note: verificationOptions should include a value for maxTokenAge as well).
// // verificationOptions = {
// // maxTokenAge: `${maxAge}s`, // e.g. `${30 * 24 * 60 * 60}s` = 30 days
// // algorithms: ['HS512']
// // },
secret: process.env.JWT_SECRET,
},
pages: {
error: '/login' // Changing the error redirect page to our custom login page
}
}
export default (req, res) => NextAuth(req, res, options)
All tutorials I found online only shows the login/signIn without details on how to implement registration
Registration is the process of registering the user, saving new users' credentials into the database. It is independent of next-auth. You create a form, submit the form and save the form data properly into the database.
next-auth takes over when you are logged in, in other words, you are authenticated meaning that you are already a registered, genuine user. Once you pass the security checks and successfully logged in, next-auth creates a session for the user.
You can view the set up demo for v4: next-auth 4 session returns null, next.js
next-auth only supports Sign In, Sign Up and Sign Out. When a user creates an account for the first time, It registers them automatically without the need for a new set of registration process.

firebase authentication: signInWithCustomToken and createSessionCookie - error auth/invalid-id

I am trying to implement a login mechanism using Firebase custom token and session cookies, for sure I am doing something wrong but I cannot figure it out.
I will put my code and then explain how I am using it to test it.
Frontend code
const functions = firebase.functions();
const auth = firebase.auth();
auth.setPersistence(firebase.auth.Auth.Persistence.NONE);
auth.onAuthStateChanged((user) => {
if (user) {
user.getIdToken()
.then((idToken) => {
console.log(idToken);
});
}
});
function testCustomLogin(token) {
firebase.auth().signInWithCustomToken(token)
.then((signInToken) => {
console.log("Login OK");
console.log("signInToken", signInToken);
signInToken.user.getIdToken()
.then((usertoken) => {
let data = {
token: usertoken
};
fetch("/logincookiesession", {
method: "POST",
body: JSON.stringify(data)
}).then((res) => {
console.log("Request complete! response:", res);
console.log("firebase signout");
auth.signOut()
.then(()=> {
console.log("redirecting ....");
window.location.assign('/');
return;
})
.catch(() => {
console.log("error during firebase.signOut");
});
});
});
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorCode, errorMessage);
});
}
Backend code
app.post('/logincookiesession', (req, res) => {
let token = req.body.token;
// Set session expiration to 5 days.
const expiresIn = 60 * 60 * 24 * 5 * 1000;
// Create the session cookie. This will also verify the ID token in the process.
// The session cookie will have the same claims as the ID token.
// To only allow session cookie setting on recent sign-in, auth_time in ID token
// can be checked to ensure user was recently signed in before creating a session cookie.
admin.auth().createSessionCookie(token, {expiresIn})
.then((sessionCookie) => {
// Set cookie policy for session cookie.
const options = {maxAge: expiresIn, httpOnly: true, secure: true};
res.cookie('session', sessionCookie, options);
res.end(JSON.stringify({status: 'success'}));
})
.catch((error) => {
res.status(401).send('UNAUTHORIZED REQUEST!' + JSON.stringify(error));
});
});
app.get('/logintest', (req, res) => {
let userId = 'jcm#email.com';
let additionalClaims = {
premiumAccount: true
};
admin.auth().createCustomToken(userId, additionalClaims)
.then(function(customToken) {
res.send(customToken);
})
.catch(function(error) {
console.log('Error creating custom token:', error);
});
});
so basically what I do is
execute firebase emulators:start
manually execute this on my browser http://localhost:5000/logintest , this gives me a token printed in the browser
Then in another page, where I have the login form, I open the javascript console of the browser and I execute my javascript function testCustomLogin and I pass as a parameter the token from step 2.
in the network traffic I see that the call to /logincookiesession return this:
UNAUTHORIZED REQUEST!{"code":"auth/invalid-id-token","message":"The provided ID token is not a valid Firebase ID token."}
I am totally lost.
I can see in the firebase console, in the Authentication section that user jcm#email.com is created and signed-in, but I cannot create the session-cookie.
Please,I need some advice here.
The route for creating the cookie session had an error.
It should start like this.
app.post('/logincookiesession', (req, res) => {
let params = JSON.parse(req.body);
let token = params.token;
And the code I used was from a manual, OMG. I hope this helps someone too.

Should I federate cognito user pools along with other social idps, or have social sign in via the userpool itself

I am building a social chat application and initially had a cognito user pool that was federated alongside Google/Facebook. I was storing user data based on the user-sub for cognito users and the identity id for google/facebook. Then in my lambda-gql resolvers, I would authenticate via the AWS-sdk:
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: process.env.IDENTITY_POOL_ID,
Logins: {
[`cognito-idp.us-east-1.amazonaws.com/${
process.env.COGNITO_USERPOOL_ID
}`]: Authorization,
},
});
Because all users are equal and I don't need fine grained controls over access to aws-resources, it seems like it would be preferable to instead have all authentication handled via the userpool and to get rid of the identity pool entirely.
For example, if I wanted to ban a user's account, it seems that I would first have to lookup the provider based on identity-id and then perform a different action based on the provider.
So my questions are:
1. Is this even possible?
- https://github.com/aws-amplify/amplify-js/issues/565
-https://www.reddit.com/r/aws/comments/92ye5s/is_it_possible_to_add_googlefacebook_user_to/
There seems to be a lot of confusion, and the aws docs are less clear than usual (which isn't much imo).
https://docs.aws.amazon.com/cognito/latest/developerguide/authentication.html
It seems that there is clearly a method to do this. I followed the above guide and am getting errors with the hosted UI endpoint, but that's probably on me (https://forums.aws.amazon.com/thread.jspa?threadID=262736). However, I do not want the hosted UI endpoint, I would like cognito users to sign in through my custom form and then social sign in users to click a "continue with fb" button and have that automatically populate my userpool.
Then replace the code above with the following to validate all users:
const validate = token => new Promise(async (resolve) => {
const {
data: { keys },
} = await axios(url);
const { sub, ...res } = decode(token, { complete: true });
const { kid } = decode(token, { header: true });
const jwk = R.find(R.propEq('kid', kid))(keys);
const pem = jwkToPem(jwk);
const response = res && res['cognito:username']
? { sub, user: res['cognito:username'] }
: { sub };
try {
await verify(token, pem);
resolve(response);
} catch (error) {
resolve(false);
}
});
If it is possible, what is the correct mechanism that would replace the following:
Auth.federatedSignIn('facebook', { token: accessToken, expires_at }, user)
.then(credentials => Auth.currentAuthenticatedUser())
.then((user) => {
onStateChange('signedIn', {});
})
.catch((e) => {
console.log(e);
});
From what I have seen, there does not appear to be a method with Amplify to accomplish this. Is there some way to do this with the aws-sdk? What about mapping the callback from the facebook api to create a cognito user client-side? It seems like that could get quite messy.
If there is no mechanism to accomplish the above, should I federate cognito users with social sign ins?
And then what should I use to identify users in my database? Am currently using username and sub for cognito and identity id for federated users. Extracting the sub from the Auth token server-side and then on the client:
Auth.currentSession()
.then((data) => {
const userSub = R.path(['accessToken', 'payload', 'sub'], data);
resolve(userSub);
})
.catch(async () => {
try {
const result = await Auth.currentCredentials();
const credentials = Auth.essentialCredentials(result);
resolve(removeRegionFromId(credentials.identityId));
} catch (error) {
resolve(false);
}
});
If anyone could provide the detailed authoritative answer I have yet to find concerning the use of cognito user pools in place of federating that would be great. Otherwise a general outline of the correct approach to take would be much appreciated.
Here's what I ended up doing for anyone in a similar position, this isn't comprehensive:
Create a userpool, do not specify client secret or any required attributes that could conflict with whats returned from Facebook/Google.
Under domains, in the Cognito sidebar, add what ever you want yours to be.
The add your identity provided from Cognito, for FB you want them to be comma seperated like so: openid, phone, email, profile, aws.cognito.signin.user.admin
Enable FB from app client settings, select implicit grant. I belive, but am not positive, openid is required for generating a access key and signin.user.admin for getting a RS256 token to verify with the public key.
The from FB dev console, https://yourdomain.auth.us-east-1.amazoncognito.com/oauth2/idpresponse, as valid oauth redirects.
Then, still on FB, go to settings (general not app specific), and enter https://yourdomain.auth.us-east-1.amazoncognito.com/oauth2/idpresponse
https://yourdomain.auth.us-east-1.amazoncognito.com/oauth2/idpresponse for your site url.
Then for the login in button you can add the following code,
const authenticate = callbackFn => () => {
const domain = process.env.COGNITO_APP_DOMAIN;
const clientId = process.env.COGNITO_USERPOOL_CLIENT_ID;
const type = 'token';
const scope = 'openid phone email profile aws.cognito.signin.user.admin';
const verification = generateVerification();
const provider = 'Facebook';
const callback = `${window.location.protocol}//${
window.location.host
}/callback`;
const url = `${domain}/authorize?identity_provider=${provider}&response_type=${type}&client_id=${clientId}&redirect_uri=${callback}&state=${verification}&scope=${scope}`;
window.open(url, '_self');
};
Then on your redirect page:
useEffect(() => {
// eslint-disable-next-line no-undef
if (window.location.href.includes('#access_token')) {
const callback = () => history.push('/');
newAuthUser(callback);
}
}, []);
/* eslint-disable no-undef */
import { CognitoAuth } from 'amazon-cognito-auth-js';
import setToast from './setToast';
export default (callback) => {
const AppWebDomain = process.env.COGNITO_APP_DOMAIN;
// https://yourdomainhere.auth.us-east-1.amazoncognito.com'
const TokenScopesArray = [
'phone',
'email',
'profile',
'openid',
'aws.cognito.signin.user.admin',
];
const redirect = 'http://localhost:8080/auth';
const authData = {
ClientId: process.env.COGNITO_USERPOOL_CLIENT_ID,
AppWebDomain,
TokenScopesArray,
RedirectUriSignIn: redirect,
RedirectUriSignOut: redirect,
IdentityProvider: 'Facebook',
UserPoolId: process.env.COGNITO_USERPOOL_ID,
AdvancedSecurityDataCollectionFlag: true,
};
const auth = new CognitoAuth(authData);
auth.userhandler = {
onSuccess() {
setToast('logged-in');
callback();
},
onFailure(error) {
setToast('auth-error', error);
callback();
},
};
const curUrl = window.location.href;
auth.parseCognitoWebResponse(curUrl);
};
You can then use Auth.currentSession() to get user attributes from the client.
Then server-side you can validate all user like so:
const decode = require('jwt-decode');
const jwt = require('jsonwebtoken');
const jwkToPem = require('jwk-to-pem');
const axios = require('axios');
const R = require('ramda');
const logger = require('./logger');
const url = `https://cognito-idp.us-east-1.amazonaws.com/${
process.env.COGNITO_USERPOOL_ID
}/.well-known/jwks.json`;
const verify = (token, n) => new Promise((resolve, reject) => {
jwt.verify(token, n, { algorithms: ['RS256'] }, (err, decoded) => {
if (err) {
reject(new Error('invalid_token', err));
} else {
resolve(decoded);
}
});
});
const validate = token => new Promise(async (resolve) => {
const {
data: { keys },
} = await axios(url);
const { sub, ...res } = decode(token, { complete: true });
const { kid } = decode(token, { header: true });
const jwk = R.find(R.propEq('kid', kid))(keys);
const pem = jwkToPem(jwk);
const response = res && res['cognito:username']
? { sub, user: res['cognito:username'] }
: { sub };
try {
await verify(token, pem);
resolve(response);
} catch (error) {
logger['on-failure']('CHECK_CREDENTIALS', error);
resolve(false);
}
});
const checkCredentialsCognito = Authorization => validate(Authorization);

Categories