azure-ad-auth-react-native
Version:
An React Native module implements Azure AD V2.0 authentication flow
198 lines (163 loc) • 10.6 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>webauth/index.js - Documentation</title>
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
<div class="navicon"></div>
</label>
<label for="nav-trigger" class="overlay"></label>
<nav>
<li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Auth.html">Auth</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.acquireTokenSilent">acquireTokenSilent</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.clearPersistenCache">clearPersistenCache</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.exchange">exchange</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.loginUrl">loginUrl</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.logoutUrl">logoutUrl</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.msGraphRequest">msGraphRequest</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.refreshTokens">refreshTokens</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="AzureAuth.html">AzureAuth</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="BaseError.html">BaseError</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Client.html">Client</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="TokenCache.AccessTokenItem.html">AccessTokenItem</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="TokenCache.BaseTokenItem.html">BaseTokenItem</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="TokenCache.RefreshTokenItem.html">RefreshTokenItem</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="TokenCache.Scope.html">Scope</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="TokenCache.TokenCache.html">TokenCache</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="WebAuth.html">WebAuth</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="WebAuth.html#.authorize">authorize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="WebAuth.html#.clearSession">clearSession</a></span></li><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#extractIdToken">extractIdToken</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#getAllUserTokenKeys">getAllUserTokenKeys</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isIntersects">isIntersects</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isSubsetOf">isSubsetOf</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#request">request</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#serializeParams">serializeParams</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#validate">validate</a></span></li>
</nav>
<div id="main">
<h1 class="page-title">webauth/index.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>import Agent from './agent'
import url from 'url'
import AuthError from '../auth/authError'
import Scope from '../token/scope'
import BaseTokenItem from '../token/baseTokenItem'
import { validate } from '../utils/validate'
/**
* Helper to perform Auth against Azure AD login page
*
* It will use `/authorize` endpoint of the Authorization Server (AS)
* with Code Grant
*
* @export
* @class WebAuth
* @see https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-code
*/
export default class WebAuth {
constructor(auth) {
this.client = auth
const { clientId } = auth
this.clientId = clientId
this.agent = new Agent()
}
/**
* Starts the AuthN/AuthZ transaction against the AS in the in-app browser.
*
* In iOS it will use `SFSafariViewController` and in Android `Chrome Custom Tabs`.
*
* @param {Object} options parameters to send
* @param {String} [options.scope] scopes requested for the issued tokens.
* OpenID Connect scopes are always added to every request. `openid profile offline_access`
* @see https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-scopes
* @param {String} [options.prompt] (optional) indicates the type of user interaction that is required.
* @param {Boolean} [options.ephemeralSession] SSO. It only affects iOS with versions 13 and above.
* The only valid values at this time are 'login', 'none', and 'consent'.
* @returns {Promise<BaseTokenItem | AccessTokenItem>}
*
* @memberof WebAuth
*/
async authorize(options = {}) {
const scope = new Scope(options.scope)
const { clientId, client, agent } = this
const {nonce, state, verifier} = await agent.generateRequestParams()
let requestParams = {
...options,
clientId,
scope: scope.toString(),
responseType: 'code' + (scope.toString().includes('openid') ? ' id_token': ''),
response_mode: 'fragment', // 'query' is unsafe and not supported, the hash fragment is also default
state: state,
nonce: nonce,
code_challenge_method: 'plain',
code_challenge: verifier
}
const loginUrl = this.client.loginUrl(requestParams)
let redirectUrl = await agent.openWeb(loginUrl, options.ephemeralSession)
if (!redirectUrl || !redirectUrl.startsWith(client.redirectUri)) {
throw new AuthError({
json: {
error: 'aa.redirect_uri.not_expected',
error_description: `Expected ${client.redirectUri} but got ${redirectUrl}`
},
status: 0
})
}
// Response is returned in hash, but we want to get parsed object
// Query can be parsed, therefore lets replace hash sign with '?' mark
redirectUrl = redirectUrl.replace('#','?') // replace only first one
const urlHashParsed = url.parse(redirectUrl, true).query
const {
code,
state: resultState,
error
} = urlHashParsed
if (error) {
throw new AuthError({json: urlHashParsed, status: 0})
}
if (resultState !== state) {
throw new AuthError({
json: {
error: 'aa.state.invalid',
error_description: 'Invalid state received in redirect url'
},
status: 0
})
}
const tokenResponse = await client.exchange({
code,
scope: scope.toString(),
code_verifier: verifier
})
if (tokenResponse.refreshToken) {
this.client.cache.saveRefreshToken(tokenResponse)
}
if (tokenResponse.accessToken) {
let accessToken = await this.client.cache.saveAccessToken(tokenResponse)
return accessToken
} else {
// we have to have at least id_token in respose
return new BaseTokenItem(tokenResponse, this.clientId)
}
}
/**
* Removes Azure session
*
* @param {Object} options parameters to send
* @param {Boolean} [options.closeOnLoad] close browser window on 'Loaded' event (works only on iOS)
* @returns {Promise}
*
* @memberof WebAuth
*/
clearSession(options = {closeOnLoad: true}) {
const { client, agent } = this
const parsedOptions = validate({
parameters: {
closeOnLoad: { required: true },
},
validate: true // not declared params are NOT allowed:
}, options)
const logoutUrl = client.logoutUrl()
return agent.openWeb(logoutUrl, false, parsedOptions.closeOnLoad)
}
}
</code></pre>
</article>
</section>
</div>
<br class="clear">
<footer>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.2</a> on Mon Oct 03 2022 22:30:32 GMT+0200 (GMT+02:00) using the Minami theme.
</footer>
<script>prettyPrint();</script>
<script src="scripts/linenumber.js"></script>
</body>
</html>