Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-oauth2-code-pkce

Package Overview
Dependencies
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-oauth2-code-pkce - npm Package Compare versions

Comparing version 1.3.0-beta.0 to 1.3.0

2

dist/AuthContext.d.ts
import React from 'react';
import { IAuthContext, IAuthProvider } from "./Types";
import { IAuthContext, IAuthProvider } from './Types';
export declare const AuthContext: React.Context<IAuthContext>;
export declare const AuthProvider: ({ authConfig, children }: IAuthProvider) => JSX.Element;
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {

@@ -41,68 +30,95 @@ if (k2 === undefined) k2 = k;

exports.AuthProvider = exports.AuthContext = void 0;
var react_1 = __importStar(require("react"));
var authentication_1 = require("./authentication");
var Hooks_1 = __importDefault(require("./Hooks"));
var validateAuthConfig_1 = require("./validateAuthConfig");
exports.AuthContext = (0, react_1.createContext)({ token: '', logOut: function () { return null; }, error: null });
var AuthProvider = function (_a) {
var authConfig = _a.authConfig, children = _a.children;
var _b = (0, Hooks_1.default)('ROCP_refreshToken', null), refreshToken = _b[0], setRefreshToken = _b[1];
var _c = (0, Hooks_1.default)('ROCP_token', null), token = _c[0], setToken = _c[1];
var _d = (0, Hooks_1.default)('ROCP_tokenExpire', null), tokenExpire = _d[0], setTokenExpire = _d[1];
var _e = (0, Hooks_1.default)('ROCP_idToken', null), idToken = _e[0], setIdToken = _e[1];
var _f = (0, Hooks_1.default)('ROCP_loginInProgress', false), loginInProgress = _f[0], setLoginInProgress = _f[1];
var _g = (0, react_1.useState)(null), tokenData = _g[0], setTokenData = _g[1];
var _h = (0, react_1.useState)(null), error = _h[0], setError = _h[1];
var interval;
const react_1 = __importStar(require("react")); // eslint-disable-line
const authentication_1 = require("./authentication");
const Hooks_1 = __importDefault(require("./Hooks"));
const validateAuthConfig_1 = require("./validateAuthConfig");
const FALLBACK_EXPIRE_TIME = 600; // 10minutes
exports.AuthContext = (0, react_1.createContext)({
token: '',
logOut: () => null,
error: null,
});
const AuthProvider = ({ authConfig, children }) => {
const [refreshToken, setRefreshToken] = (0, Hooks_1.default)('ROCP_refreshToken', undefined);
const [refreshTokenExpire, setRefreshTokenExpire] = (0, Hooks_1.default)('ROCP_refreshTokenExpire', (0, authentication_1.epochAtSecondsFromNow)(2 * FALLBACK_EXPIRE_TIME));
const [token, setToken] = (0, Hooks_1.default)('ROCP_token', '');
const [tokenExpire, setTokenExpire] = (0, Hooks_1.default)('ROCP_tokenExpire', (0, authentication_1.epochAtSecondsFromNow)(FALLBACK_EXPIRE_TIME));
const [idToken, setIdToken] = (0, Hooks_1.default)('ROCP_idToken', undefined);
const [loginInProgress, setLoginInProgress] = (0, Hooks_1.default)('ROCP_loginInProgress', false);
const [tokenData, setTokenData] = (0, react_1.useState)();
const [error, setError] = (0, react_1.useState)(null);
let interval;
// Set default values and override from passed config
var _j = authConfig.decodeToken, decodeToken = _j === void 0 ? true : _j, _k = authConfig.scope, scope = _k === void 0 ? "" : _k, _l = authConfig.preLogin, preLogin = _l === void 0 ? function () { return null; } : _l, _m = authConfig.postLogin, postLogin = _m === void 0 ? function () { return null; } : _m;
var config = __assign({ decodeToken: decodeToken, scope: scope, preLogin: preLogin, postLogin: postLogin }, authConfig);
const { decodeToken = true, scope = '', preLogin = () => null, postLogin = () => null } = authConfig;
const config = {
decodeToken: decodeToken,
scope: scope,
preLogin: preLogin,
postLogin: postLogin,
...authConfig,
};
(0, validateAuthConfig_1.validateAuthConfig)(config);
function logOut() {
setRefreshToken(null);
setToken(null);
setIdToken(null);
setTokenData(null);
setRefreshToken(undefined);
setToken('');
setTokenExpire((0, authentication_1.epochAtSecondsFromNow)(FALLBACK_EXPIRE_TIME));
setRefreshTokenExpire((0, authentication_1.epochAtSecondsFromNow)(FALLBACK_EXPIRE_TIME));
setIdToken(undefined);
setTokenData(undefined);
setLoginInProgress(false);
}
function handleTokenResponse(response) {
setRefreshToken(response === null || response === void 0 ? void 0 : response.refresh_token);
setToken(response.access_token);
setTokenExpire((0, authentication_1.timeOfExpire)(response.expires_in));
setIdToken(response === null || response === void 0 ? void 0 : response.id_token);
setRefreshToken(response.refresh_token);
setTokenExpire((0, authentication_1.epochAtSecondsFromNow)(response.expires_in || FALLBACK_EXPIRE_TIME));
// If there is no refresh_token_expire, use access_token_expire + 10min.
// If no access_token_expire, assume double the fallback expire time
let refreshTokenExpire = response.refresh_token_expires_in || 2 * FALLBACK_EXPIRE_TIME;
if (!response.refresh_token_expires_in && response.expires_in) {
refreshTokenExpire = response.expires_in + FALLBACK_EXPIRE_TIME;
}
setRefreshTokenExpire((0, authentication_1.epochAtSecondsFromNow)(refreshTokenExpire));
setIdToken(response.id_token);
setLoginInProgress(false);
if (config.decodeToken)
setTokenData((0, authentication_1.decodeJWT)(response.access_token));
try {
if (config.decodeToken)
setTokenData((0, authentication_1.decodeJWT)(response.access_token));
}
catch (e) {
setError(e.message);
}
}
function refreshAccessToken() {
if (refreshToken) {
if ((0, authentication_1.tokenExpired)(tokenExpire)) { // The client has an expired token. Will try to get a new one with the refreshToken
(0, authentication_1.fetchWithRefreshToken)({ config: config, refreshToken: refreshToken })
.then(function (result) { return handleTokenResponse(result); })
.catch(function (error) {
if (token && (0, authentication_1.epochTimeIsPast)(tokenExpire)) {
if (refreshToken && !(0, authentication_1.epochTimeIsPast)(refreshTokenExpire)) {
(0, authentication_1.fetchWithRefreshToken)({ config, refreshToken })
.then((result) => handleTokenResponse(result))
.catch((error) => {
setError(error);
if ((0, authentication_1.errorMessageForExpiredRefreshToken)(error)) {
logOut();
(0, authentication_1.login)(config);
(0, authentication_1.logIn)(config);
}
});
}
else {
// The refresh token has expired. Need to log in from scratch.
setLoginInProgress(true);
(0, authentication_1.logIn)(config);
}
}
else { // No refresh_token
console.error("Tried to refresh token without a refresh token.");
setError('Bad authorization state. Refreshing the page might solve the issue.');
}
}
// Register the 'check for soon expiring access token' interval (Every minute)
(0, react_1.useEffect)(function () {
interval = setInterval(function () { return refreshAccessToken(); }, 60000);
return function () { return clearInterval(interval); };
(0, react_1.useEffect)(() => {
interval = setInterval(() => refreshAccessToken(), 60000); // eslint-disable-line
return () => clearInterval(interval);
}, [token]); // This token dependency removes the old, and registers a new Interval when a new token is fetched.
// Runs once on page load
(0, react_1.useEffect)(function () {
if (loginInProgress) { // The client has been redirected back from the Auth endpoint with an auth code
var urlParams = new URLSearchParams(window.location.search);
(0, react_1.useEffect)(() => {
if (loginInProgress) {
// The client has been redirected back from the Auth endpoint with an auth code
const urlParams = new URLSearchParams(window.location.search);
if (!urlParams.get('code')) {
// This should not happen. There should be a 'code' parameter in the url by now..."
var error_description = urlParams.get('error_description') || 'Bad authorization state. Refreshing the page might solve the issue.';
const error_description = urlParams.get('error_description') || 'Bad authorization state. Refreshing the page might solve the issue.';
console.error(error_description);

@@ -112,11 +128,13 @@ setError(error_description);

}
else { // Request token from auth server with the auth code
else {
// Request token from auth server with the auth code
(0, authentication_1.fetchTokens)(config)
.then(function (tokens) {
.then((tokens) => {
handleTokenResponse(tokens);
history.replaceState(null, "", location.pathname); // Clear ugly url params
window.history.replaceState(null, '', window.location.pathname); // Clear ugly url params
// Call any postLogin function in authConfig
config.postLogin();
if (config?.postLogin)
config.postLogin();
})
.catch(function (error) {
.catch((error) => {
setError(error);

@@ -126,14 +144,21 @@ });

}
else if (!token) { // First page visit
else if (!token) {
// First page visit
setLoginInProgress(true);
(0, authentication_1.login)(config);
(0, authentication_1.logIn)(config);
}
else {
if (decodeToken)
setTokenData((0, authentication_1.decodeJWT)(token));
if (decodeToken) {
try {
setTokenData((0, authentication_1.decodeJWT)(token));
}
catch (e) {
setError(e.message);
}
}
refreshAccessToken(); // Check if token should be updated
}
}, []);
return (react_1.default.createElement(exports.AuthContext.Provider, { value: { tokenData: tokenData, token: token, idToken: idToken, logOut: logOut, error: error } }, children));
}, []); // eslint-disable-line
return react_1.default.createElement(exports.AuthContext.Provider, { value: { tokenData, token, idToken, logOut, error } }, children);
};
exports.AuthProvider = AuthProvider;

@@ -1,14 +0,14 @@

import { TInternalConfig, TTokenData } from "./Types";
import { TInternalConfig, TTokenData, TTokenResponse } from './Types';
export declare const EXPIRED_REFRESH_TOKEN_ERROR_CODES: string[];
export declare function login(config: TInternalConfig): Promise<void>;
export declare const fetchTokens: (config: TInternalConfig) => Promise<any>;
export declare function logIn(config: TInternalConfig): Promise<void>;
export declare const fetchTokens: (config: TInternalConfig) => Promise<TTokenResponse>;
export declare const fetchWithRefreshToken: (props: {
config: TInternalConfig;
refreshToken: string;
}) => Promise<any>;
}) => Promise<TTokenResponse>;
/**
* Decodes the base64 encoded JWT. Returns a TToken.
*/
export declare const decodeJWT: (token: string) => TTokenData | null;
export declare const timeOfExpire: (validTimeDelta: number) => number;
export declare const decodeJWT: (token: string) => TTokenData;
export declare const epochAtSecondsFromNow: (secondsFromNow: number) => number;
/**

@@ -18,3 +18,3 @@ * Check if the Access Token has expired.

*/
export declare function tokenExpired(tokenExpire: number): Boolean;
export declare function epochTimeIsPast(timestamp: number): boolean;
export declare const errorMessageForExpiredRefreshToken: (errorMessage: string) => boolean;
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorMessageForExpiredRefreshToken = exports.tokenExpired = exports.timeOfExpire = exports.decodeJWT = exports.fetchWithRefreshToken = exports.fetchTokens = exports.login = exports.EXPIRED_REFRESH_TOKEN_ERROR_CODES = void 0;
var pkceUtils_1 = require("./pkceUtils");
var codeVerifierStorageKey = "PKCE_code_verifier";
exports.errorMessageForExpiredRefreshToken = exports.epochTimeIsPast = exports.epochAtSecondsFromNow = exports.decodeJWT = exports.fetchWithRefreshToken = exports.fetchTokens = exports.logIn = exports.EXPIRED_REFRESH_TOKEN_ERROR_CODES = void 0;
const pkceUtils_1 = require("./pkceUtils");
const codeVerifierStorageKey = 'PKCE_code_verifier';
// [ AzureAD,]
exports.EXPIRED_REFRESH_TOKEN_ERROR_CODES = ["AADSTS700084"];
function login(config) {
return __awaiter(this, void 0, void 0, function () {
var codeVerifier;
return __generator(this, function (_a) {
codeVerifier = (0, pkceUtils_1.generateRandomString)(40);
localStorage.setItem(codeVerifierStorageKey, codeVerifier);
// Hash and Base64URL encode the code_verifier, used as the 'code_challenge'
(0, pkceUtils_1.generateCodeChallenge)(codeVerifier).then(function (codeChallenge) {
// Set query parameters and redirect user to OAuth2 authentication endpoint
var params = new URLSearchParams({
response_type: 'code',
client_id: config.clientId,
scope: config.scope,
redirect_uri: config.redirectUri,
code_challenge: codeChallenge,
code_challenge_method: 'S256',
});
// Call any preLogin function in authConfig
config.preLogin();
location.replace("".concat(config.authorizationEndpoint, "?").concat(params.toString()));
});
return [2 /*return*/];
exports.EXPIRED_REFRESH_TOKEN_ERROR_CODES = ['AADSTS700084'];
async function logIn(config) {
// Create and store a random string in localStorage, used as the 'code_verifier'
const codeVerifier = (0, pkceUtils_1.generateRandomString)(40);
localStorage.setItem(codeVerifierStorageKey, codeVerifier);
// Hash and Base64URL encode the code_verifier, used as the 'code_challenge'
(0, pkceUtils_1.generateCodeChallenge)(codeVerifier).then((codeChallenge) => {
// Set query parameters and redirect user to OAuth2 authentication endpoint
const params = new URLSearchParams({
response_type: 'code',
client_id: config.clientId,
scope: config.scope,
redirect_uri: config.redirectUri,
code_challenge: codeChallenge,
code_challenge_method: 'S256',
});
// Call any preLogin function in authConfig
if (config?.preLogin)
config.preLogin();
window.location.replace(`${config.authorizationEndpoint}?${params.toString()}`);
});
}
exports.login = login;
exports.logIn = logIn;
// This is called a "type predicate". Which allow use to know which kind of response we got, in a type safe way.
function isTokenResponse(body) {
return body.access_token !== undefined;
}
function postWithFormData(tokenEndpoint, formData) {

@@ -74,17 +38,19 @@ return fetch(tokenEndpoint, {

body: formData,
})
.then(function (response) { return response.json()
.then(function (body) {
}).then((response) => {
if (!response.ok) {
console.error(body.error_description);
throw body.error_description;
console.error(response);
throw Error(response.statusText);
}
return body;
}); })
.catch(function (error) {
console.error(error);
throw (error === null || error === void 0 ? void 0 : error.message) || error;
return response.json().then((body) => {
if (isTokenResponse(body)) {
return body;
}
else {
console.error(body);
throw Error(body.error_description);
}
});
});
}
var fetchTokens = function (config) {
const fetchTokens = (config) => {
/*

@@ -95,12 +61,12 @@ The browser has been redirected from the authentication endpoint with

*/
var urlParams = new URLSearchParams(window.location.search);
var authCode = urlParams.get('code');
var codeVerifier = window.localStorage.getItem(codeVerifierStorageKey);
const urlParams = new URLSearchParams(window.location.search);
const authCode = urlParams.get('code');
const codeVerifier = window.localStorage.getItem(codeVerifierStorageKey);
if (!authCode) {
throw "Parameter 'code' not found in URL. \nHas authentication taken place?";
throw Error("Parameter 'code' not found in URL. \nHas authentication taken place?");
}
if (!codeVerifier) {
throw "Can't get tokens without the CodeVerifier. \nHas authentication taken place?";
throw Error("Can't get tokens without the CodeVerifier. \nHas authentication taken place?");
}
var formData = new FormData();
const formData = new FormData();
formData.append('grant_type', 'authorization_code');

@@ -115,5 +81,5 @@ formData.append('code', authCode);

exports.fetchTokens = fetchTokens;
var fetchWithRefreshToken = function (props) {
var config = props.config, refreshToken = props.refreshToken;
var formData = new FormData();
const fetchWithRefreshToken = (props) => {
const { config, refreshToken } = props;
const formData = new FormData();
formData.append('grant_type', 'refresh_token');

@@ -130,7 +96,7 @@ formData.append('refresh_token', refreshToken);

*/
var decodeJWT = function (token) {
const decodeJWT = (token) => {
try {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var jsonPayload = decodeURIComponent(atob(base64)
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(atob(base64)
.split('')

@@ -145,5 +111,4 @@ .map(function (c) {

console.error(e);
console.error("Failed to decode the access token.\n\tIs it a proper Java Web Token?\n\t" +
throw Error('Failed to decode the access token.\n\tIs it a proper Java Web Token?\n\t' +
"You can disable JWT decoding by setting the 'decodeToken' value to 'false' the configuration.");
return null;
}

@@ -153,4 +118,4 @@ };

// Returns epoch time (in seconds) for when the token will expire
var timeOfExpire = function (validTimeDelta) { return Math.round(Date.now() / 1000 + validTimeDelta); };
exports.timeOfExpire = timeOfExpire;
const epochAtSecondsFromNow = (secondsFromNow) => Math.round(Date.now() / 1000 + secondsFromNow);
exports.epochAtSecondsFromNow = epochAtSecondsFromNow;
/**

@@ -160,12 +125,11 @@ * Check if the Access Token has expired.

*/
function tokenExpired(tokenExpire) {
var now = Math.round(Date.now()) / 1000;
var bufferTimeInSeconds = 5 * 60; // minutes * seconds
var nowWithBuffer = now + bufferTimeInSeconds;
return nowWithBuffer >= tokenExpire;
function epochTimeIsPast(timestamp) {
const now = Math.round(Date.now()) / 1000;
const nowWithBuffer = now + 120;
return nowWithBuffer >= timestamp;
}
exports.tokenExpired = tokenExpired;
var errorMessageForExpiredRefreshToken = function (errorMessage) {
var expired = false;
exports.EXPIRED_REFRESH_TOKEN_ERROR_CODES.forEach(function (errorCode) {
exports.epochTimeIsPast = epochTimeIsPast;
const errorMessageForExpiredRefreshToken = (errorMessage) => {
let expired = false;
exports.EXPIRED_REFRESH_TOKEN_ERROR_CODES.forEach((errorCode) => {
if (errorMessage.includes(errorCode)) {

@@ -172,0 +136,0 @@ expired = true;

@@ -1,2 +0,2 @@

declare function useLocalStorage<T>(key: string, initialValue: T): [any, Function];
declare function useLocalStorage<T>(key: string, initialValue: T): [T, (v: T) => void];
export default useLocalStorage;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = require("react");
const react_1 = require("react");
function useLocalStorage(key, initialValue) {
var _a = (0, react_1.useState)(function () {
const [storedValue, setStoredValue] = (0, react_1.useState)(() => {
const item = localStorage.getItem(key);
try {
var item = localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;

@@ -13,6 +13,6 @@ }

}
}), storedValue = _a[0], setStoredValue = _a[1];
var setValue = function (value) {
});
const setValue = (value) => {
try {
var valueToStore = value instanceof Function ? value(storedValue) : value;
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);

@@ -22,3 +22,3 @@ localStorage.setItem(key, JSON.stringify(valueToStore));

catch (error) {
console.log(error);
console.log(`Failed to store value '${value}' for key '${key}'`);
}

@@ -25,0 +25,0 @@ };

@@ -1,2 +0,2 @@

export { AuthProvider, AuthContext } from "./AuthContext";
export type { TAuthConfig } from "./Types";
export { AuthProvider, AuthContext } from './AuthContext';
export type { TAuthConfig, IAuthProvider, IAuthContext } from './Types';
export declare function getRandomInteger(range: number): number;
export declare function generateRandomString(length: number): string;
/**
* PKCE Code Challenge = base64url(hash(codeVerifier))
* PKCE Code Challenge = base64url(hash(codeVerifier))
*/
export declare function generateCodeChallenge(codeVerifier: string): Promise<string>;
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateCodeChallenge = exports.generateRandomString = exports.getRandomInteger = void 0;
function getRandomInteger(range) {
var max_range = 256; // Highest possible number in Uint8
const max_range = 256; // Highest possible number in Uint8
// Create byte array and fill with 1 random number
var byteArray = new Uint8Array(1);
const byteArray = new Uint8Array(1);
window.crypto.getRandomValues(byteArray); // This is the new, and safer API than Math.Random()

@@ -52,5 +16,5 @@ // If the generated number is out of range, try again

function generateRandomString(length) {
var text = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < length; i++) {
let text = '';
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < length; i++) {
text += possible.charAt(getRandomInteger(possible.length - 1));

@@ -62,31 +26,15 @@ }

/**
* PKCE Code Challenge = base64url(hash(codeVerifier))
* PKCE Code Challenge = base64url(hash(codeVerifier))
*/
function generateCodeChallenge(codeVerifier) {
return __awaiter(this, void 0, void 0, function () {
var encoder, bytes, hash, hashString, base64, base64url;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
encoder = new TextEncoder();
bytes = encoder.encode(codeVerifier) // Encode the verifier to a byteArray
;
return [4 /*yield*/, window.crypto.subtle.digest('SHA-256', bytes)
// @ts-ignore
]; // sha256 hash it
case 1:
hash = _a.sent() // sha256 hash it
;
hashString = String.fromCharCode.apply(String, new Uint8Array(hash));
base64 = btoa(hashString) // Base64 encode the verifier hash
;
base64url = base64 // Base64Url encode the base64 encoded string, making it safe as a query param
.replace(/=/g, '')
.replace(/\+/g, '-')
.replace(/\//g, '_');
return [2 /*return*/, base64url];
}
});
});
async function generateCodeChallenge(codeVerifier) {
const encoder = new TextEncoder();
const bytes = encoder.encode(codeVerifier); // Encode the verifier to a byteArray
const hash = await window.crypto.subtle.digest('SHA-256', bytes); // sha256 hash it
const hashString = String.fromCharCode(...new Uint8Array(hash));
const base64 = btoa(hashString); // Base64 encode the verifier hash
return base64 // Base64Url encode the base64 encoded string, making it safe as a query param
.replace(/=/g, '')
.replace(/\+/g, '-')
.replace(/\//g, '_');
}
exports.generateCodeChallenge = generateCodeChallenge;

@@ -1,12 +0,13 @@

import { ReactNode } from "react";
import { ReactNode } from 'react';
export declare type TTokenData = {
exp: number;
[x: string]: any;
[x: string]: unknown;
};
export declare type TTokenResponse = {
access_token: string;
expires_in: number;
scope: string;
token_type: string;
expires_in?: number;
refresh_token?: string;
refresh_token_expires_in?: number;
id_token?: string;

@@ -21,4 +22,4 @@ };

logOut: () => void;
error: any;
tokenData?: TTokenData | null;
error: string | null;
tokenData?: TTokenData;
idToken?: string;

@@ -34,6 +35,10 @@ }

logoutRedirect?: string;
preLogin?: Function;
postLogin?: Function;
preLogin?: () => void;
postLogin?: () => void;
decodeToken?: boolean;
};
export declare type TAzureADErrorResponse = {
error_description: string;
[k: string]: unknown;
};
export declare type TInternalConfig = {

@@ -45,5 +50,5 @@ clientId: string;

scope: string;
preLogin: Function;
postLogin: Function;
preLogin?: () => void;
postLogin?: () => void;
decodeToken: boolean;
};

@@ -1,2 +0,2 @@

import { TAuthConfig } from "./Types";
export declare function validateAuthConfig(authConfig: TAuthConfig): void;
import { TInternalConfig } from './Types';
export declare function validateAuthConfig(config: TInternalConfig): void;

@@ -5,15 +5,15 @@ "use strict";

function stringIsUnset(value) {
var unset = ["", undefined, null];
const unset = ['', undefined, null];
return unset.includes(value);
}
function validateAuthConfig(authConfig) {
if (stringIsUnset(authConfig === null || authConfig === void 0 ? void 0 : authConfig.clientId))
throw "'clientId' must be set in the 'AuthConfig' object passed to 'react-oauth2-code-pkce' AuthProvider";
if (stringIsUnset(authConfig === null || authConfig === void 0 ? void 0 : authConfig.authorizationEndpoint))
throw "'authorizationEndpoint' must be set in the 'AuthConfig' object passed to 'react-oauth2-code-pkce' AuthProvider";
if (stringIsUnset(authConfig === null || authConfig === void 0 ? void 0 : authConfig.tokenEndpoint))
throw "'tokenEndpoint' must be set in the 'AuthConfig' object passed to 'react-oauth2-code-pkce' AuthProvider";
if (stringIsUnset(authConfig === null || authConfig === void 0 ? void 0 : authConfig.redirectUri))
throw "'redirectUri' must be set in the 'AuthConfig' object passed to 'react-oauth2-code-pkce' AuthProvider";
function validateAuthConfig(config) {
if (stringIsUnset(config?.clientId))
throw Error("'clientId' must be set in the 'AuthConfig' object passed to 'react-oauth2-code-pkce' AuthProvider");
if (stringIsUnset(config?.authorizationEndpoint))
throw Error("'authorizationEndpoint' must be set in the 'AuthConfig' object passed to 'react-oauth2-code-pkce' AuthProvider");
if (stringIsUnset(config?.tokenEndpoint))
throw Error("'tokenEndpoint' must be set in the 'AuthConfig' object passed to 'react-oauth2-code-pkce' AuthProvider");
if (stringIsUnset(config?.redirectUri))
throw Error("'redirectUri' must be set in the 'AuthConfig' object passed to 'react-oauth2-code-pkce' AuthProvider");
}
exports.validateAuthConfig = validateAuthConfig;
{
"name": "react-oauth2-code-pkce",
"version": "1.3.0-beta.0",
"version": "1.3.0",
"description": "Plug-and-play react package for OAuth2 Authorization Code flow with PKCE",

@@ -13,3 +13,3 @@ "main": "dist/index.js",

"peerDependencies": {
"react": "17.0.2"
"react": "^17.0.2"
},

@@ -16,0 +16,0 @@ "scripts": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc