react-oauth2-code-pkce
Advanced tools
Comparing version 1.2.4 to 1.2.5
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; |
@@ -30,21 +30,24 @@ "use strict"; | ||
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_idToken', null), idToken = _d[0], setIdToken = _d[1]; | ||
var _e = (0, Hooks_1.default)('ROCP_loginInProgress', false), loginInProgress = _e[0], setLoginInProgress = _e[1]; | ||
var _f = (0, react_1.useState)(), tokenData = _f[0], setTokenData = _f[1]; | ||
var _g = (0, react_1.useState)(null), error = _g[0], setError = _g[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"); | ||
exports.AuthContext = (0, react_1.createContext)({ | ||
token: '', | ||
logOut: () => null, | ||
error: null, | ||
}); | ||
const AuthProvider = ({ authConfig, children }) => { | ||
const [refreshToken, setRefreshToken] = (0, Hooks_1.default)('ROCP_refreshToken', null); | ||
const [token, setToken] = (0, Hooks_1.default)('ROCP_token', ''); | ||
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; | ||
(0, validateAuthConfig_1.validateAuthConfig)(authConfig); | ||
function logOut() { | ||
setRefreshToken(null); | ||
setToken(null); | ||
setIdToken(null); | ||
setToken(''); | ||
setIdToken(undefined); | ||
setTokenData(undefined); | ||
@@ -56,3 +59,3 @@ setLoginInProgress(false); | ||
setToken(response.access_token); | ||
setIdToken((response === null || response === void 0 ? void 0 : response.id_token) || "None"); | ||
setIdToken(response?.id_token || 'None'); | ||
setLoginInProgress(false); | ||
@@ -63,6 +66,7 @@ setTokenData((0, authentication_1.decodeToken)(response.access_token)); | ||
if (refreshToken) { | ||
if ((0, authentication_1.tokenExpired)(token)) { // The client has an expired token. Will try to get a new one with the refreshToken | ||
(0, authentication_1.fetchWithRefreshToken)({ authConfig: authConfig, refreshToken: refreshToken }) | ||
.then(function (result) { return handleTokenResponse(result); }) | ||
.catch(function (error) { | ||
if (token && (0, authentication_1.tokenExpired)(token)) { | ||
// The client has an expired token. Will try to get a new one with the refreshToken | ||
(0, authentication_1.fetchWithRefreshToken)({ authConfig, refreshToken }) | ||
.then((result) => handleTokenResponse(result)) | ||
.catch((error) => { | ||
setError(error); | ||
@@ -76,4 +80,5 @@ if ((0, authentication_1.errorMessageForExpiredRefreshToken)(error)) { | ||
} | ||
else { // No refresh_token | ||
console.error("Tried to refresh token without a refresh token."); | ||
else { | ||
// No refresh_token | ||
console.error('Tried to refresh access_token without a refresh_token.'); | ||
setError('Bad authorization state. Refreshing the page might solve the issue.'); | ||
@@ -83,13 +88,14 @@ } | ||
// 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); | ||
@@ -99,12 +105,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)(authConfig) | ||
.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 | ||
if (authConfig === null || authConfig === void 0 ? void 0 : authConfig.postLogin) | ||
if (authConfig?.postLogin) | ||
authConfig.postLogin(); | ||
}) | ||
.catch(function (error) { | ||
.catch((error) => { | ||
setError(error); | ||
@@ -114,3 +121,4 @@ }); | ||
} | ||
else if (!token) { // First page visit | ||
else if (!token) { | ||
// First page visit | ||
setLoginInProgress(true); | ||
@@ -123,5 +131,5 @@ (0, authentication_1.login)(authConfig); | ||
} | ||
}, []); | ||
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,9 +0,9 @@ | ||
import { TAuthConfig, TTokenData } from "./Types"; | ||
import { TAuthConfig, TTokenData, TTokenResponse } from './Types'; | ||
export declare const EXPIRED_REFRESH_TOKEN_ERROR_CODES: string[]; | ||
export declare function login(authConfig: TAuthConfig): Promise<void>; | ||
export declare const fetchTokens: (authConfig: TAuthConfig) => Promise<any>; | ||
export declare const fetchTokens: (authConfig: TAuthConfig) => Promise<TTokenResponse>; | ||
export declare const fetchWithRefreshToken: (props: { | ||
authConfig: TAuthConfig; | ||
refreshToken: string; | ||
}) => Promise<any>; | ||
}) => Promise<TTokenResponse>; | ||
/** | ||
@@ -17,3 +17,3 @@ * Decodes the the base64 encoded JWT. Returns a TToken. | ||
*/ | ||
export declare const tokenExpired: (token: string) => Boolean; | ||
export declare const tokenExpired: (token: string) => 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.decodeToken = exports.fetchWithRefreshToken = exports.fetchTokens = exports.login = exports.EXPIRED_REFRESH_TOKEN_ERROR_CODES = void 0; | ||
var pkceUtils_1 = require("./pkceUtils"); | ||
var codeVerifierStorageKey = "PKCE_code_verifier"; | ||
const pkceUtils_1 = require("./pkceUtils"); | ||
const codeVerifierStorageKey = 'PKCE_code_verifier'; | ||
// [ AzureAD,] | ||
exports.EXPIRED_REFRESH_TOKEN_ERROR_CODES = ["AADSTS700084"]; | ||
function login(authConfig) { | ||
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: authConfig.clientId, | ||
scope: authConfig.scope || "", | ||
redirect_uri: authConfig.redirectUri, | ||
code_challenge: codeChallenge, | ||
code_challenge_method: 'S256', | ||
}); | ||
// Call any preLogin function in authConfig | ||
if (authConfig === null || authConfig === void 0 ? void 0 : authConfig.preLogin) | ||
authConfig.preLogin(); | ||
location.replace("".concat(authConfig.authorizationEndpoint, "?").concat(params.toString())); | ||
}); | ||
return [2 /*return*/]; | ||
exports.EXPIRED_REFRESH_TOKEN_ERROR_CODES = ['AADSTS700084']; | ||
async function login(authConfig) { | ||
// 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: authConfig.clientId, | ||
scope: authConfig.scope || '', | ||
redirect_uri: authConfig.redirectUri, | ||
code_challenge: codeChallenge, | ||
code_challenge_method: 'S256', | ||
}); | ||
// Call any preLogin function in authConfig | ||
if (authConfig?.preLogin) | ||
authConfig.preLogin(); | ||
window.location.replace(`${authConfig.authorizationEndpoint}?${params.toString()}`); | ||
}); | ||
} | ||
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) { | ||
@@ -76,16 +39,17 @@ return fetch(tokenEndpoint, { | ||
}) | ||
.then(function (response) { return response.json() | ||
.then(function (body) { | ||
if (!response.ok) { | ||
.then((response) => response.json().then((body) => { | ||
if (isTokenResponse(body)) { | ||
return body; | ||
} | ||
else { | ||
console.error(body.error_description); | ||
throw body.error_description; | ||
} | ||
return body; | ||
}); }) | ||
.catch(function (error) { | ||
})) | ||
.catch((error) => { | ||
console.error(error); | ||
throw (error === null || error === void 0 ? void 0 : error.message) || error; | ||
throw error.message; | ||
}); | ||
} | ||
var fetchTokens = function (authConfig) { | ||
const fetchTokens = (authConfig) => { | ||
/* | ||
@@ -96,15 +60,15 @@ 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'); | ||
formData.append('code', authCode); | ||
formData.append('scope', authConfig.scope || ""); | ||
formData.append('scope', authConfig.scope || ''); | ||
formData.append('client_id', authConfig.clientId); | ||
@@ -116,8 +80,8 @@ formData.append('redirect_uri', authConfig.redirectUri); | ||
exports.fetchTokens = fetchTokens; | ||
var fetchWithRefreshToken = function (props) { | ||
var authConfig = props.authConfig, refreshToken = props.refreshToken; | ||
var formData = new FormData(); | ||
const fetchWithRefreshToken = (props) => { | ||
const { authConfig, refreshToken } = props; | ||
const formData = new FormData(); | ||
formData.append('grant_type', 'refresh_token'); | ||
formData.append('refresh_token', refreshToken); | ||
formData.append('scope', authConfig.scope || ""); | ||
formData.append('scope', authConfig.scope || ''); | ||
formData.append('client_id', authConfig.clientId); | ||
@@ -131,6 +95,6 @@ formData.append('redirect_uri', authConfig.redirectUri); | ||
*/ | ||
var decodeToken = function (token) { | ||
var base64Url = token.split('.')[1]; | ||
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); | ||
var jsonPayload = decodeURIComponent(atob(base64) | ||
const decodeToken = (token) => { | ||
const base64Url = token.split('.')[1]; | ||
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); | ||
const jsonPayload = decodeURIComponent(atob(base64) | ||
.split('') | ||
@@ -148,12 +112,12 @@ .map(function (c) { | ||
*/ | ||
var tokenExpired = function (token) { | ||
var bufferTimeInMilliseconds = 10 * 60 * 1000; // minutes * seconds * toMilliseconds | ||
var exp = (0, exports.decodeToken)(token).exp; | ||
var expirationTimeWithBuffer = new Date(exp * 1000 - bufferTimeInMilliseconds); | ||
const tokenExpired = (token) => { | ||
const bufferTimeInMilliseconds = 10 * 60 * 1000; // minutes * seconds * toMilliseconds | ||
const { exp } = (0, exports.decodeToken)(token); | ||
const expirationTimeWithBuffer = new Date(exp * 1000 - bufferTimeInMilliseconds); | ||
return new Date() > expirationTimeWithBuffer; | ||
}; | ||
exports.tokenExpired = tokenExpired; | ||
var errorMessageForExpiredRefreshToken = function (errorMessage) { | ||
var expired = false; | ||
exports.EXPIRED_REFRESH_TOKEN_ERROR_CODES.forEach(function (errorCode) { | ||
const errorMessageForExpiredRefreshToken = (errorMessage) => { | ||
let expired = false; | ||
exports.EXPIRED_REFRESH_TOKEN_ERROR_CODES.forEach((errorCode) => { | ||
if (errorMessage.includes(errorCode)) { | ||
@@ -160,0 +124,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)(() => { | ||
try { | ||
var item = localStorage.getItem(key); | ||
const item = localStorage.getItem(key); | ||
return item ? JSON.parse(item) : initialValue; | ||
@@ -14,6 +14,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); | ||
@@ -20,0 +20,0 @@ localStorage.setItem(key, JSON.stringify(valueToStore)); |
@@ -1,2 +0,2 @@ | ||
export { AuthProvider, AuthContext } from "./AuthContext"; | ||
export type { TAuthConfig, IAuthProvider, IAuthContext } 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,5 +0,5 @@ | ||
import { ReactNode } from "react"; | ||
import { ReactNode } from 'react'; | ||
export declare type TTokenData = { | ||
exp: number; | ||
[x: string]: any; | ||
[x: string]: unknown; | ||
}; | ||
@@ -13,4 +13,4 @@ export interface IAuthProvider { | ||
logOut: () => void; | ||
error: any; | ||
tokenData?: TTokenData | null; | ||
error: string | null; | ||
tokenData?: TTokenData; | ||
idToken?: string; | ||
@@ -26,4 +26,14 @@ } | ||
logoutRedirect?: string; | ||
preLogin?: Function; | ||
postLogin?: Function; | ||
preLogin?: () => void; | ||
postLogin?: () => void; | ||
}; | ||
export declare type TTokenResponse = { | ||
access_token: string; | ||
refresh_token: string; | ||
expires_in: number; | ||
id_token?: string; | ||
}; | ||
export declare type TAzureADErrorResponse = { | ||
error_description: string; | ||
[k: string]: unknown; | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { TAuthConfig } from "./Types"; | ||
import { TAuthConfig } from './Types'; | ||
export declare function validateAuthConfig(authConfig: TAuthConfig): 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"; | ||
if (stringIsUnset(authConfig?.clientId)) | ||
throw Error("'clientId' must be set in the 'AuthConfig' object passed to 'react-oauth2-code-pkce' AuthProvider"); | ||
if (stringIsUnset(authConfig?.authorizationEndpoint)) | ||
throw Error("'authorizationEndpoint' must be set in the 'AuthConfig' object passed to 'react-oauth2-code-pkce' AuthProvider"); | ||
if (stringIsUnset(authConfig?.tokenEndpoint)) | ||
throw Error("'tokenEndpoint' must be set in the 'AuthConfig' object passed to 'react-oauth2-code-pkce' AuthProvider"); | ||
if (stringIsUnset(authConfig?.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.2.4", | ||
"version": "1.2.5", | ||
"description": "Plug-and-play react package for OAuth2 Authorization Code flow with PKCE", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
20687
413