From 3be730251107b3d2315de11f1004932abb3cdbdd Mon Sep 17 00:00:00 2001 From: jimafisk Date: Thu, 7 Nov 2024 21:26:24 -0500 Subject: [PATCH] Add Gitea / Forgejo provider (#271). --- cmd/build/data_source.go | 8 +- defaults/core/cms/auth.js | 36 ++++-- defaults/core/cms/button.svelte | 12 +- defaults/core/cms/providers/gitea.js | 116 ++++++++++++++++++ .../cms/{publish.js => providers/gitlab.js} | 8 +- .../cms/{post_local.js => providers/local.js} | 4 +- defaults/starters/learner/plenti.json | 3 +- readers/site_config.go | 1 + 8 files changed, 164 insertions(+), 24 deletions(-) create mode 100644 defaults/core/cms/providers/gitea.js rename defaults/core/cms/{publish.js => providers/gitlab.js} (92%) rename defaults/core/cms/{post_local.js => providers/local.js} (94%) diff --git a/cmd/build/data_source.go b/cmd/build/data_source.go index 20c8eaf0..fe1ca35a 100644 --- a/cmd/build/data_source.go +++ b/cmd/build/data_source.go @@ -68,6 +68,7 @@ type env struct { cms cms } type cms struct { + provider string repo string redirectUrl string appId string @@ -92,6 +93,7 @@ func DataSource(buildPath string, spaPath string, siteConfig readers.SiteConfig) entrypointHTML: siteConfig.EntryPointHTML, entrypointJS: siteConfig.EntryPointJS, cms: cms{ + provider: siteConfig.CMS.Provider, repo: siteConfig.CMS.Repo, redirectUrl: siteConfig.CMS.RedirectUrl, appId: siteConfig.CMS.AppId, @@ -122,7 +124,8 @@ func DataSource(buildPath string, spaPath string, siteConfig readers.SiteConfig) ", fingerprint: '" + env.fingerprint + "', entrypointHTML: '" + env.entrypointHTML + "', entrypointJS: '" + env.entrypointJS + - "', cms: { repo: '" + env.cms.repo + + "', cms: { provider: '" + env.cms.provider + + "', repo: '" + env.cms.repo + "', redirectUrl: '" + env.cms.redirectUrl + "', appId: '" + env.cms.appId + "', branch: '" + env.cms.branch + @@ -522,7 +525,8 @@ func createProps(currentContent content, allContentStr string, env env) error { ", baseurl: '"+env.baseurl+ "', fingerprint: '"+env.fingerprint+ "', entrypointJS: '"+env.entrypointJS+ - "', cms: { repo: '"+env.cms.repo+ + "', cms: { provider: '"+env.cms.provider+ + "', repo: '"+env.cms.repo+ "', redirectUrl: '"+env.cms.redirectUrl+ "', appId: '"+env.cms.appId+ "', branch: '"+env.cms.branch+ diff --git a/defaults/core/cms/auth.js b/defaults/core/cms/auth.js index 55e2bbb7..c0dad14e 100644 --- a/defaults/core/cms/auth.js +++ b/defaults/core/cms/auth.js @@ -7,8 +7,22 @@ import adminMenu from './admin_menu.svelte'; export const repoUrl = makeUrl(env.cms.repo); const local = env.local; +const provider = env.cms.provider.toLowerCase(); + +let authorization_endpoint, access_token_endpoint; +if (!provider || provider === "gitlab") { + authorization_endpoint = "/oauth/authorize"; + access_token_endpoint = "/oauth/token"; +} +if (provider === "gitea" || provider === "forgejo") { + authorization_endpoint = "/login/oauth/authorize"; + access_token_endpoint = "/login/oauth/access_token"; +} const settings = { + provider: provider, + authorization_endpoint: authorization_endpoint, + access_token_endpoint: access_token_endpoint, server: repoUrl.origin, group: repoUrl.pathname.split('/')[1], repository: repoUrl.pathname.split('/')[2], @@ -21,18 +35,18 @@ let localTokens; localTokenStore.subscribe(value => { localTokens = value; }); -const tokenStore = createDataStore('gitlab_tokens'); +const tokenStore = createDataStore('tokens'); let tokens, isExpired; tokenStore.subscribe(value => { tokens = value; isExpired = tokens && Date.now() > (tokens.created_at + tokens.expires_in) * 1000; }); -const codeVerifierStore = createDataStore('gitlab_code_verifier'); +const codeVerifierStore = createDataStore('code_verifier'); let codeVerifier; codeVerifierStore.subscribe(value => codeVerifier = value); -const stateStore = createSessionStore('gitlab_state'); +const stateStore = createSessionStore('state'); let state; stateStore.subscribe(value => state = value); @@ -56,7 +70,7 @@ const getUser = () => ({ }, refresh() { - let authTokens = JSON.parse(localStorage.getItem('PLENTI_CMS_GITLAB_TOKENS')); + let authTokens = JSON.parse(localStorage.getItem('PLENTI_CMS_TOKENS')); this.isAuthenticated = typeof authTokens?.access_token !== 'undefined'; this.tokens = authTokens; }, @@ -109,19 +123,19 @@ const requestAuthCode = async () => { codeVerifierStore.set(generateString()); const codeChallenge = await hash(codeVerifier); - const { server, redirectUrl, appId } = settings; - window.location.href = server + "/oauth/authorize" + const { authorization_endpoint, server, redirectUrl, appId } = settings; + window.location.href = server + authorization_endpoint + "?client_id=" + encodeURIComponent(appId) + "&redirect_uri=" + encodeURIComponent(redirectUrl) + "&response_type=code" + "&state=" + encodeURIComponent(state) + "&code_challenge=" + encodeURIComponent(codeChallenge) - + "&code_challenge_method=S256"; + + "&code_challenge_method=S256"; }; const requestAccessToken = async code => { - const { server, redirectUrl, appId } = settings; - const response = await fetch(server + "/oauth/token" + const { access_token_endpoint, server, redirectUrl, appId } = settings; + const response = await fetch(server + access_token_endpoint + "?client_id=" + encodeURIComponent(appId) + "&code=" + encodeURIComponent(code) + "&grant_type=authorization_code" @@ -137,11 +151,11 @@ const requestAccessToken = async code => { }; const requestRefreshToken = async () => { - const { server, redirectUrl, appId } = settings; + const { access_token_endpoint, server, redirectUrl, appId } = settings; if (!codeVerifier) { throw new Error("Code verifier not saved to session storage"); } - const response = await fetch(server + "/oauth/token" + const response = await fetch(server + access_token_endpoint + "?client_id=" + encodeURIComponent(appId) + "&refresh_token=" + encodeURIComponent(tokens.refresh_token) + "&grant_type=refresh_token" diff --git a/defaults/core/cms/button.svelte b/defaults/core/cms/button.svelte index 562d974d..9a19d8b7 100644 --- a/defaults/core/cms/button.svelte +++ b/defaults/core/cms/button.svelte @@ -1,12 +1,14 @@