Skip to content

Commit 1bd346d

Browse files
committed
feat(auth): persist cookie based apiKey in document.cookie
Refs #8683
1 parent 26709c3 commit 1bd346d

File tree

6 files changed

+108
-22
lines changed

6 files changed

+108
-22
lines changed

src/core/plugins/auth/actions.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,12 @@ export function restoreAuthorization(payload) {
273273

274274
export const persistAuthorizationIfNeeded = () => ( { authSelectors, getConfigs } ) => {
275275
const configs = getConfigs()
276-
if (configs.persistAuthorization)
277-
{
278-
const authorized = authSelectors.authorized()
279-
localStorage.setItem("authorized", JSON.stringify(authorized.toJS()))
280-
}
276+
277+
if (!configs.persistAuthorization) return
278+
279+
// persist authorization to local storage
280+
const authorized = authSelectors.authorized().toJS()
281+
localStorage.setItem("authorized", JSON.stringify(authorized))
281282
}
282283

283284
export const authPopup = (url, swaggerUIRedirectOauth2) => ( ) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @prettier
3+
*/
4+
export const loaded = (oriAction, system) => (payload) => {
5+
const { getConfigs, authActions } = system
6+
const configs = getConfigs()
7+
8+
oriAction(payload)
9+
10+
// check if we should restore authorization data from localStorage
11+
if (configs.persistAuthorization) {
12+
const authorized = localStorage.getItem("authorized")
13+
if (authorized) {
14+
authActions.restoreAuthorization({
15+
authorized: JSON.parse(authorized),
16+
})
17+
}
18+
}
19+
}

src/core/plugins/auth/index.js

+17-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import reducers from "./reducers"
22
import * as actions from "./actions"
33
import * as selectors from "./selectors"
4-
import * as specWrapActionReplacements from "./spec-wrap-actions"
4+
import { execute as wrappedExecuteAction } from "./spec-extensions/wrap-actions"
5+
import { loaded as wrappedLoadedAction } from "./config-extensions/wrap-actions"
6+
import { authorize as wrappedAuthorizeAction, logout as wrappedLogoutAction } from "./wrap-actions"
57

68
export default function() {
79
return {
@@ -15,11 +17,22 @@ export default function() {
1517
auth: {
1618
reducers,
1719
actions,
18-
selectors
20+
selectors,
21+
wrapActions: {
22+
authorize: wrappedAuthorizeAction,
23+
logout: wrappedLogoutAction,
24+
}
25+
},
26+
configs: {
27+
wrapActions: {
28+
loaded: wrappedLoadedAction,
29+
},
1930
},
2031
spec: {
21-
wrapActions: specWrapActionReplacements
22-
}
32+
wrapActions: {
33+
execute: wrappedExecuteAction,
34+
},
35+
},
2336
}
2437
}
2538
}

src/core/plugins/auth/wrap-actions.js

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* @prettier
3+
*/
4+
5+
/**
6+
* `authorize` and `logout` wrapped actions provide capacity
7+
* to persist cookie based apiKey in document.cookie.
8+
*
9+
* `persistAuthorization` SwaggerUI options needs to set to `true`
10+
* for document.cookie persistence to work.
11+
*/
12+
export const authorize = (oriAction, system) => (payload) => {
13+
oriAction(payload)
14+
15+
const configs = system.getConfigs()
16+
17+
if (!configs.persistAuthorization) return
18+
19+
// create cookie
20+
try {
21+
const [{ schema, value }] = Object.values(payload)
22+
const isApiKeyAuth = schema.get("type") === "apiKey"
23+
const isInCookie = schema.get("in") === "cookie"
24+
const isApiKeyInCookie = isApiKeyAuth && isInCookie
25+
26+
if (isApiKeyInCookie) {
27+
document.cookie = `${schema.get("name")}=${value}; SameSite=None; Secure`
28+
}
29+
} catch (error) {
30+
console.error(
31+
"Error persisting cookie based apiKey in document.cookie.",
32+
error
33+
)
34+
}
35+
}
36+
37+
export const logout = (oriAction, system) => (payload) => {
38+
const configs = system.getConfigs()
39+
const authorized = system.authSelectors.authorized()
40+
41+
// dispose of cookie
42+
try {
43+
if (configs.persistAuthorization && Array.isArray(payload)) {
44+
payload.forEach((authorizedName) => {
45+
const auth = authorized.get(authorizedName, {})
46+
const isApiKeyAuth = auth.getIn(["schema", "type"]) === "apiKey"
47+
const isInCookie = auth.getIn(["schema", "in"]) === "cookie"
48+
const isApiKeyInCookie = isApiKeyAuth && isInCookie
49+
50+
if (isApiKeyInCookie) {
51+
const cookieName = auth.getIn(["schema", "name"])
52+
document.cookie = `${cookieName}=; Max-Age=-99999999`
53+
}
54+
})
55+
}
56+
} catch (error) {
57+
console.error(
58+
"Error deleting cookie based apiKey from document.cookie.",
59+
error
60+
)
61+
}
62+
63+
oriAction(payload)
64+
}

src/core/plugins/configs/actions.js

+2-13
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,6 @@ export function toggle(configName) {
2121

2222

2323
// Hook
24-
export const loaded = () => ({getConfigs, authActions}) => {
25-
// check if we should restore authorization data from localStorage
26-
const configs = getConfigs()
27-
if (configs.persistAuthorization)
28-
{
29-
const authorized = localStorage.getItem("authorized")
30-
if(authorized)
31-
{
32-
authActions.restoreAuthorization({
33-
authorized: JSON.parse(authorized)
34-
})
35-
}
36-
}
24+
export const loaded = () => () => {
25+
// noop
3726
}

0 commit comments

Comments
 (0)