2018-03-26 00:46:45 +05:30
|
|
|
// @flow
|
2017-06-08 00:10:44 +05:30
|
|
|
/* eslint camelcase: off */
|
2018-05-05 14:31:25 +05:30
|
|
|
import type { ApplicationType } from 'components/dev/apps';
|
2016-07-27 23:57:21 +05:30
|
|
|
import request from 'services/request';
|
|
|
|
|
2019-06-30 19:02:50 +05:30
|
|
|
export type Scope =
|
2019-11-27 14:33:32 +05:30
|
|
|
| 'minecraft_server_session'
|
|
|
|
| 'offline_access'
|
|
|
|
| 'account_info'
|
|
|
|
| 'account_email';
|
2019-06-30 19:02:50 +05:30
|
|
|
|
|
|
|
export type Client = {|
|
2019-11-27 14:33:32 +05:30
|
|
|
id: string,
|
|
|
|
name: string,
|
|
|
|
description: string,
|
2019-06-30 19:02:50 +05:30
|
|
|
|};
|
|
|
|
|
2018-03-26 00:46:45 +05:30
|
|
|
export type OauthAppResponse = {
|
2019-11-27 14:33:32 +05:30
|
|
|
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,
|
2018-03-26 00:46:45 +05:30
|
|
|
};
|
|
|
|
|
2018-05-03 10:45:09 +05:30
|
|
|
type OauthRequestData = {
|
2019-11-27 14:33:32 +05:30
|
|
|
client_id: string,
|
|
|
|
redirect_uri: string,
|
|
|
|
response_type: string,
|
|
|
|
description: string,
|
|
|
|
scope: Scope,
|
|
|
|
prompt: string,
|
|
|
|
login_hint?: string,
|
|
|
|
state?: string,
|
2018-05-03 10:45:09 +05:30
|
|
|
};
|
|
|
|
|
|
|
|
export type OauthData = {
|
2019-11-27 14:33:32 +05:30
|
|
|
clientId: string,
|
|
|
|
redirectUrl: string,
|
|
|
|
responseType: string,
|
|
|
|
description: string,
|
|
|
|
scope: Scope,
|
|
|
|
prompt: 'none' | 'consent' | 'select_account',
|
|
|
|
loginHint?: string,
|
|
|
|
state?: string,
|
2018-05-03 10:45:09 +05:30
|
|
|
};
|
|
|
|
|
2018-03-26 00:46:45 +05:30
|
|
|
type FormPayloads = {
|
2019-11-27 14:33:32 +05:30
|
|
|
name?: string,
|
|
|
|
description?: string,
|
|
|
|
websiteUrl?: string,
|
|
|
|
redirectUri?: string,
|
|
|
|
minecraftServerIp?: string,
|
2018-03-26 00:46:45 +05:30
|
|
|
};
|
|
|
|
|
2018-11-10 14:33:47 +05:30
|
|
|
const api = {
|
2019-11-27 14:33:32 +05:30
|
|
|
validate(oauthData: OauthData) {
|
|
|
|
return request
|
|
|
|
.get<{|
|
|
|
|
session: {|
|
|
|
|
scopes: Scope[],
|
|
|
|
|},
|
|
|
|
client: Client,
|
|
|
|
oAuth: {||},
|
|
|
|
|}>('/api/oauth2/v1/validate', getOAuthRequest(oauthData))
|
|
|
|
.catch(handleOauthParamsValidation);
|
|
|
|
},
|
|
|
|
|
|
|
|
complete(
|
|
|
|
oauthData: OauthData,
|
|
|
|
params: { accept?: boolean } = {},
|
|
|
|
): Promise<{
|
|
|
|
success: boolean,
|
|
|
|
redirectUri: string,
|
|
|
|
}> {
|
|
|
|
const query = request.buildQuery(getOAuthRequest(oauthData));
|
|
|
|
|
|
|
|
return request
|
|
|
|
.post<{
|
|
|
|
success: boolean,
|
2018-05-03 10:45:09 +05:30
|
|
|
redirectUri: string,
|
2019-11-27 14:33:32 +05:30
|
|
|
}>(
|
|
|
|
`/api/oauth2/v1/complete?${query}`,
|
|
|
|
typeof params.accept === 'undefined' ? {} : { accept: params.accept },
|
|
|
|
)
|
|
|
|
.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: Object = new Error('Unauthorized');
|
|
|
|
error.unauthorized = true;
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (resp.statusCode === 401 && resp.error === 'accept_required') {
|
|
|
|
const error: Object = 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}`);
|
|
|
|
},
|
2016-07-27 23:57:21 +05:30
|
|
|
};
|
2018-11-10 14:33:47 +05:30
|
|
|
|
|
|
|
if (window.Cypress) {
|
2019-11-27 14:33:32 +05:30
|
|
|
window.oauthApi = api;
|
2018-11-10 14:33:47 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
export default api;
|
|
|
|
|
2016-08-23 10:00:06 +05:30
|
|
|
/**
|
|
|
|
* @param {object} oauthData
|
|
|
|
* @param {string} oauthData.clientId
|
|
|
|
* @param {string} oauthData.redirectUrl
|
|
|
|
* @param {string} oauthData.responseType
|
|
|
|
* @param {string} oauthData.description
|
|
|
|
* @param {string} oauthData.scope
|
|
|
|
* @param {string} oauthData.state
|
|
|
|
*
|
2019-11-27 14:33:32 +05:30
|
|
|
* @returns {object}
|
2016-08-23 10:00:06 +05:30
|
|
|
*/
|
2018-05-03 10:45:09 +05:30
|
|
|
function getOAuthRequest(oauthData: OauthData): OauthRequestData {
|
2019-11-27 14:33:32 +05:30
|
|
|
return {
|
|
|
|
client_id: oauthData.clientId,
|
|
|
|
redirect_uri: oauthData.redirectUrl,
|
|
|
|
response_type: oauthData.responseType,
|
|
|
|
description: oauthData.description,
|
|
|
|
scope: oauthData.scope,
|
|
|
|
prompt: oauthData.prompt,
|
|
|
|
login_hint: oauthData.loginHint,
|
|
|
|
state: oauthData.state,
|
|
|
|
};
|
2016-07-27 23:57:21 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
function handleOauthParamsValidation(resp = {}) {
|
2019-11-27 14:33:32 +05:30
|
|
|
if (resp.statusCode === 400 && resp.error === 'invalid_request') {
|
|
|
|
resp.userMessage = `Invalid request (${resp.parameter} required).`;
|
|
|
|
} else if (
|
|
|
|
resp.statusCode === 400 &&
|
|
|
|
resp.error === 'unsupported_response_type'
|
|
|
|
) {
|
|
|
|
resp.userMessage = `Invalid response type '${resp.parameter}'.`;
|
|
|
|
} else if (resp.statusCode === 400 && resp.error === 'invalid_scope') {
|
|
|
|
resp.userMessage = `Invalid scope '${resp.parameter}'.`;
|
|
|
|
} else if (resp.statusCode === 401 && resp.error === 'invalid_client') {
|
|
|
|
resp.userMessage = 'Can not find application you are trying to authorize.';
|
|
|
|
}
|
|
|
|
|
|
|
|
return Promise.reject(resp);
|
2016-07-27 23:57:21 +05:30
|
|
|
}
|