mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-12-26 15:00:23 +05:30
171 lines
5.1 KiB
TypeScript
171 lines
5.1 KiB
TypeScript
import { ApplicationType } from 'app/components/dev/apps';
|
|
import request from 'app/services/request';
|
|
|
|
export type Scope = 'minecraft_server_session' | 'offline_access' | 'account_info' | 'account_email';
|
|
|
|
export interface Client {
|
|
id: string;
|
|
name: string;
|
|
description: string;
|
|
}
|
|
|
|
export interface OauthAppResponse {
|
|
clientId: string;
|
|
clientSecret: string;
|
|
type: ApplicationType;
|
|
name: string;
|
|
websiteUrl: string;
|
|
createdAt: number;
|
|
// fields for 'application' type
|
|
countUsers?: number;
|
|
description?: string;
|
|
redirectUri?: string;
|
|
// fields for 'minecraft-server' type
|
|
minecraftServerIp?: string;
|
|
}
|
|
|
|
interface AuthCodeFlowRequestData {
|
|
client_id: string;
|
|
redirect_uri: string;
|
|
response_type: string;
|
|
scope: string;
|
|
state?: string;
|
|
}
|
|
|
|
interface DeviceCodeFlowRequestData {
|
|
user_code: string;
|
|
}
|
|
|
|
export type OauthRequestData = (AuthCodeFlowRequestData | DeviceCodeFlowRequestData) & {
|
|
description?: string;
|
|
};
|
|
|
|
export interface OAuthValidateResponse {
|
|
session: {
|
|
scopes: Scope[];
|
|
};
|
|
client: Client;
|
|
}
|
|
|
|
interface FormPayloads {
|
|
name?: string;
|
|
description?: string;
|
|
websiteUrl?: string;
|
|
redirectUri?: string;
|
|
minecraftServerIp?: string;
|
|
}
|
|
|
|
const api = {
|
|
validate(oauthData: OauthRequestData) {
|
|
return request
|
|
.get<OAuthValidateResponse>('/api/oauth2/v1/validate', oauthData)
|
|
.catch(handleOauthParamsValidation);
|
|
},
|
|
|
|
complete(
|
|
oauthData: OauthRequestData,
|
|
params: { accept?: boolean } = {},
|
|
): Promise<{
|
|
success: boolean;
|
|
redirectUri?: string;
|
|
}> {
|
|
const data: Record<string, any> = {};
|
|
|
|
if (typeof params.accept !== 'undefined') {
|
|
data.accept = params.accept;
|
|
}
|
|
|
|
return request
|
|
.post<{
|
|
success: boolean;
|
|
redirectUri: string;
|
|
}>(`/api/oauth2/v1/complete?${request.buildQuery(oauthData)}`, data)
|
|
.catch((resp = {}) => {
|
|
if (resp.statusCode === 401 && resp.error === 'access_denied') {
|
|
// user declined permissions
|
|
return {
|
|
success: false,
|
|
redirectUri: resp.redirectUri,
|
|
originalResponse: resp.originalResponse,
|
|
};
|
|
}
|
|
|
|
if (resp.status === 401 && resp.name === 'Unauthorized') {
|
|
const error: { [key: string]: any } = new Error('Unauthorized');
|
|
error.unauthorized = true;
|
|
throw error;
|
|
}
|
|
|
|
if (resp.statusCode === 401 && resp.error === 'accept_required') {
|
|
const error: { [key: string]: any } = new Error('Permissions accept required');
|
|
error.acceptRequired = true;
|
|
throw error;
|
|
}
|
|
|
|
return handleOauthParamsValidation(resp);
|
|
});
|
|
},
|
|
|
|
create(type: string, formParams: FormPayloads) {
|
|
return request.post<{ success: boolean; data: OauthAppResponse }>(`/api/v1/oauth2/${type}`, formParams);
|
|
},
|
|
|
|
update(clientId: string, formParams: FormPayloads) {
|
|
return request.put<{ success: boolean; data: OauthAppResponse }>(`/api/v1/oauth2/${clientId}`, formParams);
|
|
},
|
|
|
|
getApp(clientId: string) {
|
|
return request.get<OauthAppResponse>(`/api/v1/oauth2/${clientId}`);
|
|
},
|
|
|
|
getAppsByUser(userId: number): Promise<OauthAppResponse[]> {
|
|
return request.get(`/api/v1/accounts/${userId}/oauth2/clients`);
|
|
},
|
|
|
|
reset(clientId: string, regenerateSecret: boolean = false) {
|
|
return request.post<{ success: boolean; data: OauthAppResponse }>(
|
|
`/api/v1/oauth2/${clientId}/reset${regenerateSecret ? '?regenerateSecret' : ''}`,
|
|
);
|
|
},
|
|
|
|
delete(clientId: string) {
|
|
return request.delete<{ success: boolean }>(`/api/v1/oauth2/${clientId}`);
|
|
},
|
|
};
|
|
|
|
if ('Cypress' in window) {
|
|
(window as any).oauthApi = api;
|
|
}
|
|
|
|
export default api;
|
|
|
|
function handleOauthParamsValidation(
|
|
resp:
|
|
| Record<string, any>
|
|
| {
|
|
statusCode: number;
|
|
success: false;
|
|
error:
|
|
| 'invalid_request'
|
|
| 'unsupported_response_type'
|
|
| 'invalid_scope'
|
|
| 'invalid_client'
|
|
| 'invalid_user_code';
|
|
parameter: string;
|
|
} = {},
|
|
) {
|
|
let userMessage: string | null = null;
|
|
|
|
if (resp.statusCode === 400 && resp.error === 'invalid_request') {
|
|
userMessage = `Invalid request (${resp.parameter} required).`;
|
|
} else if (resp.statusCode === 400 && resp.error === 'unsupported_response_type') {
|
|
userMessage = `Invalid response type '${resp.parameter}'.`;
|
|
} else if (resp.statusCode === 400 && resp.error === 'invalid_scope') {
|
|
userMessage = `Invalid scope '${resp.parameter}'.`;
|
|
} else if (resp.statusCode === 401 && resp.error === 'invalid_client') {
|
|
userMessage = 'Can not find application you are trying to authorize.';
|
|
}
|
|
|
|
return userMessage ? Promise.reject({ ...resp, userMessage }) : Promise.reject(resp);
|
|
}
|