@byu-oit/nuxt-common 2.14.4 → 2.15.0-beta.0
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.d.ts +21 -21
- package/dist/index.js +29 -29
- package/dist/plugins/appDynamics.d.ts +3 -3
- package/dist/plugins/appDynamics.js +23 -23
- package/dist/plugins/axios.d.ts +3 -3
- package/dist/plugins/axios.js +75 -75
- package/dist/plugins/byucomponents.d.ts +1 -1
- package/dist/plugins/byucomponents.js +3 -3
- package/dist/plugins/filters.d.ts +1 -1
- package/dist/plugins/filters.js +37 -37
- package/dist/plugins/implicit-grant.d.ts +3 -3
- package/dist/plugins/implicit-grant.js +109 -109
- package/dist/plugins/vuetify-dialog.d.ts +2 -2
- package/dist/plugins/vuetify-dialog.js +3 -3
- package/package.json +9 -9
package/dist/index.d.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import '@nuxtjs/axios';
|
|
2
|
-
import { Module } from '@nuxt/types';
|
|
3
|
-
import { VuetifyDialog } from 'vuetify-dialog';
|
|
4
|
-
declare module 'vuetify-dialog' {
|
|
5
|
-
interface VuetifyDialog {
|
|
6
|
-
authRefreshRequired: (params: any) => Promise<any>;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
declare module 'vuex/types/index' {
|
|
10
|
-
interface Store<S> {
|
|
11
|
-
$dialog: VuetifyDialog;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
declare module 'axios' {
|
|
15
|
-
interface AxiosRequestConfig {
|
|
16
|
-
noAutoError?: boolean;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
declare const byuModuleWrapper: Module;
|
|
20
|
-
export default byuModuleWrapper;
|
|
21
|
-
export declare const meta: any;
|
|
1
|
+
import '@nuxtjs/axios';
|
|
2
|
+
import { Module } from '@nuxt/types';
|
|
3
|
+
import { VuetifyDialog } from 'vuetify-dialog';
|
|
4
|
+
declare module 'vuetify-dialog' {
|
|
5
|
+
interface VuetifyDialog {
|
|
6
|
+
authRefreshRequired: (params: any) => Promise<any>;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
declare module 'vuex/types/index' {
|
|
10
|
+
interface Store<S> {
|
|
11
|
+
$dialog: VuetifyDialog;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
declare module 'axios' {
|
|
15
|
+
interface AxiosRequestConfig {
|
|
16
|
+
noAutoError?: boolean;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
declare const byuModuleWrapper: Module;
|
|
20
|
+
export default byuModuleWrapper;
|
|
21
|
+
export declare const meta: any;
|
package/dist/index.js
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import '@nuxtjs/axios';
|
|
2
|
-
import { resolve } from 'path';
|
|
3
|
-
// @ts-ignore
|
|
4
|
-
import { sequence } from '@nuxt/utils';
|
|
5
|
-
const byuModuleWrapper = async function (moduleOptions) {
|
|
6
|
-
const excludedModules = (moduleOptions && moduleOptions.excludedModules) || [];
|
|
7
|
-
const excludedPlugins = (moduleOptions && moduleOptions.excludedPlugins) || [];
|
|
8
|
-
const excludedBuildModules = (moduleOptions && moduleOptions.excludedBuildModules) || [];
|
|
9
|
-
const modules = ['@nuxtjs/axios', 'vuetify-dialog/nuxt'].filter(module => !excludedModules.includes(module));
|
|
10
|
-
const plugins = ['axios', 'implicit-grant', 'filters', 'appDynamics', 'byucomponents', 'vuetify-dialog'].filter(plugin => !excludedPlugins.includes(plugin));
|
|
11
|
-
if (!this.options.modules) {
|
|
12
|
-
this.options.modules = [];
|
|
13
|
-
}
|
|
14
|
-
modules.forEach(module => {
|
|
15
|
-
this.options.modules.push(module);
|
|
16
|
-
});
|
|
17
|
-
plugins.forEach(plugin => {
|
|
18
|
-
this.addPlugin({
|
|
19
|
-
src: resolve(__dirname, `plugins/${plugin}.js`),
|
|
20
|
-
options: (moduleOptions && moduleOptions.pluginOptions && moduleOptions.pluginOptions[plugin]) || {}
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
// We're inside "buildModules", so we can't simply tweak the nuxt options. Instead, we'll call addModule ourselves
|
|
24
|
-
const buildModules = ['@nuxt/typescript-build', '@nuxtjs/vuetify'].filter(buildModule => !excludedBuildModules.includes(buildModule));
|
|
25
|
-
const addModule = this.addModule.bind(this);
|
|
26
|
-
await sequence(buildModules, addModule);
|
|
27
|
-
};
|
|
28
|
-
export default byuModuleWrapper;
|
|
29
|
-
export const meta = require('../package.json');
|
|
1
|
+
import '@nuxtjs/axios';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import { sequence } from '@nuxt/utils';
|
|
5
|
+
const byuModuleWrapper = async function (moduleOptions) {
|
|
6
|
+
const excludedModules = (moduleOptions && moduleOptions.excludedModules) || [];
|
|
7
|
+
const excludedPlugins = (moduleOptions && moduleOptions.excludedPlugins) || [];
|
|
8
|
+
const excludedBuildModules = (moduleOptions && moduleOptions.excludedBuildModules) || [];
|
|
9
|
+
const modules = ['@nuxtjs/axios', 'vuetify-dialog/nuxt'].filter(module => !excludedModules.includes(module));
|
|
10
|
+
const plugins = ['axios', 'implicit-grant', 'filters', 'appDynamics', 'byucomponents', 'vuetify-dialog'].filter(plugin => !excludedPlugins.includes(plugin));
|
|
11
|
+
if (!this.options.modules) {
|
|
12
|
+
this.options.modules = [];
|
|
13
|
+
}
|
|
14
|
+
modules.forEach(module => {
|
|
15
|
+
this.options.modules.push(module);
|
|
16
|
+
});
|
|
17
|
+
plugins.forEach(plugin => {
|
|
18
|
+
this.addPlugin({
|
|
19
|
+
src: resolve(__dirname, `plugins/${plugin}.js`),
|
|
20
|
+
options: (moduleOptions && moduleOptions.pluginOptions && moduleOptions.pluginOptions[plugin]) || {}
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
// We're inside "buildModules", so we can't simply tweak the nuxt options. Instead, we'll call addModule ourselves
|
|
24
|
+
const buildModules = ['@nuxt/typescript-build', '@nuxtjs/vuetify'].filter(buildModule => !excludedBuildModules.includes(buildModule));
|
|
25
|
+
const addModule = this.addModule.bind(this);
|
|
26
|
+
await sequence(buildModules, addModule);
|
|
27
|
+
};
|
|
28
|
+
export default byuModuleWrapper;
|
|
29
|
+
export const meta = require('../package.json');
|
|
30
30
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Context } from '@nuxt/types';
|
|
2
|
-
declare const _default: (context: Context) => void;
|
|
3
|
-
export default _default;
|
|
1
|
+
import { Context } from '@nuxt/types';
|
|
2
|
+
declare const _default: (context: Context) => void;
|
|
3
|
+
export default _default;
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
export default (context) => {
|
|
2
|
-
const appKey = context.env.appDynamicsKey || process.env.NUXT_ENV_APP_DYNAMICS_KEY;
|
|
3
|
-
if (!appKey) {
|
|
4
|
-
// No key available, so skip App Dynamics setup
|
|
5
|
-
return;
|
|
6
|
-
}
|
|
7
|
-
Object.assign(window, {
|
|
8
|
-
'adrum-start-time': new Date().getTime(),
|
|
9
|
-
'adrum-config': {
|
|
10
|
-
appKey,
|
|
11
|
-
adrumExtUrlHttp: 'http://cdn.appdynamics.com',
|
|
12
|
-
adrumExtUrlHttps: 'https://cdn.appdynamics.com',
|
|
13
|
-
beaconUrlHttp: 'http://pdx-col.eum-appdynamics.com',
|
|
14
|
-
beaconUrlHttps: 'https://pdx-col.eum-appdynamics.com',
|
|
15
|
-
useHTTPSAlways: true,
|
|
16
|
-
xd: { enable: false },
|
|
17
|
-
spa: { spa2: true }
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
const script = document.createElement('script');
|
|
21
|
-
script.src = '//cdn.appdynamics.com/adrum/adrum-latest.js';
|
|
22
|
-
document.body.appendChild(script);
|
|
23
|
-
};
|
|
1
|
+
export default (context) => {
|
|
2
|
+
const appKey = context.env.appDynamicsKey || process.env.NUXT_ENV_APP_DYNAMICS_KEY;
|
|
3
|
+
if (!appKey) {
|
|
4
|
+
// No key available, so skip App Dynamics setup
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
Object.assign(window, {
|
|
8
|
+
'adrum-start-time': new Date().getTime(),
|
|
9
|
+
'adrum-config': {
|
|
10
|
+
appKey,
|
|
11
|
+
adrumExtUrlHttp: 'http://cdn.appdynamics.com',
|
|
12
|
+
adrumExtUrlHttps: 'https://cdn.appdynamics.com',
|
|
13
|
+
beaconUrlHttp: 'http://pdx-col.eum-appdynamics.com',
|
|
14
|
+
beaconUrlHttps: 'https://pdx-col.eum-appdynamics.com',
|
|
15
|
+
useHTTPSAlways: true,
|
|
16
|
+
xd: { enable: false },
|
|
17
|
+
spa: { spa2: true }
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const script = document.createElement('script');
|
|
21
|
+
script.src = '//cdn.appdynamics.com/adrum/adrum-latest.js';
|
|
22
|
+
document.body.appendChild(script);
|
|
23
|
+
};
|
|
24
24
|
//# sourceMappingURL=appDynamics.js.map
|
package/dist/plugins/axios.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Context } from '@nuxt/types';
|
|
2
|
-
declare const _default: (context: Context) => void;
|
|
3
|
-
export default _default;
|
|
1
|
+
import { Context } from '@nuxt/types';
|
|
2
|
+
declare const _default: (context: Context) => void;
|
|
3
|
+
export default _default;
|
package/dist/plugins/axios.js
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import * as authn from '@byuweb/browser-oauth';
|
|
3
|
-
// @ts-ignore
|
|
4
|
-
import { get } from 'lodash';
|
|
5
|
-
let refreshDialogVisible = false;
|
|
6
|
-
const errorMessages = [];
|
|
7
|
-
export default (context) => {
|
|
8
|
-
context.$axios.onResponseError(error => {
|
|
9
|
-
if (axios.isCancel(error)) {
|
|
10
|
-
// Explicit cancellation, so do not show "error" message
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
if (error.config &&
|
|
14
|
-
error.response?.status === 401 &&
|
|
15
|
-
JSON.stringify(error.response.data)?.includes?.('code>90090')) {
|
|
16
|
-
// @ts-ignore Internal var added to config, so we can tell if this is a second automated attempt
|
|
17
|
-
if (!error.config.insideRetry) {
|
|
18
|
-
return retryWithRefreshedToken(error);
|
|
19
|
-
}
|
|
20
|
-
// WSO2 "Invalid Credentials", "Token Expired", etc, are code "90090[X]".
|
|
21
|
-
// We don't bother parsing the full XML doc, just check if that chunk appears in the raw XML string
|
|
22
|
-
// Auto-refresh should happen in iframe background in ./implicit-grant.js
|
|
23
|
-
// If that fails, then we can't auto-refresh, so...
|
|
24
|
-
if (!refreshDialogVisible) {
|
|
25
|
-
const failDuringPost = error.config.method !== 'get';
|
|
26
|
-
refreshDialogVisible = true;
|
|
27
|
-
context.$dialog
|
|
28
|
-
.authRefreshRequired({
|
|
29
|
-
failDuringPost,
|
|
30
|
-
persistent: true,
|
|
31
|
-
waitForResult: true
|
|
32
|
-
})
|
|
33
|
-
// @ts-ignore: Third-party Typescript definition file is not correct: "show" can return a Promise
|
|
34
|
-
.then(() => (refreshDialogVisible = false));
|
|
35
|
-
}
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
if (error?.config?.noAutoError || process.env.NUXT_ENV_NO_AXIOS_AUTO_ERROR) {
|
|
39
|
-
// Caller has declared that it will handle unknown errors instead of using auto-popup
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const text = get(error, 'response.data.errorMessage') ||
|
|
43
|
-
get(error, 'response.data.readable_message') ||
|
|
44
|
-
get(error, 'response.data.metadata.validation_response.message') ||
|
|
45
|
-
get(error, 'response.data.ResolveIdentityService.errors.0.message') ||
|
|
46
|
-
get(error, 'response.data.message') ||
|
|
47
|
-
get(error, 'response.data.error.message') ||
|
|
48
|
-
get(error, 'response.headers.x-error-message') ||
|
|
49
|
-
error.message ||
|
|
50
|
-
'Unknown Error';
|
|
51
|
-
// Only pop up one copy of each error message at a time
|
|
52
|
-
if (!errorMessages.includes(text)) {
|
|
53
|
-
errorMessages.push(text);
|
|
54
|
-
context.$dialog.error({ title: 'Error', icon: false, text }).then(() => {
|
|
55
|
-
const index = errorMessages.indexOf(text);
|
|
56
|
-
if (index !== -1) {
|
|
57
|
-
errorMessages.splice(index, 1);
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
let refreshPromise = null;
|
|
63
|
-
function retryWithRefreshedToken(error) {
|
|
64
|
-
if (!refreshPromise) {
|
|
65
|
-
refreshPromise = authn.refresh('iframe').finally(() => (refreshPromise = null));
|
|
66
|
-
}
|
|
67
|
-
return refreshPromise.then((tokenInfo) => {
|
|
68
|
-
const config = Object.assign({ insideRetry: true }, error.config);
|
|
69
|
-
if (tokenInfo?.state === authn.STATE_AUTHENTICATED && tokenInfo.token?.authorizationHeader) {
|
|
70
|
-
config.headers.Authorization = tokenInfo.token.authorizationHeader;
|
|
71
|
-
}
|
|
72
|
-
return context.$axios.request(config);
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
};
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import * as authn from '@byuweb/browser-oauth';
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import { get } from 'lodash';
|
|
5
|
+
let refreshDialogVisible = false;
|
|
6
|
+
const errorMessages = [];
|
|
7
|
+
export default (context) => {
|
|
8
|
+
context.$axios.onResponseError(error => {
|
|
9
|
+
if (axios.isCancel(error)) {
|
|
10
|
+
// Explicit cancellation, so do not show "error" message
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (error.config &&
|
|
14
|
+
error.response?.status === 401 &&
|
|
15
|
+
JSON.stringify(error.response.data)?.includes?.('code>90090')) {
|
|
16
|
+
// @ts-ignore Internal var added to config, so we can tell if this is a second automated attempt
|
|
17
|
+
if (!error.config.insideRetry) {
|
|
18
|
+
return retryWithRefreshedToken(error);
|
|
19
|
+
}
|
|
20
|
+
// WSO2 "Invalid Credentials", "Token Expired", etc, are code "90090[X]".
|
|
21
|
+
// We don't bother parsing the full XML doc, just check if that chunk appears in the raw XML string
|
|
22
|
+
// Auto-refresh should happen in iframe background in ./implicit-grant.js
|
|
23
|
+
// If that fails, then we can't auto-refresh, so...
|
|
24
|
+
if (!refreshDialogVisible) {
|
|
25
|
+
const failDuringPost = error.config.method !== 'get';
|
|
26
|
+
refreshDialogVisible = true;
|
|
27
|
+
context.$dialog
|
|
28
|
+
.authRefreshRequired({
|
|
29
|
+
failDuringPost,
|
|
30
|
+
persistent: true,
|
|
31
|
+
waitForResult: true
|
|
32
|
+
})
|
|
33
|
+
// @ts-ignore: Third-party Typescript definition file is not correct: "show" can return a Promise
|
|
34
|
+
.then(() => (refreshDialogVisible = false));
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (error?.config?.noAutoError || process.env.NUXT_ENV_NO_AXIOS_AUTO_ERROR) {
|
|
39
|
+
// Caller has declared that it will handle unknown errors instead of using auto-popup
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const text = get(error, 'response.data.errorMessage') ||
|
|
43
|
+
get(error, 'response.data.readable_message') ||
|
|
44
|
+
get(error, 'response.data.metadata.validation_response.message') ||
|
|
45
|
+
get(error, 'response.data.ResolveIdentityService.errors.0.message') ||
|
|
46
|
+
get(error, 'response.data.message') ||
|
|
47
|
+
get(error, 'response.data.error.message') ||
|
|
48
|
+
get(error, 'response.headers.x-error-message') ||
|
|
49
|
+
error.message ||
|
|
50
|
+
'Unknown Error';
|
|
51
|
+
// Only pop up one copy of each error message at a time
|
|
52
|
+
if (!errorMessages.includes(text)) {
|
|
53
|
+
errorMessages.push(text);
|
|
54
|
+
context.$dialog.error({ title: 'Error', icon: false, text }).then(() => {
|
|
55
|
+
const index = errorMessages.indexOf(text);
|
|
56
|
+
if (index !== -1) {
|
|
57
|
+
errorMessages.splice(index, 1);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
let refreshPromise = null;
|
|
63
|
+
function retryWithRefreshedToken(error) {
|
|
64
|
+
if (!refreshPromise) {
|
|
65
|
+
refreshPromise = authn.refresh('iframe').finally(() => (refreshPromise = null));
|
|
66
|
+
}
|
|
67
|
+
return refreshPromise.then((tokenInfo) => {
|
|
68
|
+
const config = Object.assign({ insideRetry: true }, error.config);
|
|
69
|
+
if (tokenInfo?.state === authn.STATE_AUTHENTICATED && tokenInfo.token?.authorizationHeader) {
|
|
70
|
+
config.headers.Authorization = tokenInfo.token.authorizationHeader;
|
|
71
|
+
}
|
|
72
|
+
return context.$axios.request(config);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
76
|
//# sourceMappingURL=axios.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Vue from 'vue';
|
|
2
|
-
// Just hiding Vue "unknown element" warnings for external BYU components
|
|
3
|
-
Vue.config.ignoredElements = [/^byu-/];
|
|
1
|
+
import Vue from 'vue';
|
|
2
|
+
// Just hiding Vue "unknown element" warnings for external BYU components
|
|
3
|
+
Vue.config.ignoredElements = [/^byu-/];
|
|
4
4
|
//# sourceMappingURL=byucomponents.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
package/dist/plugins/filters.js
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
/* Some commonly used filters */
|
|
2
|
-
import Vue from 'vue';
|
|
3
|
-
import vueMoment from 'vue-moment';
|
|
4
|
-
Vue.filter('stripHtml', (value) => {
|
|
5
|
-
const div = document.createElement('div');
|
|
6
|
-
div.innerHTML = value;
|
|
7
|
-
// eslint-disable-next-line unicorn/prefer-text-content
|
|
8
|
-
return div.textContent || div.innerText || '';
|
|
9
|
-
});
|
|
10
|
-
Vue.use(vueMoment);
|
|
11
|
-
// vue-moment filter is unnecessarily noisy if the input value is empty (0, empty string, null, etc)
|
|
12
|
-
// So we monkey patch it to quietly do that "empty?" check ourselves before calling the real filter
|
|
13
|
-
const realVueMomentFilter = Vue.options.filters.moment;
|
|
14
|
-
Vue.filter('moment', (...args) => {
|
|
15
|
-
if (!args[0]) {
|
|
16
|
-
return args[0];
|
|
17
|
-
}
|
|
18
|
-
return realVueMomentFilter(...args);
|
|
19
|
-
});
|
|
20
|
-
const terms = {
|
|
21
|
-
'1': 'Winter',
|
|
22
|
-
'3': 'Spring',
|
|
23
|
-
'4': 'Summer',
|
|
24
|
-
'5': 'Fall'
|
|
25
|
-
};
|
|
26
|
-
Vue.filter('yearTerm', (yearTerm) => {
|
|
27
|
-
const string = '' + yearTerm;
|
|
28
|
-
if (string.length !== 5) {
|
|
29
|
-
return yearTerm;
|
|
30
|
-
}
|
|
31
|
-
const termNumber = yearTerm.substr(4);
|
|
32
|
-
if (!terms[termNumber]) {
|
|
33
|
-
return yearTerm;
|
|
34
|
-
}
|
|
35
|
-
const year = yearTerm.substr(0, 4);
|
|
36
|
-
return `${terms[termNumber]} ${year}`;
|
|
37
|
-
});
|
|
1
|
+
/* Some commonly used filters */
|
|
2
|
+
import Vue from 'vue';
|
|
3
|
+
import vueMoment from 'vue-moment';
|
|
4
|
+
Vue.filter('stripHtml', (value) => {
|
|
5
|
+
const div = document.createElement('div');
|
|
6
|
+
div.innerHTML = value;
|
|
7
|
+
// eslint-disable-next-line unicorn/prefer-text-content
|
|
8
|
+
return div.textContent || div.innerText || '';
|
|
9
|
+
});
|
|
10
|
+
Vue.use(vueMoment);
|
|
11
|
+
// vue-moment filter is unnecessarily noisy if the input value is empty (0, empty string, null, etc)
|
|
12
|
+
// So we monkey patch it to quietly do that "empty?" check ourselves before calling the real filter
|
|
13
|
+
const realVueMomentFilter = Vue.options.filters.moment;
|
|
14
|
+
Vue.filter('moment', (...args) => {
|
|
15
|
+
if (!args[0]) {
|
|
16
|
+
return args[0];
|
|
17
|
+
}
|
|
18
|
+
return realVueMomentFilter(...args);
|
|
19
|
+
});
|
|
20
|
+
const terms = {
|
|
21
|
+
'1': 'Winter',
|
|
22
|
+
'3': 'Spring',
|
|
23
|
+
'4': 'Summer',
|
|
24
|
+
'5': 'Fall'
|
|
25
|
+
};
|
|
26
|
+
Vue.filter('yearTerm', (yearTerm) => {
|
|
27
|
+
const string = '' + yearTerm;
|
|
28
|
+
if (string.length !== 5) {
|
|
29
|
+
return yearTerm;
|
|
30
|
+
}
|
|
31
|
+
const termNumber = yearTerm.substr(4);
|
|
32
|
+
if (!terms[termNumber]) {
|
|
33
|
+
return yearTerm;
|
|
34
|
+
}
|
|
35
|
+
const year = yearTerm.substr(0, 4);
|
|
36
|
+
return `${terms[termNumber]} ${year}`;
|
|
37
|
+
});
|
|
38
38
|
//# sourceMappingURL=filters.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Context } from '@nuxt/types';
|
|
2
|
-
declare const _default: (context: Context) => void;
|
|
3
|
-
export default _default;
|
|
1
|
+
import { Context } from '@nuxt/types';
|
|
2
|
+
declare const _default: (context: Context) => void;
|
|
3
|
+
export default _default;
|
|
@@ -1,110 +1,110 @@
|
|
|
1
|
-
import Vue from 'vue';
|
|
2
|
-
import * as authn from '@byuweb/browser-oauth';
|
|
3
|
-
// @ts-ignore
|
|
4
|
-
import dynamicImportPolyfill from 'dynamic-import-polyfill';
|
|
5
|
-
import { isEqual } from 'lodash';
|
|
6
|
-
const AuthRefreshRequired = Vue.extend({
|
|
7
|
-
props: {
|
|
8
|
-
failDuringPost: Boolean
|
|
9
|
-
},
|
|
10
|
-
methods: {
|
|
11
|
-
popupAuth() {
|
|
12
|
-
authn.refresh('popup');
|
|
13
|
-
this.$emit('submit');
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
// Template compilation doesn't work at runtime in our standard BYU builds, so we
|
|
17
|
-
// manually do the `render` function instead of a `template`
|
|
18
|
-
// ADDENDUM: Sigh, even the Vuetify elements ("v-card", "v-card-title", etc.) do not
|
|
19
|
-
// compile, so we have to manually generate them as well
|
|
20
|
-
render(h) {
|
|
21
|
-
return h('div', { staticClass: 'v-card v-sheet theme--light' }, [
|
|
22
|
-
h('div', { staticClass: 'v-card__title headline warning white--text' }, 'Re-authentication Required'),
|
|
23
|
-
h('div', { staticClass: 'v-card__text' }, [
|
|
24
|
-
'CAS Authentication has expired.',
|
|
25
|
-
h('br'),
|
|
26
|
-
h('br'),
|
|
27
|
-
'Click this "Re-authenticate" button. You will log in through a separate tab and then immediately return to this page.',
|
|
28
|
-
this.failDuringPost
|
|
29
|
-
? h('div', [h('br'), 'If you were in the middle of saving data, you may have to click "Save" again.'])
|
|
30
|
-
: ''
|
|
31
|
-
]),
|
|
32
|
-
h('div', { staticClass: 'v-card__actions' }, [
|
|
33
|
-
h('button', {
|
|
34
|
-
staticClass: 'v-btn v-btn--contained theme--light v-size--large primary',
|
|
35
|
-
on: {
|
|
36
|
-
click: ($event) => {
|
|
37
|
-
$event.stopPropagation();
|
|
38
|
-
// @ts-ignore
|
|
39
|
-
return this.popupAuth($event);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}, [h('span', { staticClass: 'v-btn__content' }, 'Re-authenticate')])
|
|
43
|
-
])
|
|
44
|
-
]);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
export default (context) => {
|
|
48
|
-
context.$dialog.component('authRefreshRequired', AuthRefreshRequired);
|
|
49
|
-
let oAuthConfig = context.env.oAuth;
|
|
50
|
-
if (!oAuthConfig?.clientId && process.env.NUXT_ENV_OAUTH_CLIENT_ID) {
|
|
51
|
-
oAuthConfig = {
|
|
52
|
-
autoRefreshOnTimeout: true,
|
|
53
|
-
logoutRedirect: 'https://www.byu.edu',
|
|
54
|
-
clientId: process.env.NUXT_ENV_OAUTH_CLIENT_ID,
|
|
55
|
-
callbackUrl: process.env.NUXT_ENV_OAUTH_CALLBACK_URL
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
if (!oAuthConfig?.clientId) {
|
|
59
|
-
// $dialog isn't fully configured when this code runs, so setTimeout bumps this call to the end of the event queue
|
|
60
|
-
setTimeout(() => context.$dialog.error({
|
|
61
|
-
title: 'Configuration Error',
|
|
62
|
-
text: 'This site is not configured correctly',
|
|
63
|
-
persistent: true
|
|
64
|
-
}));
|
|
65
|
-
console.error('OAuth environment variables (NUXT_ENV_OAUTH_CLIENT_ID, NUXT_ENV_OAUTH_CALLBACK_URL) not set');
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
const providerUrl = '<%= options.providerUrl || "https://cdn.byu.edu/browser-oauth-implicit/" + (options.pkceShim ? "experimental/pkce-shim" : "latest") + "/implicit-grant.min.js" %>';
|
|
69
|
-
// TODO: If Edge ever natively supports dynamic imports (i.e. "import(xxx)" returns a Promise), then use native
|
|
70
|
-
dynamicImportPolyfill.initialize();
|
|
71
|
-
__import__(/* webpackIgnore: true */ providerUrl).then(implicit => implicit.configure(oAuthConfig));
|
|
72
|
-
// External library, so we cannot avoid "new" constructor
|
|
73
|
-
// eslint-disable-next-line no-new
|
|
74
|
-
new authn.AuthenticationObserver(({ state, token, user }) => {
|
|
75
|
-
// Ignore HASH of current path, just get path + query
|
|
76
|
-
const currentPath = {
|
|
77
|
-
path: context.route.path,
|
|
78
|
-
query: context.route.query
|
|
79
|
-
};
|
|
80
|
-
switch (state) {
|
|
81
|
-
case authn.STATE_UNAUTHENTICATED:
|
|
82
|
-
window.sessionStorage.setItem('sitePreauthPath', JSON.stringify(currentPath));
|
|
83
|
-
if (!process.env.NUXT_ENV_OAUTH_DISABLE_AUTO_LOGIN) {
|
|
84
|
-
authn.login();
|
|
85
|
-
}
|
|
86
|
-
break;
|
|
87
|
-
case authn.STATE_ERROR:
|
|
88
|
-
context.$dialog.authRefreshRequired({ persistent: true });
|
|
89
|
-
break;
|
|
90
|
-
case authn.STATE_AUTHENTICATED: {
|
|
91
|
-
context.$axios.setToken(token.authorizationHeader);
|
|
92
|
-
context.store.dispatch('authenticate', user);
|
|
93
|
-
const prePathString = window.sessionStorage.getItem('sitePreauthPath');
|
|
94
|
-
window.sessionStorage.removeItem('sitePreauthPath');
|
|
95
|
-
if (prePathString) {
|
|
96
|
-
try {
|
|
97
|
-
const prePath = JSON.parse(prePathString);
|
|
98
|
-
if (!isEqual(prePath, currentPath) && prePath.path) {
|
|
99
|
-
context.redirect(prePath.path, prePath.query);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
catch (e) {
|
|
103
|
-
// Intentionally ignoring. If the stored path is malformed JSON, then just stay where we are
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
};
|
|
1
|
+
import Vue from 'vue';
|
|
2
|
+
import * as authn from '@byuweb/browser-oauth';
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import dynamicImportPolyfill from 'dynamic-import-polyfill';
|
|
5
|
+
import { isEqual } from 'lodash';
|
|
6
|
+
const AuthRefreshRequired = Vue.extend({
|
|
7
|
+
props: {
|
|
8
|
+
failDuringPost: Boolean
|
|
9
|
+
},
|
|
10
|
+
methods: {
|
|
11
|
+
popupAuth() {
|
|
12
|
+
authn.refresh('popup');
|
|
13
|
+
this.$emit('submit');
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
// Template compilation doesn't work at runtime in our standard BYU builds, so we
|
|
17
|
+
// manually do the `render` function instead of a `template`
|
|
18
|
+
// ADDENDUM: Sigh, even the Vuetify elements ("v-card", "v-card-title", etc.) do not
|
|
19
|
+
// compile, so we have to manually generate them as well
|
|
20
|
+
render(h) {
|
|
21
|
+
return h('div', { staticClass: 'v-card v-sheet theme--light' }, [
|
|
22
|
+
h('div', { staticClass: 'v-card__title headline warning white--text' }, 'Re-authentication Required'),
|
|
23
|
+
h('div', { staticClass: 'v-card__text' }, [
|
|
24
|
+
'CAS Authentication has expired.',
|
|
25
|
+
h('br'),
|
|
26
|
+
h('br'),
|
|
27
|
+
'Click this "Re-authenticate" button. You will log in through a separate tab and then immediately return to this page.',
|
|
28
|
+
this.failDuringPost
|
|
29
|
+
? h('div', [h('br'), 'If you were in the middle of saving data, you may have to click "Save" again.'])
|
|
30
|
+
: ''
|
|
31
|
+
]),
|
|
32
|
+
h('div', { staticClass: 'v-card__actions' }, [
|
|
33
|
+
h('button', {
|
|
34
|
+
staticClass: 'v-btn v-btn--contained theme--light v-size--large primary',
|
|
35
|
+
on: {
|
|
36
|
+
click: ($event) => {
|
|
37
|
+
$event.stopPropagation();
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
return this.popupAuth($event);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}, [h('span', { staticClass: 'v-btn__content' }, 'Re-authenticate')])
|
|
43
|
+
])
|
|
44
|
+
]);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
export default (context) => {
|
|
48
|
+
context.$dialog.component('authRefreshRequired', AuthRefreshRequired);
|
|
49
|
+
let oAuthConfig = context.env.oAuth;
|
|
50
|
+
if (!oAuthConfig?.clientId && process.env.NUXT_ENV_OAUTH_CLIENT_ID) {
|
|
51
|
+
oAuthConfig = {
|
|
52
|
+
autoRefreshOnTimeout: true,
|
|
53
|
+
logoutRedirect: 'https://www.byu.edu',
|
|
54
|
+
clientId: process.env.NUXT_ENV_OAUTH_CLIENT_ID,
|
|
55
|
+
callbackUrl: process.env.NUXT_ENV_OAUTH_CALLBACK_URL
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (!oAuthConfig?.clientId) {
|
|
59
|
+
// $dialog isn't fully configured when this code runs, so setTimeout bumps this call to the end of the event queue
|
|
60
|
+
setTimeout(() => context.$dialog.error({
|
|
61
|
+
title: 'Configuration Error',
|
|
62
|
+
text: 'This site is not configured correctly',
|
|
63
|
+
persistent: true
|
|
64
|
+
}));
|
|
65
|
+
console.error('OAuth environment variables (NUXT_ENV_OAUTH_CLIENT_ID, NUXT_ENV_OAUTH_CALLBACK_URL) not set');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const providerUrl = '<%= options.providerUrl || "https://cdn.byu.edu/browser-oauth-implicit/" + (options.pkceShim ? "experimental/pkce-shim" : "latest") + "/implicit-grant.min.js" %>';
|
|
69
|
+
// TODO: If Edge ever natively supports dynamic imports (i.e. "import(xxx)" returns a Promise), then use native
|
|
70
|
+
dynamicImportPolyfill.initialize();
|
|
71
|
+
__import__(/* webpackIgnore: true */ providerUrl).then(implicit => implicit.configure(oAuthConfig));
|
|
72
|
+
// External library, so we cannot avoid "new" constructor
|
|
73
|
+
// eslint-disable-next-line no-new
|
|
74
|
+
new authn.AuthenticationObserver(({ state, token, user }) => {
|
|
75
|
+
// Ignore HASH of current path, just get path + query
|
|
76
|
+
const currentPath = {
|
|
77
|
+
path: context.route.path,
|
|
78
|
+
query: context.route.query
|
|
79
|
+
};
|
|
80
|
+
switch (state) {
|
|
81
|
+
case authn.STATE_UNAUTHENTICATED:
|
|
82
|
+
window.sessionStorage.setItem('sitePreauthPath', JSON.stringify(currentPath));
|
|
83
|
+
if (!process.env.NUXT_ENV_OAUTH_DISABLE_AUTO_LOGIN) {
|
|
84
|
+
authn.login();
|
|
85
|
+
}
|
|
86
|
+
break;
|
|
87
|
+
case authn.STATE_ERROR:
|
|
88
|
+
context.$dialog.authRefreshRequired({ persistent: true });
|
|
89
|
+
break;
|
|
90
|
+
case authn.STATE_AUTHENTICATED: {
|
|
91
|
+
context.$axios.setToken(token.authorizationHeader);
|
|
92
|
+
context.store.dispatch('authenticate', user);
|
|
93
|
+
const prePathString = window.sessionStorage.getItem('sitePreauthPath');
|
|
94
|
+
window.sessionStorage.removeItem('sitePreauthPath');
|
|
95
|
+
if (prePathString) {
|
|
96
|
+
try {
|
|
97
|
+
const prePath = JSON.parse(prePathString);
|
|
98
|
+
if (!isEqual(prePath, currentPath) && prePath.path) {
|
|
99
|
+
context.redirect(prePath.path, prePath.query);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
// Intentionally ignoring. If the stored path is malformed JSON, then just stay where we are
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
110
|
//# sourceMappingURL=implicit-grant.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Context } from '@nuxt/types';
|
|
2
|
-
export default function (context: Context): void;
|
|
1
|
+
import { Context } from '@nuxt/types';
|
|
2
|
+
export default function (context: Context): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export default function (context) {
|
|
2
|
-
context.store.$dialog = context.$dialog;
|
|
3
|
-
}
|
|
1
|
+
export default function (context) {
|
|
2
|
+
context.store.$dialog = context.$dialog;
|
|
3
|
+
}
|
|
4
4
|
//# sourceMappingURL=vuetify-dialog.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@byu-oit/nuxt-common",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.0-beta.0",
|
|
4
4
|
"description": "BYU Front End common module for Nuxt.js",
|
|
5
5
|
"author": "BYU Apps Custom",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"dist"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@babel/core": "^7.16.
|
|
21
|
+
"@babel/core": "^7.16.12",
|
|
22
22
|
"@byuweb/browser-oauth": "^1.0.3",
|
|
23
23
|
"@nuxt/types": "^2.15.8",
|
|
24
24
|
"@nuxt/typescript-build": "^2.1.0",
|
|
@@ -33,27 +33,27 @@
|
|
|
33
33
|
"@types/lru-cache": "^5.1.1",
|
|
34
34
|
"@types/superagent": "^4.1.14",
|
|
35
35
|
"@types/vue-moment": "^4.0.3",
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
37
|
-
"@typescript-eslint/parser": "5.
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "5.10.0",
|
|
37
|
+
"@typescript-eslint/parser": "5.10.0",
|
|
38
38
|
"@vue/cli-plugin-unit-jest": "^4.5.15",
|
|
39
39
|
"@vue/eslint-config-standard": "^6.1.0",
|
|
40
40
|
"@vue/eslint-config-typescript": "^10.0.0",
|
|
41
41
|
"@vue/server-test-utils": "^1.3.0",
|
|
42
42
|
"@vue/test-utils": "^1.3.0",
|
|
43
43
|
"babel-polyfill": "^6.26.0",
|
|
44
|
-
"dotenv": "^
|
|
44
|
+
"dotenv": "^14.2.0",
|
|
45
45
|
"dynamic-import-polyfill": "^0.1.1",
|
|
46
|
-
"eslint": "^8.
|
|
46
|
+
"eslint": "^8.7.0",
|
|
47
47
|
"eslint-config-prettier": "^8.3.0",
|
|
48
48
|
"eslint-config-standard": "^16.0.3",
|
|
49
49
|
"eslint-plugin-import": "^2.25.4",
|
|
50
|
-
"eslint-plugin-jest": "^
|
|
50
|
+
"eslint-plugin-jest": "^26.0.0",
|
|
51
51
|
"eslint-plugin-node": "^11.1.0",
|
|
52
52
|
"eslint-plugin-nuxt": "^3.1.0",
|
|
53
53
|
"eslint-plugin-prettier": "^4.0.0",
|
|
54
54
|
"eslint-plugin-promise": "^6.0.0",
|
|
55
55
|
"eslint-plugin-standard": "^5.0.0",
|
|
56
|
-
"eslint-plugin-vue": "^8.
|
|
56
|
+
"eslint-plugin-vue": "^8.3.0",
|
|
57
57
|
"eslint-plugin-vuetify": "^1.1.0",
|
|
58
58
|
"flush-promises": "^1.0.2",
|
|
59
59
|
"husky": "^7.0.4",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"nuxt": "^2.15.8",
|
|
62
62
|
"nuxt-property-decorator": "^2.9.1",
|
|
63
63
|
"swagger-typescript-codegen": "^3.2.4",
|
|
64
|
-
"ts-jest": "^27.1.
|
|
64
|
+
"ts-jest": "^27.1.3",
|
|
65
65
|
"ts-node": "^10.4.0",
|
|
66
66
|
"vue-moment": "^4.1.0",
|
|
67
67
|
"vuetify-dialog": "^2.0.17",
|