Skip to content

Commit

Permalink
feat: get userinfo in ssr
Browse files Browse the repository at this point in the history
Signed-off-by: Vaibhav Upreti <[email protected]>
  • Loading branch information
VaibhavUpreti committed Dec 31, 2024
1 parent cb132b6 commit 6e7b109
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 22 deletions.
19 changes: 13 additions & 6 deletions demo/ssr-express-demo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,18 +218,25 @@ app.get('/refresh-token', async (req, res) => {
}
});


app.get("/user", async (req, res) => {
try {
const cookies = req.cookies;
const accessToken = req.cookies.access_token;

if (!accessToken) {
return res.status(401).json({ message: "Access token not found. Please authenticate again." });
}

// Fetch user information using the access token
const userData = await oauthClient.getUserInfo(accessToken);

res.status(200).json({
message: "Cookies successfully retrieved",
cookies: cookies,
message: "User information retrieved successfully.",
user: userData, // Assuming `getUserInfo` already returns a parsed object
});
} catch (error) {
console.error("Error fetching cookies:", error);
console.error("Error fetching user information:", error);
res.status(500).json({
message: "An error occurred while retrieving cookies",
message: "An error occurred while retrieving user information.",
error: error.message,
});
}
Expand Down
5 changes: 5 additions & 0 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getEnvironment } from './utils/getEnvironment.js';
import { startAuthFlow as browserStartAuthFlow, handleCallback as browserHandleCallback, exchangeAuthCodeForToken as browserExchangeAuthCodeForToken } from './grants/pkce-grant.js';
import { startAuthFlow as serverStartAuthFlow, handleCallback as serverHandleCallback, exchangeAuthCodeForToken as serverExchangeAuthCodeForToken } from './grants/authorization-code.js';
import { refreshAccessToken } from './grants/refresh-token.js';
import { fetchUserInfo } from './utils/getUserInfo.js';

class OAuthClient {
constructor(config, environment = getEnvironment()) {
Expand Down Expand Up @@ -49,6 +50,10 @@ class OAuthClient {
throw new Error(`Unknown environment: ${this.environment}`);
}
}

async getUserInfo(accessToken) {
return fetchUserInfo(accessToken);
}
}

export { OAuthClient };
3 changes: 1 addition & 2 deletions lib/grants/authorization-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ export async function handleCallback(config) {
return null;
}
const data = response.json();
return null;
// return exchangeAuthCodeForToken(config);
return data;
}

export async function exchangeAuthCodeForToken(config, code) {
Expand Down
2 changes: 2 additions & 0 deletions lib/grants/pkce-grant.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// For client and native apps

import CryptoUtils from '../utils/cryptoUtils.js';
import { fetchUserInfo } from '../utils/getUserInfo.js'
/**
Expand Down
2 changes: 0 additions & 2 deletions lib/grants/refresh-token.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export async function refreshAccessToken(config, refreshToken) {
refresh_token: refreshToken,
});

// Make the POST request to refresh the token
const response = await fetch(config.token_url, {
method: "POST",
headers: {
Expand All @@ -26,7 +25,6 @@ export async function refreshAccessToken(config, refreshToken) {
return null;
}

// Parse the response to get the tokens
const data = await response.json();

// Check if we are in the browser and then store the tokens
Expand Down
13 changes: 2 additions & 11 deletions lib/utils/cryptoUtils.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
// Check if we're running in a browser or Node.js
const isBrowser = typeof window !== 'undefined';

class CryptoUtils {
static generateRandomString(length = 28) {
if (isBrowser) {
// Browser: Use the Web Crypto API
const array = new Uint32Array(length);
window.crypto.getRandomValues(array);
return Array.from(array, dec => ('0' + dec.toString(16)).substr(-2)).join('');
} else {
// Node.js: Use the built-in crypto (only available in Node.js)
const array = new Uint8Array(length);
require('crypto').randomFillSync(array);
return Array.from(array, byte => ('0' + byte.toString(16)).substr(-2)).join('');
}
}

// Base64 URL encode a buffer (works for both Node.js and browser)
static base64urlencode(buffer) {
let base64String;
if (isBrowser) {
Expand All @@ -31,30 +27,25 @@ class CryptoUtils {
.replace(/=+$/, '');
}

// SHA-256 hashing function (works for both Node.js and browser)
static async sha256(plain) {
if (isBrowser) {
// Browser: Use the Web Crypto API
const encoder = new TextEncoder();
const data = encoder.encode(plain);
const hashed = await window.crypto.subtle.digest('SHA-256', data);
return new Uint8Array(hashed); // Convert ArrayBuffer to Uint8Array
return new Uint8Array(hashed);
} else {
// Node.js: Use the built-in crypto (only available in Node.js)
const crypto = require('crypto');
const hash = crypto.createHash('sha256');
hash.update(plain);
return hash.digest(); // Return a buffer
return hash.digest();
}
}

// PKCE challenge generation from a verifier
static async pkceChallengeFromVerifier(verifier) {
const hashed = await this.sha256(verifier);
return this.base64urlencode(hashed);
}

// Parse a query string into an object
static parseQueryString(query) {
const params = new URLSearchParams(query);
const result = {};
Expand Down
4 changes: 3 additions & 1 deletion lib/utils/getUserInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @param {string} accessToken - Access token.
* @returns {Object|null} - User info if successful, null otherwise.
*/
export async function fetchUserInfo(config, accessToken) {
async function fetchUserInfo(config, accessToken) {
const baseUrl = new URL(config.token_url).origin;
const userInfoUrl = `${baseUrl}/userinfo`;

Expand All @@ -28,3 +28,5 @@ export async function fetchUserInfo(config, accessToken) {
return null;
}
}

export {fetchUserInfo};

0 comments on commit 6e7b109

Please sign in to comment.