Skip to content

Commit

Permalink
feat(desktop): add appToken for providers & fix ssr error
Browse files Browse the repository at this point in the history
  • Loading branch information
xudaotutou committed Mar 7, 2024
1 parent b766fb5 commit 97e0752
Show file tree
Hide file tree
Showing 14 changed files with 72 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ describe('invite member', () => {
role
});
console.log(res);
console.log(ns)
console.log(payload1)
console.log(ns);
console.log(payload1);
expect(res.code).toBe(200);
setAuth(token2);
const res2 = await verifyInviteRequest({ action: reciveAction.Accepte, ns_uid });
Expand Down
4 changes: 3 additions & 1 deletion frontend/desktop/src/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { AxiosHeaders, AxiosHeaderValue, type AxiosInstance } from 'axios';
import useSessionStore from '@/stores/session';

export const _getRegionToken = (request: AxiosInstance) => () =>
request.post<any, ApiResp<{ token: string; kubeconfig: string }>>('/api/auth/regionToken');
request.post<any, ApiResp<{ token: string; kubeconfig: string; appToken: string }>>(
'/api/auth/regionToken'
);

export const getRegionToken = _getRegionToken(request);
export const _passwordExistRequest = (request: AxiosInstance) => (data: { user: string }) =>
Expand Down
9 changes: 6 additions & 3 deletions frontend/desktop/src/api/namespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,12 @@ export const _teamDetailsRequest = (request: AxiosInstance) => (ns_uid: string)
export const _reciveMessageRequest = (request: AxiosInstance) => () =>
request.post<any, ApiResp<{ messages: teamMessageDto[] }>>('/api/auth/namespace/recive');
export const _switchRequest = (request: AxiosInstance) => (ns_uid: string) =>
request.post<any, ApiResp<{ token: string; kubeconfig: string }>>('/api/auth/namespace/switch', {
ns_uid
});
request.post<any, ApiResp<{ token: string; kubeconfig: string; appToken: string }>>(
'/api/auth/namespace/switch',
{
ns_uid
}
);
// 提供给prod/dev环境使用
export const abdicateRequest = _abdicateRequest(request);
export const createRequest = _createRequest(request);
Expand Down
19 changes: 4 additions & 15 deletions frontend/desktop/src/components/account/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { CopyIcon, DownloadIcon, LogoutIcon, RightArrowIcon } from '@sealos/ui';
import { ImageFallBackUrl } from '@/stores/config';
import { jwtDecode } from 'jwt-decode';
import { AccessTokenPayload } from '@/types/token';
import { sessionConfig } from '@/utils/sessionConfig';

const NsMenu = () => {
const { t } = useTranslation();
Expand All @@ -46,21 +47,9 @@ const NsMenu = () => {
mutationFn: switchRequest,
async onSuccess(data) {
if (data.code === 200 && !!data.data) {
setToken(data.data.token);
const payload = jwtDecode<AccessTokenPayload>(data.data.token);
if (session) {
setSession({
...session,
user: {
...session.user,
nsid: payload.workspaceId,
ns_uid: payload.workspaceUid
},
kubeconfig: data.data.kubeconfig
});
} else {
throw Error('session in invalid');
}
await sessionConfig(data.data);
} else {
throw Error('session in invalid');
}
}
});
Expand Down
21 changes: 2 additions & 19 deletions frontend/desktop/src/components/signin/auth/usePassword.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { jwtDecode } from 'jwt-decode';
import { AccessTokenPayload } from '@/types/token';
import { sessionConfig } from '@/utils/sessionConfig';

export default function usePassword({
showError
Expand Down Expand Up @@ -53,25 +54,7 @@ export default function usePassword({
inviterId
});
if (!!result?.data) {
const regionUserToken = result.data.token;
setToken(regionUserToken);
const infoData = await UserInfo();
const payload = jwtDecode<AccessTokenPayload>(regionUserToken);
setSession({
token: regionUserToken,
user: {
k8s_username: payload.userCrName,
name: infoData.data?.info.nickname || '',
avatar: infoData.data?.info.avatarUri || '',
nsid: payload.workspaceId,
ns_uid: payload.workspaceUid,
userCrUid: payload.userCrUid,
userUid: payload.userUid,
userId: payload.userId
},
// @ts-ignore
kubeconfig: result.data.kubeconfig
});
await sessionConfig(result.data);
await router.replace('/');
}
return;
Expand Down
20 changes: 2 additions & 18 deletions frontend/desktop/src/components/signin/auth/useSms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { getRegionToken, UserInfo } from '@/api/auth';
import { jwtDecode } from 'jwt-decode';
import { uploadConvertData } from '@/api/platform';
import { AccessTokenPayload } from '@/types/token';
import { sessionConfig } from '@/utils/sessionConfig';

export default function useSms({
showError
Expand Down Expand Up @@ -61,24 +62,7 @@ export default function useSms({
setToken(globalToken);
const regionTokenRes = await getRegionToken();
if (regionTokenRes?.data) {
const regionUserToken = regionTokenRes.data.token;
setToken(regionUserToken);
const infoData = await UserInfo();
const payload = jwtDecode<AccessTokenPayload>(regionUserToken);
setSession({
token: regionUserToken,
user: {
k8s_username: payload.userCrName,
name: infoData.data?.info.nickname || '',
avatar: infoData.data?.info.avatarUri || '',
nsid: payload.workspaceId,
ns_uid: payload.workspaceUid,
userCrUid: payload.userCrUid,
userId: payload.userId,
userUid: payload.userUid
},
kubeconfig: regionTokenRes.data.kubeconfig
});
await sessionConfig(regionTokenRes.data);
uploadConvertData([3]).then(
(res) => {
console.log(res);
Expand Down
17 changes: 7 additions & 10 deletions frontend/desktop/src/pages/api/auth/namespace/switch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { getUserKubeconfig } from '@/services/backend/kubernetes/admin';
import { switchKubeconfigNamespace } from '@/services/backend/kubernetes/user';
import { validate } from 'uuid';
import { JoinStatus } from 'prisma/region/generated/client';
import { generateAccessToken, verifyAccessToken } from '@/services/backend/auth';
import { generateAccessToken, generateAppToken, verifyAccessToken } from '@/services/backend/auth';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
Expand All @@ -26,30 +26,27 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
userCr: true
}
});
const curWorkspaceItem = queryResults.find(
(item) => item.workspace.uid === payload.workspaceUid
);
if (!curWorkspaceItem)
return jsonRes(res, { code: 403, message: 'You are not in this workspace' });
const newWorkspaceItem = queryResults.find((item) => item.workspace.uid === ns_uid);
if (!newWorkspaceItem)
return jsonRes(res, { code: 403, message: 'You are not in this workspace' });
const oldKcRaw = await getUserKubeconfig(payload.userCrUid, payload.userCrName);
if (!oldKcRaw) return jsonRes(res, { code: 404, message: 'The kubeconfig is not found' });
const kubeconfig = switchKubeconfigNamespace(oldKcRaw, newWorkspaceItem.workspace.id);

const token = generateAccessToken({
const jwtPayload = {
workspaceUid: newWorkspaceItem.workspaceUid,
workspaceId: newWorkspaceItem.workspace.id,
regionUid: payload.regionUid,
userCrUid: payload.userCrUid,
userCrName: payload.userCrName,
userId: payload.userId,
userUid: payload.userUid
});
};
const token = generateAccessToken(jwtPayload);
const appToken = generateAppToken(jwtPayload);
const data = {
token,
kubeconfig
kubeconfig,
appToken
};
return jsonRes(res, {
data,
Expand Down
20 changes: 2 additions & 18 deletions frontend/desktop/src/pages/callback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { jwtDecode } from 'jwt-decode';
import { isString } from 'lodash';
import { getRegionToken, UserInfo } from '@/api/auth';
import { AccessTokenPayload } from '@/types/token';
import { sessionConfig } from '@/utils/sessionConfig';

const Callback: NextPage = () => {
const router = useRouter();
Expand Down Expand Up @@ -70,24 +71,7 @@ const Callback: NextPage = () => {
setToken(token);
const regionTokenRes = await getRegionToken();
if (regionTokenRes?.data) {
const regionUserToken = regionTokenRes.data.token;
setToken(regionUserToken);
const infoData = await UserInfo();
const payload = jwtDecode<AccessTokenPayload>(regionUserToken);
setSession({
token: regionUserToken,
user: {
k8s_username: payload.userCrName,
name: infoData.data?.info.nickname || '',
avatar: infoData.data?.info.avatarUri || '',
nsid: payload.workspaceId,
ns_uid: payload.workspaceUid,
userCrUid: payload.userCrUid,
userUid: payload.userUid,
userId: payload.userId
},
kubeconfig: regionTokenRes.data.kubeconfig
});
await sessionConfig(regionTokenRes.data);
uploadConvertData([3]).then(
(res) => {
console.log(res);
Expand Down
28 changes: 2 additions & 26 deletions frontend/desktop/src/pages/switchRegion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { getRegionToken, UserInfo } from '@/api/auth';
import { isString } from 'lodash';
import { jwtDecode } from 'jwt-decode';
import { AccessTokenPayload } from '@/types/token';
import { sessionConfig } from '@/utils/sessionConfig';

const Callback: NextPage = () => {
const router = useRouter();
Expand All @@ -28,32 +29,7 @@ const Callback: NextPage = () => {
setToken(globalToken);
const regionTokenRes = await getRegionToken();
if (regionTokenRes?.data) {
const regionUserToken = regionTokenRes.data.token;
setToken(regionUserToken);
const infoData = await UserInfo();
const payload = jwtDecode<AccessTokenPayload>(regionUserToken);
setSession({
token: regionUserToken,
user: {
k8s_username: payload.userCrName,
name: infoData.data?.info.nickname || '',
avatar: infoData.data?.info.avatarUri || '',
nsid: payload.workspaceId,
ns_uid: payload.workspaceUid,
userCrUid: payload.userCrUid,
userId: payload.userId,
userUid: payload.userUid
},
kubeconfig: regionTokenRes.data.kubeconfig
});
uploadConvertData([3]).then(
(res) => {
console.log(res);
},
(err) => {
console.log(err);
}
);
await sessionConfig(regionTokenRes.data);
await router.replace('/');
return;
} else {
Expand Down
4 changes: 3 additions & 1 deletion frontend/desktop/src/services/backend/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getRegionUid } from '@/services/enable';

const jwtSecret = (process.env.JWT_SECRET as string) || '123456789';
const regionJwtSecret = process.env.JWT_SECRET_REGION || '123456789';
const appJwtSecret = process.env.JWT_SECRET_APP || '123456789';
const verifyToken = async <T extends Object>(header: IncomingHttpHeaders) => {
try {
if (!header?.authorization) {
Expand Down Expand Up @@ -60,6 +61,7 @@ export const verifyJWT = <T extends Object = JWTPayload>(token?: string, secret?
});
export const generateAccessToken = (props: AccessTokenPayload) =>
sign(props, jwtSecret, { expiresIn: '7d' });

export const generateAppToken = (props: AccessTokenPayload) =>
sign(props, appJwtSecret, { expiresIn: '300000' });
export const generateAuthenticationToken = (props: AuthenticationTokenPayload) =>
sign(props, regionJwtSecret, { expiresIn: '60000' });
28 changes: 4 additions & 24 deletions frontend/desktop/src/services/backend/regionAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { customAlphabet } from 'nanoid';
import { retrySerially } from '@/utils/tools';
import { AccessTokenPayload } from '@/types/token';
import { JoinStatus, Role } from 'prisma/region/generated/client';
import { generateAccessToken } from '@/services/backend/auth';
import { generateAccessToken, generateAppToken } from '@/services/backend/auth';

const LetterBytes = 'abcdefghijklmnopqrstuvwxyz0123456789';
const HostnameLength = 8;
Expand Down Expand Up @@ -35,6 +35,7 @@ export async function getRegionToken({
}): Promise<{
kubeconfig: string;
token: string;
appToken: string;
}> {
const region = await globalPrisma.region.findUnique({
where: {
Expand Down Expand Up @@ -141,28 +142,7 @@ export async function getRegionToken({

return {
kubeconfig,
token: generateAccessToken(payload)
token: generateAccessToken(payload),
appToken: generateAppToken(payload)
};
}

export function verifyK8sUser({
workspaceUid,
userCrUid
}: {
workspaceUid: string;
userCrUid: string;
}) {
return prisma.userWorkspace
.findUnique({
where: {
workspaceUid_userCrUid: {
userCrUid,
workspaceUid
}
}
})
.then(
(result) => !!result,
() => false
);
}
33 changes: 33 additions & 0 deletions frontend/desktop/src/utils/sessionConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { UserInfo } from '@/api/auth';
import { jwtDecode } from 'jwt-decode';
import { AccessTokenPayload } from '@/types/token';
import useSessionStore from '@/stores/session';

export const sessionConfig = async ({
token,
kubeconfig,
appToken
}: {
token: string;
kubeconfig: string;
appToken: string;
}) => {
const store = useSessionStore.getState();
store.setToken(token);
const infoData = await UserInfo();
const payload = jwtDecode<AccessTokenPayload>(token);
store.setSession({
token: appToken,
user: {
k8s_username: payload.userCrName,
name: infoData.data?.info.nickname || '',
avatar: infoData.data?.info.avatarUri || '',
nsid: payload.workspaceId,
ns_uid: payload.workspaceUid,
userCrUid: payload.userCrUid,
userId: payload.userId,
userUid: payload.userUid
},
kubeconfig
});
};
1 change: 1 addition & 0 deletions frontend/packages/client-sdk/src/master.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class MasterSDK {
avatar: session.user.avatar,
nsid: session.user.nsid
},
token: session.token,
kubeconfig: session.kubeconfig
};
}
Expand Down
4 changes: 1 addition & 3 deletions frontend/packages/client-sdk/src/types/user.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ export type KubeConfig = string;

export type Session = {
token: string; // jwt token
// 提供一些简单的信息
user: UserInfo;
// 帮忙导出用的
kubeconfig: KubeConfig;
};

Expand All @@ -39,7 +37,7 @@ export type UserInfoV1 = Readonly<{
}>;

export type SessionV1 = {
token?: OAuthToken;
token?: string;
user: UserInfoV1;
kubeconfig: KubeConfig;
};

0 comments on commit 97e0752

Please sign in to comment.