feat: Preserve authorization on browser refresh and close/reopen (#5939)
* Add default configuration `preserveAuthorization` * Add localStorage to auth plugin * Add persistAuthorization unit tests * Refactor persistAuthorization to use wrapped actions * Upgrade unit tests to be compatible with jest * Add persistAuthorization documentation Co-authored-by: Tim Lai <timothy.lai@gmail.com>
This commit is contained in:
committed by
GitHub
parent
48ee32faa1
commit
96aecc8860
@@ -27,7 +27,7 @@ export default class Auths extends React.Component {
|
||||
e.preventDefault()
|
||||
|
||||
let { authActions } = this.props
|
||||
authActions.authorize(this.state)
|
||||
authActions.authorizeWithPersistOption(this.state)
|
||||
}
|
||||
|
||||
logoutClick =(e) => {
|
||||
@@ -43,7 +43,7 @@ export default class Auths extends React.Component {
|
||||
return prev
|
||||
}, {}))
|
||||
|
||||
authActions.logout(auths)
|
||||
authActions.logoutWithPersistOption(auths)
|
||||
}
|
||||
|
||||
close =(e) => {
|
||||
|
||||
@@ -96,7 +96,7 @@ export default class Oauth2 extends React.Component {
|
||||
let { authActions, errActions, name } = this.props
|
||||
|
||||
errActions.clear({authId: name, type: "auth", source: "auth"})
|
||||
authActions.logout([ name ])
|
||||
authActions.logoutWithPersistOption([ name ])
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -37,6 +37,7 @@ export default function SwaggerUI(opts) {
|
||||
filter: null,
|
||||
validatorUrl: "https://validator.swagger.io/validator",
|
||||
oauth2RedirectUrl: `${window.location.protocol}//${window.location.host}/oauth2-redirect.html`,
|
||||
persistAuthorization: false,
|
||||
configs: {},
|
||||
custom: {},
|
||||
displayOperationId: false,
|
||||
|
||||
@@ -9,6 +9,7 @@ export const PRE_AUTHORIZE_OAUTH2 = "pre_authorize_oauth2"
|
||||
export const AUTHORIZE_OAUTH2 = "authorize_oauth2"
|
||||
export const VALIDATE = "validate"
|
||||
export const CONFIGURE_AUTH = "configure_auth"
|
||||
export const RESTORE_AUTHORIZATION = "restore_authorization"
|
||||
|
||||
const scopeSeparator = " "
|
||||
|
||||
@@ -26,6 +27,11 @@ export function authorize(payload) {
|
||||
}
|
||||
}
|
||||
|
||||
export const authorizeWithPersistOption = (payload) => ( { authActions } ) => {
|
||||
authActions.authorize(payload)
|
||||
authActions.persistAuthorizationIfNeeded()
|
||||
}
|
||||
|
||||
export function logout(payload) {
|
||||
return {
|
||||
type: LOGOUT,
|
||||
@@ -33,6 +39,11 @@ export function logout(payload) {
|
||||
}
|
||||
}
|
||||
|
||||
export const logoutWithPersistOption = (payload) => ( { authActions } ) => {
|
||||
authActions.logout(payload)
|
||||
authActions.persistAuthorizationIfNeeded()
|
||||
}
|
||||
|
||||
export const preAuthorizeImplicit = (payload) => ( { authActions, errActions } ) => {
|
||||
let { auth , token, isValid } = payload
|
||||
let { schema, name } = auth
|
||||
@@ -60,9 +71,10 @@ export const preAuthorizeImplicit = (payload) => ( { authActions, errActions } )
|
||||
return
|
||||
}
|
||||
|
||||
authActions.authorizeOauth2({ auth, token })
|
||||
authActions.authorizeOauth2WithPersistOption({ auth, token })
|
||||
}
|
||||
|
||||
|
||||
export function authorizeOauth2(payload) {
|
||||
return {
|
||||
type: AUTHORIZE_OAUTH2,
|
||||
@@ -70,6 +82,12 @@ export function authorizeOauth2(payload) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const authorizeOauth2WithPersistOption = (payload) => ( { authActions } ) => {
|
||||
authActions.authorizeOauth2(payload)
|
||||
authActions.persistAuthorizationIfNeeded()
|
||||
}
|
||||
|
||||
export const authorizePassword = ( auth ) => ( { authActions } ) => {
|
||||
let { schema, name, username, password, passwordType, clientId, clientSecret } = auth
|
||||
let form = {
|
||||
@@ -208,7 +226,7 @@ export const authorizeRequest = ( data ) => ( { fn, getConfigs, authActions, err
|
||||
return
|
||||
}
|
||||
|
||||
authActions.authorizeOauth2({ auth, token})
|
||||
authActions.authorizeOauth2WithPersistOption({ auth, token})
|
||||
})
|
||||
.catch(e => {
|
||||
let err = new Error(e)
|
||||
@@ -244,3 +262,19 @@ export function configureAuth(payload) {
|
||||
payload: payload
|
||||
}
|
||||
}
|
||||
|
||||
export function restoreAuthorization(payload) {
|
||||
return {
|
||||
type: RESTORE_AUTHORIZATION,
|
||||
payload: payload
|
||||
}
|
||||
}
|
||||
|
||||
export const persistAuthorizationIfNeeded = () => ( { authSelectors, getConfigs } ) => {
|
||||
const configs = getConfigs()
|
||||
if (configs.persistAuthorization)
|
||||
{
|
||||
const authorized = authSelectors.authorized()
|
||||
localStorage.setItem("authorized", JSON.stringify(authorized.toJS()))
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,8 @@ import {
|
||||
AUTHORIZE,
|
||||
AUTHORIZE_OAUTH2,
|
||||
LOGOUT,
|
||||
CONFIGURE_AUTH
|
||||
CONFIGURE_AUTH,
|
||||
RESTORE_AUTHORIZATION
|
||||
} from "./actions"
|
||||
|
||||
export default {
|
||||
@@ -50,7 +51,10 @@ export default {
|
||||
auth.token = Object.assign({}, token)
|
||||
parsedAuth = fromJS(auth)
|
||||
|
||||
return state.setIn( [ "authorized", parsedAuth.get("name") ], parsedAuth )
|
||||
let map = state.get("authorized") || Map()
|
||||
map = map.set(parsedAuth.get("name"), parsedAuth)
|
||||
|
||||
return state.set( "authorized", map )
|
||||
},
|
||||
|
||||
[LOGOUT]: (state, { payload } ) =>{
|
||||
@@ -65,5 +69,9 @@ export default {
|
||||
|
||||
[CONFIGURE_AUTH]: (state, { payload } ) =>{
|
||||
return state.set("configs", payload)
|
||||
}
|
||||
},
|
||||
|
||||
[RESTORE_AUTHORIZATION]: (state, { payload } ) =>{
|
||||
return state.set("authorized", fromJS(payload.authorized))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -21,4 +21,17 @@ export function toggle(configName) {
|
||||
|
||||
|
||||
// Hook
|
||||
export const loaded = () => () => {}
|
||||
export const loaded = () => ({getConfigs, authActions}) => {
|
||||
// check if we should restore authorization data from localStorage
|
||||
const configs = getConfigs()
|
||||
if (configs.persistAuthorization)
|
||||
{
|
||||
const authorized = localStorage.getItem("authorized")
|
||||
if(authorized)
|
||||
{
|
||||
authActions.restoreAuthorization({
|
||||
authorized: JSON.parse(authorized)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user