Skip to content

Commit 667672a

Browse files
merge, no commit, ff (DevExpress#32322), put import last, rename files with override, deferred fallback / wg esm vs default
1 parent ac68b75 commit 667672a

File tree

11 files changed

+203
-0
lines changed

11 files changed

+203
-0
lines changed

apps/demos/Demos/DataGrid/BatchUpdateRequest/Angular/app/app.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { HttpClient, provideHttpClient, withFetch } from '@angular/common/http';
44
import { lastValueFrom } from 'rxjs';
55
import * as AspNetData from 'devextreme-aspnet-data-nojquery';
66
import { DxDataGridComponent, DxDataGridModule, DxDataGridTypes } from 'devextreme-angular/ui/data-grid';
7+
import 'anti-forgery';
78

89
if (!/localhost/.test(document.location.host)) {
910
enableProdMode();

apps/demos/Demos/DataGrid/BatchUpdateRequest/React/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import React from 'react';
22
import ReactDOM from 'react-dom';
33

44
import App from './App.tsx';
5+
// eslint-disable-next-line import/no-unresolved
6+
import 'anti-forgery';
57

68
ReactDOM.render(
79
<App />,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom';
33
import App from './App.js';
4+
// eslint-disable-next-line import/no-unresolved
5+
import 'anti-forgery';
46

57
ReactDOM.render(<App />, document.getElementById('app'));
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createApp } from 'vue';
22
import App from './App.vue';
3+
import 'anti-forgery';
34

45
createApp(App).mount('#app');

apps/demos/Demos/DataGrid/BatchUpdateRequest/jQuery/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<link rel="stylesheet" type="text/css" href="styles.css" />
1111
<script src="../../../../node_modules/devextreme-dist/js/dx.all.js"></script>
1212
<script src="../../../../node_modules/devextreme-aspnet-data/js/dx.aspnet.data.js"></script>
13+
<script src="/shared/anti-forgery/jquery-override.js"></script>
1314
<script src="index.js"></script>
1415
</head>
1516
<body class="dx-viewport">

apps/demos/configs/Angular/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,10 @@ window.config = {
155155
'npm:': '../../../../node_modules/',
156156
'bundles:': '../../../../bundles/',
157157
'externals:': '../../../../bundles/externals/',
158+
'anti-forgery:': '../../../../shared/anti-forgery/',
158159
},
159160
map: {
161+
'anti-forgery': 'anti-forgery:fetch-override.js',
160162
'ts': 'npm:plugin-typescript/lib/plugin.js',
161163
'typescript': 'npm:typescript/lib/typescript.js',
162164
'jszip': 'npm:jszip/dist/jszip.min.js',

apps/demos/configs/React/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,11 @@ window.config = {
4646
'npm:': '../../../../node_modules/',
4747
'bundles:': '../../../../bundles/',
4848
'externals:': '../../../../bundles/externals/',
49+
'anti-forgery:': '../../../../shared/anti-forgery/',
4950
},
5051
defaultExtension: 'js',
5152
map: {
53+
'anti-forgery': 'anti-forgery:fetch-override.js',
5254
'ts': 'npm:plugin-typescript/lib/plugin.js',
5355
'typescript': 'npm:typescript/lib/typescript.js',
5456
'jszip': 'npm:jszip/dist/jszip.min.js',

apps/demos/configs/ReactJs/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,11 @@ window.config = {
4646
'npm:': '../../../../node_modules/',
4747
'bundles:': '../../../../bundles/',
4848
'externals:': '../../../../bundles/externals/',
49+
'anti-forgery:': '../../../../shared/anti-forgery/',
4950
},
5051
defaultExtension: 'js',
5152
map: {
53+
'anti-forgery': 'anti-forgery:fetch-override.js',
5254
'ts': 'npm:plugin-typescript/lib/plugin.js',
5355
'typescript': 'npm:typescript/lib/typescript.js',
5456
'jszip': 'npm:jszip/dist/jszip.min.js',

apps/demos/configs/Vue/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ window.config = {
4444
'npm:': '../../../../node_modules/',
4545
'bundles:': '../../../../bundles/',
4646
'externals:': '../../../../bundles/externals/',
47+
'anti-forgery:': '../../../../shared/anti-forgery/',
4748
},
4849
map: {
50+
'anti-forgery': 'anti-forgery:fetch-override.js',
4951
'vue': 'npm:vue/dist/vue.esm-browser.js',
5052
'@vue/shared': 'npm:@vue/shared/dist/shared.cjs.prod.js',
5153
'vue-loader': 'npm:dx-systemjs-vue-browser/index.js',
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import ajax from 'devextreme/core/utils/ajax';
2+
import { Deferred } from 'devextreme/core/utils/deferred';
3+
4+
const sendRequestOrig = ajax.sendRequest;
5+
const fetchOrig = fetch;
6+
let antiForgeryGettingPromise = null;
7+
8+
async function fetchAntiForgeryToken() {
9+
try {
10+
const response = await fetchOrig('https://js.devexpress.com/Demos/NetCore/api/Common/GetAntiForgeryToken', {
11+
method: 'GET',
12+
credentials: 'include',
13+
cache: 'no-cache',
14+
});
15+
16+
if (!response.ok) {
17+
const errorMessage = await response.text();
18+
throw new Error(`Failed to retrieve anti-forgery token: ${errorMessage || response.statusText}`);
19+
}
20+
21+
return await response.json();
22+
} catch (error) {
23+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
24+
throw new Error(errorMessage);
25+
}
26+
}
27+
28+
async function getAntiForgeryTokenValue() {
29+
const tokenMeta = document.querySelector('meta[name="csrf-token"]');
30+
31+
if (tokenMeta) {
32+
const headerName = tokenMeta.dataset.headerName || 'RequestVerificationToken';
33+
const token = tokenMeta.getAttribute('content') || '';
34+
35+
return Promise.resolve({ headerName, token });
36+
}
37+
38+
if (!antiForgeryGettingPromise) {
39+
antiForgeryGettingPromise = fetchAntiForgeryToken();
40+
}
41+
42+
const tokenData = await antiForgeryGettingPromise;
43+
const meta = document.createElement('meta');
44+
45+
meta.name = 'csrf-token';
46+
meta.content = tokenData.token;
47+
meta.dataset.headerName = tokenData.headerName;
48+
document.head.appendChild(meta);
49+
antiForgeryGettingPromise = null;
50+
51+
return tokenData;
52+
}
53+
54+
ajax.sendRequest = (options) => {
55+
const deferred = typeof Deferred !== 'undefined' ? new Deferred() : (() => {
56+
let resolve;
57+
let reject;
58+
// eslint-disable-next-line spellcheck/spell-checker
59+
const promise = new Promise((res, rej) => { resolve = res; reject = rej; });
60+
return { promise: () => promise, resolve, reject };
61+
})();
62+
63+
getAntiForgeryTokenValue().then(({ headerName, token }) => {
64+
options.headers = {
65+
[headerName]: token,
66+
...(options.headers || {}),
67+
};
68+
69+
options.xhrFields = {
70+
withCredentials: true,
71+
};
72+
73+
sendRequestOrig(options).then(
74+
(result) => {
75+
deferred.resolve(result);
76+
if (result.success) {
77+
deferred.resolve(result);
78+
} else {
79+
deferred.reject(result);
80+
}
81+
},
82+
(e) => deferred.reject(e),
83+
);
84+
});
85+
86+
return deferred.promise();
87+
};
88+
89+
window.fetch = async (url, options = {}) => {
90+
const { headerName, token } = await getAntiForgeryTokenValue();
91+
92+
options.headers = {
93+
[headerName]: token,
94+
...(options.headers || {}),
95+
};
96+
97+
options.credentials = 'include';
98+
99+
return fetchOrig(url, options);
100+
};

0 commit comments

Comments
 (0)