Let a custom auth app be embedded in the build

merge-requests/1208/head
Alex Gleason 2022-04-12 15:23:18 -05:00
rodzic 424d5d65af
commit 93a6945b7f
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
3 zmienionych plików z 50 dodań i 7 usunięć

Wyświetl plik

@ -14,6 +14,7 @@ import { createApp } from 'soapbox/actions/apps';
import { fetchMeSuccess, fetchMeFail } from 'soapbox/actions/me';
import { obtainOAuthToken, revokeOAuthToken } from 'soapbox/actions/oauth';
import snackbar from 'soapbox/actions/snackbar';
import { custom } from 'soapbox/custom';
import KVStore from 'soapbox/storage/kv_store';
import { getLoggedInAccount, parseBaseURL } from 'soapbox/utils/auth';
import sourceCode from 'soapbox/utils/code';
@ -39,12 +40,14 @@ export const AUTH_ACCOUNT_REMEMBER_REQUEST = 'AUTH_ACCOUNT_REMEMBER_REQUEST';
export const AUTH_ACCOUNT_REMEMBER_SUCCESS = 'AUTH_ACCOUNT_REMEMBER_SUCCESS';
export const AUTH_ACCOUNT_REMEMBER_FAIL = 'AUTH_ACCOUNT_REMEMBER_FAIL';
const customApp = custom('app');
export const messages = defineMessages({
loggedOut: { id: 'auth.logged_out', defaultMessage: 'Logged out.' },
invalidCredentials: { id: 'auth.invalid_credentials', defaultMessage: 'Wrong username or password' },
});
const noOp = () => () => new Promise(f => f());
const noOp = () => new Promise(f => f());
const getScopes = state => {
const instance = state.get('instance');
@ -54,12 +57,23 @@ const getScopes = state => {
function createAppAndToken() {
return (dispatch, getState) => {
return dispatch(createAuthApp()).then(() => {
return dispatch(getAuthApp()).then(() => {
return dispatch(createAppToken());
});
};
}
/** Create an auth app, or use it from build config */
function getAuthApp() {
return (dispatch, getState) => {
if (customApp?.client_secret) {
return noOp().then(() => dispatch({ type: AUTH_APP_CREATED, app: customApp }));
} else {
return dispatch(createAuthApp());
}
};
}
function createAuthApp() {
return (dispatch, getState) => {
const params = {
@ -117,7 +131,7 @@ export function refreshUserToken() {
const refreshToken = getState().getIn(['auth', 'user', 'refresh_token']);
const app = getState().getIn(['auth', 'app']);
if (!refreshToken) return dispatch(noOp());
if (!refreshToken) return dispatch(noOp);
const params = {
client_id: app.get('client_id'),
@ -200,7 +214,7 @@ export function loadCredentials(token, accountUrl) {
export function logIn(intl, username, password) {
return (dispatch, getState) => {
return dispatch(createAuthApp()).then(() => {
return dispatch(getAuthApp()).then(() => {
return dispatch(createUserToken(username, password));
}).catch(error => {
if (error.response.data.error === 'mfa_required') {

Wyświetl plik

@ -1,12 +1,13 @@
/**
* Functions for dealing with custom build configuration.
*/
import { NODE_ENV } from 'soapbox/build_config';
import * as BuildConfig from 'soapbox/build_config';
/** Require a custom JSON file if it exists */
export const custom = (filename, fallback = {}) => {
if (NODE_ENV === 'test') return fallback;
export const custom = (filename: string, fallback: any = {}): any => {
if (BuildConfig.NODE_ENV === 'test') return fallback;
// @ts-ignore: yes it does
const context = require.context('custom', false, /\.json$/);
const path = `./${filename}.json`;

Wyświetl plik

@ -38,6 +38,34 @@ For example:
See `app/soapbox/utils/features.js` for the full list of features.
### Embedded app (`custom/app.json`)
By default, Soapbox will create a new OAuth app every time a user tries to register or log in.
This is usually the desired behavior, as it works "out of the box" without any additional configuration, and it is resistant to tampering and subtle client bugs.
However, some larger servers may wish to skip this step for performance reasons.
If an app is supplied in `custom/app.json`, it will be used for authorization.
The full app entity must be provided, for example:
```json
{
"client_id": "cf5yI6ffXH1UcDkEApEIrtHpwCi5Tv9xmju8IKdMAkE",
"client_secret": "vHmSDpm6BJGUvR4_qWzmqWjfHcSYlZumxpFfohRwNNQ",
"id": "7132",
"name": "Soapbox FE",
"redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
"website": "https://soapbox.pub/",
"vapid_key": "BLElLQVJVmY_e4F5JoYxI5jXiVOYNsJ9p-amkykc9NcI-jwa9T1Y2GIbDqbY-HqC6ayPkfW4K4o9vgBFKYmkuS4"
}
```
It is crucial that the app has the expected scopes.
You can obtain one with the following curl command (replace `MY_DOMAIN`):
```sh
curl -X POST -H "Content-Type: application/json" -d '{"client_name": "Soapbox FE", "redirect_uris": "urn:ietf:wg:oauth:2.0:oob", "scopes": "read write follow push admin", "website": "https://soapbox.pub/"}' "https://MY_DOMAIN.com/api/v1/apps"
```
### Custom files (`custom/instance/*`)
You can place arbitrary files of any type in the `custom/instance/` directory.