Let a custom auth app be embedded in the build
This commit is contained in:
parent
424d5d65af
commit
93a6945b7f
3 changed files with 50 additions and 7 deletions
|
@ -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') {
|
||||
|
|
|
@ -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`;
|
||||
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue