feat: Support custom auth schemes for Github API (#1086)
This commit is contained in:
parent
dcdc49232d
commit
17b32f0902
@ -33,7 +33,7 @@ import {
|
||||
} from '@staticcms/core/lib/util/APIUtils';
|
||||
import { GitHubCommitStatusState, PullRequestState } from './types';
|
||||
|
||||
import type { DataFile, PersistOptions, UnpublishedEntry } from '@staticcms/core';
|
||||
import type { AuthScheme, DataFile, PersistOptions, UnpublishedEntry } from '@staticcms/core';
|
||||
import type { ApiRequest, FetchError } from '@staticcms/core/lib/util';
|
||||
import type AssetProxy from '@staticcms/core/valueObjects/AssetProxy';
|
||||
import type { Semaphore } from 'semaphore';
|
||||
@ -75,6 +75,7 @@ export const MOCK_PULL_REQUEST = -1;
|
||||
export interface Config {
|
||||
apiRoot?: string;
|
||||
token?: string;
|
||||
authScheme?: AuthScheme;
|
||||
branch?: string;
|
||||
useOpenAuthoring?: boolean;
|
||||
openAuthoringEnabled?: boolean;
|
||||
@ -162,6 +163,7 @@ export type Diff = {
|
||||
export default class API {
|
||||
apiRoot: string;
|
||||
token: string;
|
||||
authScheme: AuthScheme;
|
||||
branch: string;
|
||||
useOpenAuthoring?: boolean;
|
||||
openAuthoringEnabled?: boolean;
|
||||
@ -185,6 +187,7 @@ export default class API {
|
||||
constructor(config: Config) {
|
||||
this.apiRoot = config.apiRoot || 'https://api.github.com';
|
||||
this.token = config.token || '';
|
||||
this.authScheme = config.authScheme || 'token';
|
||||
this.branch = config.branch || 'main';
|
||||
this.useOpenAuthoring = config.useOpenAuthoring;
|
||||
this.repo = config.repo || '';
|
||||
@ -242,7 +245,7 @@ export default class API {
|
||||
};
|
||||
|
||||
if (this.token) {
|
||||
baseHeader.Authorization = `token ${this.token}`;
|
||||
baseHeader.Authorization = `${this.authScheme} ${this.token}`;
|
||||
return Promise.resolve(baseHeader);
|
||||
}
|
||||
|
||||
|
@ -103,6 +103,35 @@ describe('github API', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should fetch url with authorization header using custom auth scheme', async () => {
|
||||
const api = new API({
|
||||
branch: 'gh-pages',
|
||||
repo: 'my-repo',
|
||||
token: 'token',
|
||||
authScheme: 'Bearer',
|
||||
squashMerges: false,
|
||||
initialWorkflowStatus: WorkflowStatus.DRAFT,
|
||||
cmsLabelPrefix: '',
|
||||
});
|
||||
|
||||
fetch.mockResolvedValue({
|
||||
text: jest.fn().mockResolvedValue('some response'),
|
||||
ok: true,
|
||||
status: 200,
|
||||
headers: { get: () => '' },
|
||||
});
|
||||
const result = await api.request('/some-path');
|
||||
expect(result).toEqual('some response');
|
||||
expect(fetch).toHaveBeenCalledTimes(1);
|
||||
expect(fetch).toHaveBeenCalledWith('https://api.github.com/some-path', {
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
Authorization: 'Bearer token',
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw error on not ok response', async () => {
|
||||
const api = new API({
|
||||
branch: 'gh-pages',
|
||||
|
@ -25,6 +25,7 @@ import API, { API_NAME } from './API';
|
||||
import AuthenticationPage from './AuthenticationPage';
|
||||
|
||||
import type {
|
||||
AuthScheme,
|
||||
BackendClass,
|
||||
BackendEntry,
|
||||
ConfigWithDefaults,
|
||||
@ -75,6 +76,7 @@ export default class GitHub implements BackendClass {
|
||||
mediaFolder?: string;
|
||||
previewContext: string;
|
||||
token: string | null;
|
||||
authScheme: AuthScheme;
|
||||
squashMerges: boolean;
|
||||
cmsLabelPrefix: string;
|
||||
_currentUserPromise?: Promise<GitHubUser>;
|
||||
@ -114,6 +116,7 @@ export default class GitHub implements BackendClass {
|
||||
this.branch = config.backend.branch?.trim() || 'main';
|
||||
this.apiRoot = config.backend.api_root || 'https://api.github.com';
|
||||
this.token = '';
|
||||
this.authScheme = config.backend.auth_scheme || 'token';
|
||||
this.squashMerges = config.backend.squash_merges || false;
|
||||
this.cmsLabelPrefix = config.backend.cms_label_prefix || '';
|
||||
this.mediaFolder = config.media_folder;
|
||||
@ -171,7 +174,7 @@ export default class GitHub implements BackendClass {
|
||||
let repoExists = false;
|
||||
while (!repoExists) {
|
||||
repoExists = await fetch(`${this.apiRoot}/repos/${repo}`, {
|
||||
headers: { Authorization: `token ${token}` },
|
||||
headers: { Authorization: `${this.authScheme} ${token}` },
|
||||
})
|
||||
.then(() => true)
|
||||
.catch(err => {
|
||||
@ -194,7 +197,7 @@ export default class GitHub implements BackendClass {
|
||||
if (!this._currentUserPromise) {
|
||||
this._currentUserPromise = fetch(`${this.apiRoot}/user`, {
|
||||
headers: {
|
||||
Authorization: `token ${token}`,
|
||||
Authorization: `${this.authScheme} ${token}`,
|
||||
},
|
||||
}).then(res => res.json());
|
||||
}
|
||||
@ -215,7 +218,7 @@ export default class GitHub implements BackendClass {
|
||||
`${this.apiRoot}/repos/${this.originRepo}/collaborators/${username}/permission`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `token ${token}`,
|
||||
Authorization: `${this.authScheme} ${token}`,
|
||||
},
|
||||
},
|
||||
)
|
||||
@ -232,7 +235,7 @@ export default class GitHub implements BackendClass {
|
||||
const repo = await fetch(`${this.apiRoot}/repos/${currentUser.login}/${repoName}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `token ${token}`,
|
||||
Authorization: `${this.authScheme} ${token}`,
|
||||
},
|
||||
}).then(res => res.json());
|
||||
|
||||
@ -276,7 +279,7 @@ export default class GitHub implements BackendClass {
|
||||
const fork = await fetch(`${this.apiRoot}/repos/${this.originRepo}/forks`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `token ${token}`,
|
||||
Authorization: `${this.authScheme} ${token}`,
|
||||
},
|
||||
}).then(res => res.json());
|
||||
this.useOpenAuthoring = true;
|
||||
@ -289,6 +292,7 @@ export default class GitHub implements BackendClass {
|
||||
const apiCtor = API;
|
||||
this.api = new apiCtor({
|
||||
token: this.token,
|
||||
authScheme: this.authScheme,
|
||||
branch: this.branch,
|
||||
repo: this.repo,
|
||||
originRepo: this.originRepo,
|
||||
|
@ -698,6 +698,8 @@ export interface SelectWidgetOptionObject {
|
||||
|
||||
export type AuthScope = 'repo' | 'public_repo';
|
||||
|
||||
export type AuthScheme = 'token' | 'Bearer';
|
||||
|
||||
export type SlugEncoding = 'unicode' | 'ascii';
|
||||
|
||||
export type RenderedField<F extends BaseField = UnknownField> = F & {
|
||||
@ -1025,6 +1027,7 @@ export interface Backend {
|
||||
identity_url?: string;
|
||||
gateway_url?: string;
|
||||
auth_scope?: AuthScope;
|
||||
auth_scheme?: AuthScheme;
|
||||
commit_messages?: {
|
||||
create?: string;
|
||||
update?: string;
|
||||
|
Loading…
x
Reference in New Issue
Block a user