@cortezaproject/corteza-vue 2021.9.9 → 2021.9.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.es.js +66 -47
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +66 -47
- package/dist/index.js.map +1 -1
- package/dist/plugins/auth.d.ts +16 -6
- package/package.json +1 -1
package/dist/index.es.js
CHANGED
|
@@ -1934,7 +1934,7 @@ const storeKeyFinalState = 'auth.state.final';
|
|
|
1934
1934
|
const storeKeyRefreshToken = 'auth.refresh-token';
|
|
1935
1935
|
const maxStartAttempts = 5;
|
|
1936
1936
|
class Auth {
|
|
1937
|
-
constructor({ app, verbose, cortezaAuthURL, callbackURL, entrypointURL, location, sessionStorage, refreshFactor }) {
|
|
1937
|
+
constructor({ app, verbose, cortezaAuthURL, callbackURL, entrypointURL, location, sessionStorage, refreshFactor, registerEventListener }) {
|
|
1938
1938
|
if (refreshFactor >= 1 || refreshFactor <= 0) {
|
|
1939
1939
|
throw new Error('refreshFactor should be between 0 and 1');
|
|
1940
1940
|
}
|
|
@@ -1944,6 +1944,7 @@ class Auth {
|
|
|
1944
1944
|
this.callbackURL = callbackURL;
|
|
1945
1945
|
this.location = location;
|
|
1946
1946
|
this.sessionStorage = sessionStorage;
|
|
1947
|
+
this.registerEventListener = registerEventListener;
|
|
1947
1948
|
this.refreshFactor = refreshFactor;
|
|
1948
1949
|
this.entrypointURL = entrypointURL;
|
|
1949
1950
|
this.log.debug('initialized auth plugin', {
|
|
@@ -1998,38 +1999,26 @@ class Auth {
|
|
|
1998
1999
|
handle(req = new URL(this.entrypointURL)) {
|
|
1999
2000
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2000
2001
|
this.log.info('handling authentication');
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2002
|
+
// State management
|
|
2003
|
+
// - duplication checking
|
|
2004
|
+
// - management handlers
|
|
2005
|
+
const dup = this.handleStateManagement();
|
|
2006
|
+
if (dup) {
|
|
2007
|
+
this.log.debug('duplicate tab: unauthorized');
|
|
2008
|
+
throw new Error('Unauthenticated');
|
|
2009
|
+
}
|
|
2010
|
+
// Handle auth callback requests
|
|
2011
|
+
const params = new URLSearchParams(req.search);
|
|
2012
|
+
if (this.isCallback(req.pathname) && (params.has('error') || params.has('code'))) {
|
|
2004
2013
|
if (params.has('error')) {
|
|
2005
2014
|
throw new Error(params.get('error') || 'authentication flow failed with error');
|
|
2006
2015
|
}
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
if (params.has('state')) {
|
|
2010
|
-
const state = params.get('state') || '';
|
|
2011
|
-
const storeKeyStateLocation = `auth.state.${state}.location`;
|
|
2012
|
-
const tmp = this.sessionStorage.getItem(storeKeyStateLocation);
|
|
2013
|
-
if (tmp === null) {
|
|
2014
|
-
console.warn('state does not match, restarting authentication flow');
|
|
2015
|
-
this.startAuthenticationFlow();
|
|
2016
|
-
return null;
|
|
2017
|
-
}
|
|
2018
|
-
if (!this.isCallback(tmp)) {
|
|
2019
|
-
// if by some coincidence we got callback URL to finalLocation
|
|
2020
|
-
// we'll silently ignore it and redirect user back to entrypoint
|
|
2021
|
-
finalLocation = tmp;
|
|
2022
|
-
}
|
|
2023
|
-
this.sessionStorage.removeItem(storeKeyStateLocation);
|
|
2024
|
-
}
|
|
2025
|
-
const code = params.get('code') || '';
|
|
2026
|
-
this.log.info('authorization code received', code);
|
|
2027
|
-
const rsp = yield this.exchangeCode(code);
|
|
2028
|
-
this.startFinalState(finalLocation);
|
|
2029
|
-
return rsp;
|
|
2030
|
-
}
|
|
2016
|
+
this.log.info('handling authentication callback');
|
|
2017
|
+
return this.handleCallbackRoute(params.get('state'), (params.has('code') ? params.get('code') : ''));
|
|
2031
2018
|
}
|
|
2032
|
-
|
|
2019
|
+
// Handle auth from the current system state
|
|
2020
|
+
this.log.info('handling authentication from state');
|
|
2021
|
+
return this.handleState();
|
|
2033
2022
|
});
|
|
2034
2023
|
}
|
|
2035
2024
|
/**
|
|
@@ -2046,10 +2035,16 @@ class Auth {
|
|
|
2046
2035
|
* know, after the redirection to the final location, if this is a final stage or not and if the refresh token
|
|
2047
2036
|
* belongs to this session or not.
|
|
2048
2037
|
*/
|
|
2049
|
-
|
|
2050
|
-
|
|
2038
|
+
handleStateManagement() {
|
|
2039
|
+
// See if this is a duplicate
|
|
2040
|
+
const dup = this.sessionStorage.getItem(storeKeyFinalState) !== null;
|
|
2041
|
+
// Bind listeners to cleanup
|
|
2042
|
+
this.registerEventListener('beforeunload', function () {
|
|
2043
|
+
this.sessionStorage.removeItem(storeKeyFinalState);
|
|
2044
|
+
});
|
|
2045
|
+
// Set state
|
|
2051
2046
|
this.sessionStorage.setItem(storeKeyFinalState, Date.now().toString());
|
|
2052
|
-
|
|
2047
|
+
return dup;
|
|
2053
2048
|
}
|
|
2054
2049
|
/**
|
|
2055
2050
|
* Called when refresh token is re-fetched.
|
|
@@ -2057,7 +2052,6 @@ class Auth {
|
|
|
2057
2052
|
* Cleanup aux items in the session store
|
|
2058
2053
|
*/
|
|
2059
2054
|
completeFinalState() {
|
|
2060
|
-
this.sessionStorage.removeItem(storeKeyFinalState);
|
|
2061
2055
|
this.sessionStorage.removeItem(storeKeyFlowStarted);
|
|
2062
2056
|
const stateKey = /^auth\.state\.\w+\.location$/;
|
|
2063
2057
|
for (let i = 0; i < this.sessionStorage.length; i++) {
|
|
@@ -2068,12 +2062,38 @@ class Auth {
|
|
|
2068
2062
|
}
|
|
2069
2063
|
}
|
|
2070
2064
|
/**
|
|
2071
|
-
*
|
|
2065
|
+
* Exchanges the auth parameters for access & refresh token.
|
|
2072
2066
|
*
|
|
2073
|
-
*
|
|
2067
|
+
* If the parameters are correct and exchange is successful, the refresh token
|
|
2068
|
+
* gets stored in localStorage for further use, the access token and current user get stored
|
|
2069
|
+
* in-memory.
|
|
2070
|
+
*
|
|
2071
|
+
* Function will throw null when user is unauthenticated
|
|
2074
2072
|
*/
|
|
2075
|
-
|
|
2076
|
-
return this
|
|
2073
|
+
handleCallbackRoute(state, code) {
|
|
2074
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2075
|
+
let finalLocation = this.entrypointURL;
|
|
2076
|
+
if (state) {
|
|
2077
|
+
const storeKeyStateLocation = `auth.state.${state}.location`;
|
|
2078
|
+
const tmp = this.sessionStorage.getItem(storeKeyStateLocation);
|
|
2079
|
+
if (tmp === null) {
|
|
2080
|
+
console.warn('state does not match, restarting authentication flow');
|
|
2081
|
+
this.startAuthenticationFlow();
|
|
2082
|
+
return null;
|
|
2083
|
+
}
|
|
2084
|
+
if (!this.isCallback(tmp)) {
|
|
2085
|
+
// if by some coincidence we got callback URL to finalLocation
|
|
2086
|
+
// we'll silently ignore it and redirect user back to entrypoint
|
|
2087
|
+
finalLocation = tmp;
|
|
2088
|
+
}
|
|
2089
|
+
this.sessionStorage.removeItem(storeKeyStateLocation);
|
|
2090
|
+
}
|
|
2091
|
+
this.log.info('authorization code received', code);
|
|
2092
|
+
const rsp = yield this.exchangeCode(code);
|
|
2093
|
+
this.log.info('redirecting back to final destination', finalLocation);
|
|
2094
|
+
this.location.assign(finalLocation);
|
|
2095
|
+
return rsp;
|
|
2096
|
+
});
|
|
2077
2097
|
}
|
|
2078
2098
|
/**
|
|
2079
2099
|
* Checks current auth state; is access token loaded OR do we have a refresh token we can use
|
|
@@ -2087,7 +2107,7 @@ class Auth {
|
|
|
2087
2107
|
*
|
|
2088
2108
|
* Function will throw null when user is unauthenticated
|
|
2089
2109
|
*/
|
|
2090
|
-
|
|
2110
|
+
handleState() {
|
|
2091
2111
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2092
2112
|
this.log.info('checking authentication');
|
|
2093
2113
|
if (this[accessToken]) {
|
|
@@ -2123,14 +2143,12 @@ class Auth {
|
|
|
2123
2143
|
* If this is a duplicated-session, an error will be thrown and authentication will be (probably)
|
|
2124
2144
|
* restarted by the caller.
|
|
2125
2145
|
*/
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
return this.exchangeRefresh(refreshToken);
|
|
2133
|
-
}
|
|
2146
|
+
this.log.info('refreshing token', refreshToken);
|
|
2147
|
+
/**
|
|
2148
|
+
* Refresh token found in the storage,
|
|
2149
|
+
* let's use it to get new access token
|
|
2150
|
+
*/
|
|
2151
|
+
return this.exchangeRefresh(refreshToken);
|
|
2134
2152
|
}
|
|
2135
2153
|
throw new Error('Unauthenticated');
|
|
2136
2154
|
});
|
|
@@ -2321,7 +2339,7 @@ class Auth {
|
|
|
2321
2339
|
}
|
|
2322
2340
|
function auth () {
|
|
2323
2341
|
return function (Vue, opts) {
|
|
2324
|
-
let { app = '', rootApp = false, cortezaAuthURL = '', callbackURL = '', verbose = undefined, refreshFactor = 0.75, entrypointURL = window.location.toString(), location = window.location, sessionStorage = window.sessionStorage, } = (opts || {});
|
|
2342
|
+
let { app = '', rootApp = false, cortezaAuthURL = '', callbackURL = '', verbose = undefined, refreshFactor = 0.75, entrypointURL = window.location.toString(), location = window.location, sessionStorage = window.sessionStorage, registerEventListener = window.addEventListener.bind(window), } = (opts || {});
|
|
2325
2343
|
if (!cortezaAuthURL) {
|
|
2326
2344
|
/**
|
|
2327
2345
|
* cortezaAuthURL not explicitly set, try to auto-configure from properties set on window variable
|
|
@@ -2415,6 +2433,7 @@ function auth () {
|
|
|
2415
2433
|
sessionStorage,
|
|
2416
2434
|
entrypointURL,
|
|
2417
2435
|
refreshFactor,
|
|
2436
|
+
registerEventListener,
|
|
2418
2437
|
});
|
|
2419
2438
|
};
|
|
2420
2439
|
}
|