Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,5 @@ NEXT_PUBLIC_FT_ACTIVITIES=true
SENTRY_DSN=
NEXT_PUBLIC_SENTRY_DSN=

#NEXT_PUBLIC_ASKTUG_PROXY_BASE_URL=https://community-preview.tidb.net/_asktug
NEXT_PUBLIC_ASKTUG_PROXY_BASE_URL=http://127.0.0.1:3100/_asktug
NEXT_PUBLIC_ASKTUG_WEBSITE_BASE_URL=https://community-preview.asktug.com
NEXT_PUBLIC_ASKTUG_PROXY_BASE_URL=https://community-preview.tidb.net/_asktug
NEXT_PUBLIC_ASKTUG_WEBSITE_BASE_URL=https://new.asktug.com
8 changes: 4 additions & 4 deletions src/api/asktug/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,10 @@ export async function getSummaryByUsername(
const { username } = input;
const url = `${askTugApiDomain}/u/${encodeURIComponent(username)}/summary.json`;
try {
const result: IProfileSummary = await asktugClient.get(
url,
withAccountsCookies({ isReturnErrorResponse: true }, ssrCtx)
);
const result: IProfileSummary = await asktugClient.get(url, {
isReturnErrorResponse: true,
ssrCtx,
});
return result ?? null;
} catch (response) {
if (response?.status && response.status === 404) {
Expand Down
8 changes: 6 additions & 2 deletions src/api/clients/asktugClient.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import axios from 'axios';
import { dispatchApiError } from './events';
import { applyDebugInterceptor } from './interceptors/debug';
import { passThroughCookies } from '~/api/clients/interceptors/ssr';

const isDispatchGlobalApiError = (status) => {
return ![400, 409, 428].includes(status);
Expand All @@ -11,6 +13,7 @@ const asktugClient = axios.create({
headers: {
accept: 'application/json',
},
passThroughCookies: 'asktug',
isDispatchApiError({ status }) {
return status !== 404;
},
Expand All @@ -21,15 +24,16 @@ const asktugClient = axios.create({
// }, error => {
// return Promise.reject(error);
// });
axios.interceptors.request.use(passThroughCookies);
applyDebugInterceptor(asktugClient);

asktugClient.interceptors.response.use(
({ data }) => {
return data;
},
(err) => {
const { config, response } = err;

console.error(response?.status ?? 'unknown', config.url);

// Some errors may not have response, like the timeout error
if (!response) {
dispatchApiError(err);
Expand Down
6 changes: 6 additions & 0 deletions src/api/clients/blogClient.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import axios from 'axios';
import { dispatchApiError } from './events';
import { applyDebugInterceptor } from './interceptors/debug';
import { passThroughCookies } from '~/api/clients/interceptors/ssr';

const isDispatchGlobalApiError = (status) => {
return ![400, 409, 428].includes(status);
Expand All @@ -11,13 +13,17 @@ const blogClient = axios.create({
headers: {
accept: 'application/json',
},
passThroughCookies: 'blog',
});
// axios.interceptors.request.use((config) => {
// console.log('request params:', config);
// return config;
// }, error => {
// return Promise.reject(error);
// });
axios.interceptors.request.use(passThroughCookies);
applyDebugInterceptor(blogClient);

blogClient.interceptors.response.use(
({ data }) => {
return data;
Expand Down
6 changes: 6 additions & 0 deletions src/api/clients/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { createCaptchaInterceptor } from '@tidb-community/common/utils/axios';
import { getCaptchaToken } from '@tidb-community/common/utils/form';

import { dispatchApiError } from './events';
import { applyDebugInterceptor } from './interceptors/debug';
import { passThroughCookies } from '~/api/clients/interceptors/ssr';

const CSRF_MSG = 'CSRF Failed: CSRF token missing or incorrect.';

Expand All @@ -14,8 +16,10 @@ const isDispatchGlobalApiError = (status) => {
const client = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_BASE_URL ?? '',
withCredentials: true,
passThroughCookies: 'accounts',
});

axios.interceptors.request.use(passThroughCookies);
client.interceptors.request.use((config) => {
const csrftoken = Cookie.get('csrftoken');

Expand All @@ -33,6 +37,8 @@ client.interceptors.request.use((config) => {
return config;
});

applyDebugInterceptor(client);

client.interceptors.response.use(
({ data }) => data,
(err) => {
Expand Down
6 changes: 5 additions & 1 deletion src/api/clients/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { AxiosInstance, AxiosResponse } from 'axios';
import _asktugClient from './asktugClient';
import _blogClient from './blogClient';
import _client from './client';
import _nextClient from './nextClient';
import { GetServerSidePropsContext } from 'next';

declare module 'axios' {
export interface AxiosRequestConfig {
isDispatchApiError?(res: AxiosResponse): boolean;
isReturnErrorResponse?: boolean;
fallbackResponse?: any;
ssrCtx?: GetServerSidePropsContext;
passThroughCookies?: 'accounts' | 'asktug' | 'blog';
}
}

export { default as asktugClient } from './asktugClient';
export const asktugClient: AxiosInstance = _asktugClient;
export const blogClient: AxiosInstance = _blogClient;
export const nextClient: AxiosInstance = _nextClient;
export const client: AxiosInstance = _client;
32 changes: 32 additions & 0 deletions src/api/clients/interceptors/debug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { AxiosError, AxiosInstance, AxiosResponse } from 'axios';

function isAxiosError(error: unknown): error is AxiosError {
return error && typeof error === 'object' && (error as AxiosError).isAxiosError;
}

export function debugResponseInterceptor(response: AxiosResponse): AxiosResponse {
// eslint-disable-next-line no-console
console.debug('[axios:debug:success]', response.status, response.config.method, response.request.path);
return response;
}

export function debugErrorResponseInterceptor(error: unknown) {
if (!error) {
throw error;
}
if (isAxiosError(error)) {
let errorPrefix = `[axios:debug:error]`;
if (error.config.ssrCtx) {
errorPrefix += ' at ' + error.config.ssrCtx.resolvedUrl + ':';
}
console.error(errorPrefix, error.response.status, error.config.method, error.response.request.path);
}
throw error;
}

export function applyDebugInterceptor(client: AxiosInstance) {
if (process.env.NODE_ENV === 'development' || process.env.AXIOS_DEBUG === 'true') {
client.interceptors.response.use(debugResponseInterceptor);
}
client.interceptors.response.use(undefined, debugErrorResponseInterceptor);
}
31 changes: 31 additions & 0 deletions src/api/clients/interceptors/ssr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { AxiosRequestConfig } from 'axios';

const SITE_COOKIES = {
accounts: ['uid', 'dev_sid', 'ssid', '_t'],
asktug: ['uid', 'dev_sid', 'ssid', '_t'],
blog: ['uid', 'dev_sid', 'ssid', 'JSESSIONID'],
};

export function passThroughCookies(config: AxiosRequestConfig): AxiosRequestConfig {
const { passThroughCookies, ssrCtx } = config;
if (!passThroughCookies || !ssrCtx) {
return config;
}

const cookies = ssrCtx.req.cookies;
const headers = (config.headers = config.headers || {});

if (headers.cookie) {
headers.cookie += ';';
} else {
headers.cookie = '';
}

headers.cookie += SITE_COOKIES[passThroughCookies]
.map((name) => [name, cookies[name]])
.filter(([, value]) => value)
.map(([name, value]) => `${name}=${encodeURIComponent(value)}`)
.join(';');

return config;
}
2 changes: 1 addition & 1 deletion src/pages/u/[username]/answer/[[...status]].page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const getServerSideProps: GetServerSideProps<IProps, IQuery> = async (ctx
getI18nProps(['common'])(ctx),
getBadgesByUsername({ username }),
getUserProfileByUsername({ username }),
getSummaryByUsername({ username }),
getSummaryByUsername({ username }, ctx),
getAnswersByUsername({ pageNumber: pageNumber + 1, pageSize, username, markedSolution }),
getPostsNumberByUsername({ username }),
getPostFavoritesNumberByUsername({ username }),
Expand Down