bigbuffet-rw/app/soapbox/actions/auth.js

292 lines
9.3 KiB
JavaScript
Raw Normal View History

2020-04-04 13:28:57 -07:00
import api from '../api';
2020-05-29 07:55:38 -07:00
import { showAlert } from 'soapbox/actions/alerts';
2020-05-28 15:52:07 -07:00
import { fetchMe } from 'soapbox/actions/me';
2020-04-04 13:28:57 -07:00
2020-04-05 16:39:22 -07:00
export const AUTH_APP_CREATED = 'AUTH_APP_CREATED';
export const AUTH_APP_AUTHORIZED = 'AUTH_APP_AUTHORIZED';
export const AUTH_LOGGED_IN = 'AUTH_LOGGED_IN';
2020-04-11 12:41:13 -07:00
export const AUTH_LOGGED_OUT = 'AUTH_LOGGED_OUT';
2020-04-05 14:54:51 -07:00
2020-04-23 16:41:20 -07:00
export const AUTH_REGISTER_REQUEST = 'AUTH_REGISTER_REQUEST';
export const AUTH_REGISTER_SUCCESS = 'AUTH_REGISTER_SUCCESS';
export const AUTH_REGISTER_FAIL = 'AUTH_REGISTER_FAIL';
2020-05-24 16:22:36 -07:00
export const RESET_PASSWORD_REQUEST = 'RESET_PASSWORD_REQUEST';
export const RESET_PASSWORD_SUCCESS = 'RESET_PASSWORD_SUCCESS';
export const RESET_PASSWORD_FAIL = 'RESET_PASSWORD_FAIL';
export const CHANGE_EMAIL_REQUEST = 'CHANGE_EMAIL_REQUEST';
export const CHANGE_EMAIL_SUCCESS = 'CHANGE_EMAIL_SUCCESS';
export const CHANGE_EMAIL_FAIL = 'CHANGE_EMAIL_FAIL';
2020-07-20 13:23:38 -07:00
export const DELETE_ACCOUNT_REQUEST = 'DELETE_ACCOUNT_REQUEST';
export const DELETE_ACCOUNT_SUCCESS = 'DELETE_ACCOUNT_SUCCESS';
export const DELETE_ACCOUNT_FAIL = 'DELETE_ACCOUNT_FAIL';
export const CHANGE_PASSWORD_REQUEST = 'CHANGE_PASSWORD_REQUEST';
export const CHANGE_PASSWORD_SUCCESS = 'CHANGE_PASSWORD_SUCCESS';
export const CHANGE_PASSWORD_FAIL = 'CHANGE_PASSWORD_FAIL';
2020-06-05 13:43:03 -07:00
export const FETCH_TOKENS_REQUEST = 'FETCH_TOKENS_REQUEST';
export const FETCH_TOKENS_SUCCESS = 'FETCH_TOKENS_SUCCESS';
export const FETCH_TOKENS_FAIL = 'FETCH_TOKENS_FAIL';
2020-06-05 13:54:09 -07:00
export const REVOKE_TOKEN_REQUEST = 'REVOKE_TOKEN_REQUEST';
export const REVOKE_TOKEN_SUCCESS = 'REVOKE_TOKEN_SUCCESS';
export const REVOKE_TOKEN_FAIL = 'REVOKE_TOKEN_FAIL';
2020-04-29 16:29:41 -07:00
const noOp = () => () => new Promise(f => f());
2020-04-29 12:07:22 -07:00
function createAppAndToken() {
return (dispatch, getState) => {
return dispatch(createApp()).then(() => {
return dispatch(createAppToken());
2020-04-29 12:07:22 -07:00
});
};
}
const appName = () => {
const timestamp = (new Date()).toISOString();
return `SoapboxFE_${timestamp}`; // TODO: Add commit hash
};
function createApp() {
2020-04-04 13:28:57 -07:00
return (dispatch, getState) => {
2020-04-29 12:07:22 -07:00
return api(getState, 'app').post('/api/v1/apps', {
client_name: appName(),
2020-04-04 13:28:57 -07:00
redirect_uris: 'urn:ietf:wg:oauth:2.0:oob',
2020-04-29 12:07:22 -07:00
scopes: 'read write follow push admin',
2020-04-04 13:28:57 -07:00
}).then(response => {
return dispatch(authAppCreated(response.data));
2020-04-29 12:07:22 -07:00
});
};
}
function createAppToken() {
2020-04-29 12:07:22 -07:00
return (dispatch, getState) => {
const app = getState().getIn(['auth', 'app']);
return api(getState, 'app').post('/oauth/token', {
2020-04-29 12:07:22 -07:00
client_id: app.get('client_id'),
client_secret: app.get('client_secret'),
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
grant_type: 'client_credentials',
2020-04-05 16:39:22 -07:00
}).then(response => {
return dispatch(authAppAuthorized(response.data));
2020-04-04 13:28:57 -07:00
});
2020-04-14 11:44:40 -07:00
};
2020-04-04 13:28:57 -07:00
}
function createUserToken(username, password) {
2020-04-04 13:28:57 -07:00
return (dispatch, getState) => {
2020-04-05 14:54:51 -07:00
const app = getState().getIn(['auth', 'app']);
return api(getState, 'app').post('/oauth/token', {
client_id: app.get('client_id'),
2020-04-05 16:39:22 -07:00
client_secret: app.get('client_secret'),
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
grant_type: 'password',
username: username,
password: password,
2020-04-29 17:38:24 -07:00
}).then(response => {
dispatch(authLoggedIn(response.data));
});
};
}
export function refreshUserToken() {
return (dispatch, getState) => {
const refreshToken = getState().getIn(['auth', 'user', 'refresh_token']);
const app = getState().getIn(['auth', 'app']);
if (!refreshToken) return dispatch(noOp());
return api(getState, 'app').post('/oauth/token', {
client_id: app.get('client_id'),
client_secret: app.get('client_secret'),
refresh_token: refreshToken,
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
grant_type: 'refresh_token',
}).then(response => {
dispatch(authLoggedIn(response.data));
});
};
}
2020-08-07 13:17:13 -07:00
export function otpVerify(code, mfa_token) {
return (dispatch, getState) => {
const app = getState().getIn(['auth', 'app']);
return api(getState, 'app').post('/oauth/mfa/challenge', {
client_id: app.get('client_id'),
client_secret: app.get('client_secret'),
mfa_token: mfa_token,
code: code,
challenge_type: 'totp',
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
}).then(response => {
dispatch(authLoggedIn(response.data));
});
};
}
export function logIn(username, password) {
return (dispatch, getState) => {
return dispatch(createAppAndToken()).then(() => {
return dispatch(createUserToken(username, password));
}).catch(error => {
2020-08-07 13:17:13 -07:00
if (error.response.data.error === 'mfa_required') {
throw error;
} else {
dispatch(showAlert('Login failed.', 'Invalid username or password.'));
}
2020-04-11 12:41:13 -07:00
throw error;
2020-04-04 13:28:57 -07:00
});
2020-04-14 11:44:40 -07:00
};
2020-04-04 13:28:57 -07:00
}
2020-04-05 14:54:51 -07:00
2020-04-11 12:41:13 -07:00
export function logOut() {
return (dispatch, getState) => {
dispatch({ type: AUTH_LOGGED_OUT });
dispatch(showAlert('Successfully logged out.', ''));
};
}
2020-04-23 16:41:20 -07:00
export function register(params) {
return (dispatch, getState) => {
const needsConfirmation = getState().getIn(['instance', 'pleroma', 'metadata', 'account_activation_required']);
const needsApproval = getState().getIn(['instance', 'approval_required']);
params.fullname = params.username;
2020-04-23 16:41:20 -07:00
dispatch({ type: AUTH_REGISTER_REQUEST });
2020-05-29 07:55:38 -07:00
return dispatch(createAppAndToken()).then(() => {
return api(getState, 'app').post('/api/v1/accounts', params);
}).then(response => {
2020-04-23 17:12:42 -07:00
dispatch({ type: AUTH_REGISTER_SUCCESS, token: response.data });
dispatch(authLoggedIn(response.data));
if (needsConfirmation) {
return dispatch(showAlert('', 'Check your email for further instructions.'));
} else if (needsApproval) {
return dispatch(showAlert('', 'Your account has been submitted for approval.'));
} else {
return dispatch(fetchMe());
}
2020-04-23 16:41:20 -07:00
}).catch(error => {
dispatch({ type: AUTH_REGISTER_FAIL, error });
2020-04-29 18:00:01 -07:00
throw error;
2020-04-23 16:41:20 -07:00
});
};
}
2020-04-23 18:48:25 -07:00
export function fetchCaptcha() {
return (dispatch, getState) => {
return api(getState).get('/api/pleroma/captcha');
};
}
2020-05-24 16:22:36 -07:00
export function resetPassword(nickNameOrEmail) {
return (dispatch, getState) => {
dispatch({ type: RESET_PASSWORD_REQUEST });
const params =
nickNameOrEmail.includes('@')
? { email: nickNameOrEmail }
: { nickname: nickNameOrEmail };
return api(getState).post('/auth/password', params).then(() => {
dispatch({ type: RESET_PASSWORD_SUCCESS });
}).catch(error => {
2020-05-24 17:37:15 -07:00
dispatch({ type: RESET_PASSWORD_FAIL, error });
throw error;
2020-05-24 16:22:36 -07:00
});
};
}
export function changeEmail(email, password) {
return (dispatch, getState) => {
dispatch({ type: CHANGE_EMAIL_REQUEST, email });
return api(getState).post('/api/pleroma/change_email', {
email,
password,
}).then(response => {
if (response.data.error) throw response.data.error; // This endpoint returns HTTP 200 even on failure
dispatch({ type: CHANGE_EMAIL_SUCCESS, email, response });
}).catch(error => {
dispatch({ type: CHANGE_EMAIL_FAIL, email, error, skipAlert: true });
throw error;
});
};
}
2020-07-20 13:23:38 -07:00
export function deleteAccount(password) {
return (dispatch, getState) => {
2020-07-20 13:23:38 -07:00
dispatch({ type: DELETE_ACCOUNT_REQUEST });
return api(getState).post('/api/pleroma/delete_account', {
password,
}).then(response => {
if (response.data.error) throw response.data.error; // This endpoint returns HTTP 200 even on failure
2020-07-20 13:23:38 -07:00
dispatch({ type: DELETE_ACCOUNT_SUCCESS, response });
dispatch({ type: AUTH_LOGGED_OUT });
2020-07-20 13:23:38 -07:00
dispatch(showAlert('Successfully logged out.', ''));
}).catch(error => {
2020-07-20 13:23:38 -07:00
dispatch({ type: DELETE_ACCOUNT_FAIL, error, skipAlert: true });
throw error;
});
};
}
export function changePassword(oldPassword, newPassword, confirmation) {
return (dispatch, getState) => {
dispatch({ type: CHANGE_PASSWORD_REQUEST });
return api(getState).post('/api/pleroma/change_password', {
password: oldPassword,
new_password: newPassword,
new_password_confirmation: confirmation,
}).then(response => {
if (response.data.error) throw response.data.error; // This endpoint returns HTTP 200 even on failure
dispatch({ type: CHANGE_PASSWORD_SUCCESS, response });
}).catch(error => {
dispatch({ type: CHANGE_PASSWORD_FAIL, error, skipAlert: true });
throw error;
});
};
}
2020-06-05 13:43:03 -07:00
export function fetchOAuthTokens() {
return (dispatch, getState) => {
dispatch({ type: FETCH_TOKENS_REQUEST });
return api(getState).get('/api/oauth_tokens.json').then(response => {
dispatch({ type: FETCH_TOKENS_SUCCESS, tokens: response.data });
}).catch(error => {
dispatch({ type: FETCH_TOKENS_FAIL });
});
};
}
2020-06-05 13:54:09 -07:00
export function revokeOAuthToken(id) {
return (dispatch, getState) => {
dispatch({ type: REVOKE_TOKEN_REQUEST, id });
return api(getState).delete(`/api/oauth_tokens/${id}`).then(response => {
dispatch({ type: REVOKE_TOKEN_SUCCESS, id });
}).catch(error => {
dispatch({ type: REVOKE_TOKEN_FAIL, id });
});
};
}
2020-04-05 14:54:51 -07:00
export function authAppCreated(app) {
return {
type: AUTH_APP_CREATED,
2020-04-14 11:44:40 -07:00
app,
2020-04-05 14:54:51 -07:00
};
}
2020-04-05 16:39:22 -07:00
export function authAppAuthorized(app) {
return {
type: AUTH_APP_AUTHORIZED,
2020-04-14 11:44:40 -07:00
app,
2020-04-05 16:39:22 -07:00
};
}
2020-04-05 14:54:51 -07:00
export function authLoggedIn(user) {
return {
type: AUTH_LOGGED_IN,
2020-04-14 11:44:40 -07:00
user,
2020-04-05 14:54:51 -07:00
};
}