mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-09-12 21:58:57 +02:00
feat: add read-only GitHub App access alongside OAuth
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"core.min.js": "core.c5bd53363a.min.js",
|
||||
"vendor.min.js": "vendor.0f10f9accb.min.js",
|
||||
"vendor.min.js": "vendor.b17b42ea2b.min.js",
|
||||
"mermaid.min.js": "mermaid.f848a72d16.min.js",
|
||||
"all.min.css": "all.7ac8730b9a.min.css",
|
||||
"markdown.min.js": "markdown.ad7b1d71c3.min.js",
|
||||
|
||||
@@ -114,7 +114,28 @@
|
||||
"storage_read_error": "An error occurred while reading the file from storage — please try again.",
|
||||
"upstream_error": "A temporary error occurred while fetching from GitHub — please try again.",
|
||||
"token_expired": "Your GitHub access token has expired. Please log out and log in again to refresh it.",
|
||||
"job_is_active": "This job is currently running — wait for it to finish or remove it first."
|
||||
"job_is_active": "This job is currently running — wait for it to finish or remove it first.",
|
||||
"github_app_access_required": "Allow this repository on GitHub using the read-only access button, then retry. Organization access may require administrator approval.",
|
||||
"github_app_reconnect_required": "Reconnect your GitHub App account to restore read-only access.",
|
||||
"github_app_disabled": "New GitHub App connections are currently unavailable.",
|
||||
"github_oauth_required": "Connect legacy GitHub OAuth to use this feature.",
|
||||
"github_identity_mismatch": "Use the same GitHub account that you are signed in with here.",
|
||||
"github_app_permissions_invalid": "The GitHub App must be configured with read-only permissions.",
|
||||
"github_unavailable": "GitHub is temporarily unavailable. Please retry.",
|
||||
"connection_changed": "The repository connection changed. Reload and try again.",
|
||||
"repository_busy": "Wait for the repository operation to finish before changing its connection.",
|
||||
"invalid_connection": "Select a supported GitHub connection.",
|
||||
"github_oauth_disabled": "Legacy OAuth sign-in is currently disabled.",
|
||||
"invalid_auth_state": "The authorization session expired. Please start again from Anonymous GitHub.",
|
||||
"invalid_webhook_signature": "The webhook signature is invalid.",
|
||||
"webhook_processing_failed": "Webhook processing failed. Retry the delivery.",
|
||||
"github_app_authorization_cancelled": "GitHub authorization was cancelled.",
|
||||
"github_account_link_required": "This username belongs to an existing account. Sign in to that account before connecting GitHub.",
|
||||
"github_app_refresh_busy": "GitHub credentials are being renewed. Please retry shortly.",
|
||||
"github_grant_revocation_failed": "Unable to revoke the GitHub grant. Please retry.",
|
||||
"another_login_required": "Connect and verify another sign-in method before disconnecting OAuth.",
|
||||
"oauth_resources_remaining": "Some resources still require OAuth. Migrate or remove them before disconnecting.",
|
||||
"invalid_github_path": "The GitHub repository path is invalid."
|
||||
},
|
||||
"WARNINGS": {
|
||||
"page_not_enabled_on_repo": "GitHub Pages is not enabled on this repository. Enable it in the repository's Settings → Pages on GitHub, then refresh.",
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
<div class="anonymize-page h-100">
|
||||
<div class="container py-3" v-if="githubConnections?.appEnabled">
|
||||
<span v-if="isUpdate">Connection: {{ githubConnection === 'github-app' ? 'GitHub App (read-only)' : 'Legacy OAuth' }}. <a href="/connections">Change connection</a></span>
|
||||
<span v-if="!isUpdate">Repository access:
|
||||
<button class="btn" :disabled="githubConnection === 'github-app'" @click="chooseGitHubConnection('github-app')">Read-only GitHub App</button>
|
||||
<button v-if="githubConnections?.oauthConnected" class="btn" :disabled="githubConnection === 'oauth'" @click="chooseGitHubConnection('oauth')">Use existing OAuth access</button>
|
||||
</span>
|
||||
<button class="btn btn-ink" @click="grantGitHubAccess()">{{ githubConnections?.appConnected ? 'Allow repository access on GitHub' : 'Connect read-only GitHub access' }}</button>
|
||||
<p class="mb-0"><small>Return here after confirming access on GitHub. Anonymization publishes the configured content, including content from private repositories. Gists currently use OAuth.</small></p>
|
||||
</div>
|
||||
<!-- ===== STATE 1: No URL — centered input ===== -->
|
||||
<div class="anonymize-landing" v-show="!(sourceUrl)">
|
||||
<div class="anonymize-landing-inner">
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<div class="container page paper-page">
|
||||
<div class="paper-crumbs"><a href="/dashboard">My work</a> / GitHub connections</div>
|
||||
<h1 class="paper-page-title">GitHub <em>connections</em></h1>
|
||||
<p>Connect the GitHub account you use here. Your anonymizations and URLs stay the same.</p>
|
||||
<p class="alert alert-danger" role="alert" v-if="connectionError">{{ connectionError }}</p>
|
||||
<div v-if="connections">
|
||||
<section class="paper-settings-section" v-if="connections.appEnabled">
|
||||
<h2>Read-only GitHub App</h2>
|
||||
<p v-if="connections.appError" role="alert">{{ connections.appError }}. Reconnect to restore access.</p>
|
||||
<a class="btn btn-ink" target="_self" href="/github/app/login">{{ connections.appConnected ? 'Reconnect GitHub account' : 'Connect GitHub account' }}</a>
|
||||
<a class="btn" v-if="connections.appConnected" target="_self" href="/github/app/install">Allow repositories on GitHub</a>
|
||||
<p class="mt-2">GitHub opens directly to the access screen. Select repositories and confirm. Organization access may require an administrator's approval.</p>
|
||||
<ul>
|
||||
<li v-for="installation in connections.installations" :key="installation.id">
|
||||
{{ installation.account }} {{ installation.suspended ? '(suspended)' : '' }} —
|
||||
<a target="_self" :href="'/github/app/install?installationId=' + installation.id">Add or remove repository access</a>
|
||||
</li>
|
||||
</ul>
|
||||
<button class="btn" :disabled="busy" @click="loadConnections()">Refresh access after approval</button>
|
||||
</section>
|
||||
<section class="paper-settings-section">
|
||||
<h2>Legacy OAuth</h2>
|
||||
<p>{{ connections.oauthConnected ? 'Connected' : 'Not connected' }}. Existing OAuth anonymizations continue to use this connection.</p>
|
||||
<a v-if="connections.oauthEnabled" target="_self" href="/github/login" class="btn">Connect legacy OAuth</a>
|
||||
<p v-if="connections.gistCount">{{ connections.gistCount }} gist(s) still require OAuth.</p>
|
||||
<button v-if="connections.oauthConnected && connections.appConnected" class="btn" :disabled="busy || connections.gistCount || connections.resources.some(r => r.connection === 'oauth')" @click="disconnectOAuth()">Revoke OAuth access</button>
|
||||
<p>Migrate all dependent resources before revoking OAuth. Revocation removes GitHub's broad OAuth repository grant.</p>
|
||||
</section>
|
||||
<section class="paper-settings-section">
|
||||
<h2>Repository connections</h2>
|
||||
<p>Check read-only access, then switch each resource. Connecting the App alone does not change existing resources.</p>
|
||||
<p>Removing GitHub access stops fetching new source content. Already published anonymized content follows its existing expiration and removal settings.</p>
|
||||
<div v-for="resource in connections.resources" :key="resource.type + resource.id" class="mb-3">
|
||||
<strong>{{ resource.id }}</strong> — {{ resource.name }} ({{ resource.type }})<br>
|
||||
Connection: {{ resource.connection === 'github-app' ? 'GitHub App (read-only)' : 'Legacy OAuth' }}
|
||||
<div v-if="resource.connection === 'oauth' && connections.appEnabled && connections.appConnected">
|
||||
<button class="btn" :disabled="busy" @click="changeConnection(resource, 'github-app', true)">Check read-only access</button>
|
||||
<button v-if="resource.eligible" class="btn btn-ink" :disabled="busy" @click="changeConnection(resource, 'github-app', false)">Switch to read-only access</button>
|
||||
</div>
|
||||
<button v-if="resource.connection === 'github-app' && connections.oauthConnected" class="btn" :disabled="busy" @click="changeConnection(resource, 'oauth', false)">Switch to existing OAuth access</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
@@ -12,6 +12,8 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p class="mt-3"><a href="/connections">Manage GitHub connections and read-only access</a></p>
|
||||
|
||||
<!-- Quota -->
|
||||
<div class="quota-row" v-if="quota">
|
||||
<div class="quota-item" v-for="(q, index) in [
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item" v-if="!user">
|
||||
<a class="nav-link btn-signin" target="_self" href="/github/login" data-offset="30"><i class="fab fa-github mr-1"></i>
|
||||
<a class="nav-link btn-signin" target="_self" href="/signin" data-offset="30"><i class="fab fa-github mr-1"></i>
|
||||
Sign in
|
||||
</a>
|
||||
</li>
|
||||
@@ -75,6 +75,7 @@
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right user-menu" aria-labelledby="navbarDropdownMenuLink">
|
||||
<h6 class="dropdown-header">Signed in as @{{ user?.username }}</h6>
|
||||
<a class="dropdown-item" href="/connections">GitHub connections</a>
|
||||
<a class="dropdown-item" href="/profile">
|
||||
<i class="fas fa-sliders-h" aria-hidden="true"></i>
|
||||
<span>Settings<small>Defaults, quotas, account</small></span>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</p>
|
||||
|
||||
<div class="paper-cta-row">
|
||||
<a href="/github/login" target="_self" class="btn-hero" v-if="!user">
|
||||
<a href="/signin" target="_self" class="btn-hero" v-if="!user">
|
||||
<i class="fab fa-github mr-2" aria-hidden="true"></i>Sign in with GitHub
|
||||
</a>
|
||||
<a href="/anonymize" class="btn-hero" v-if="user">
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<div class="container page paper-page">
|
||||
<h1 class="paper-page-title">Connect to <em>GitHub</em></h1>
|
||||
<p>Sign in to manage your anonymizations. Both connections use the same Anonymous GitHub account.</p>
|
||||
<p v-if="site_options?.GITHUB_APP_ENABLED"><a class="btn btn-ink" target="_self" href="/github/app/login">Continue with read-only GitHub App</a></p>
|
||||
<p v-if="site_options?.GITHUB_APP_ENABLED">Choose which repositories to allow after signing in. Private repositories are accessed with read-only permissions.</p>
|
||||
<p v-if="site_options?.GITHUB_OAUTH_ENABLED"><a class="btn" target="_self" href="/github/login">Continue with legacy GitHub OAuth</a></p>
|
||||
<p v-if="site_options?.GITHUB_OAUTH_ENABLED">OAuth supports existing connections and gists. GitHub's private repository OAuth scope includes write access.</p>
|
||||
</div>
|
||||
+87
-11
@@ -888,6 +888,22 @@ export const statusController = function (state, http, params) {
|
||||
export const anonymizeController = function (state, http, html, params, location, translate, timeout) {
|
||||
// Unified state
|
||||
state.sourceUrl = "";
|
||||
state.githubConnection = undefined;
|
||||
state.githubConnections = null;
|
||||
state.grantGitHubAccess = () => {
|
||||
const draft = {};
|
||||
for (const key of ["sourceUrl", "terms", "repoId", "pullRequestId", "gistId", "source", "options", "conference", "githubConnection"]) draft[key] = state[key];
|
||||
sessionStorage.setItem("github-access-draft", JSON.stringify({ path: location.path(), savedAt: Date.now(), draft }));
|
||||
const returnTo = location.path();
|
||||
const repository = parseRepoFullName(state.sourceUrl) || "";
|
||||
const route = state.githubConnections?.appConnected ? "/github/app/install" : "/github/app/login";
|
||||
window.location.href = route + "?returnTo=" + encodeURIComponent(returnTo) + "&repository=" + encodeURIComponent(repository) + "&install=1";
|
||||
};
|
||||
state.chooseGitHubConnection = async (value) => {
|
||||
state.githubConnection = value;
|
||||
state.readme = "";
|
||||
if (state.sourceUrl) await refreshGitHubAccess();
|
||||
};
|
||||
state.detectedType = null; // 'repo' | 'pr' | 'gist'
|
||||
state.repoId = "";
|
||||
state.pullRequestId = "";
|
||||
@@ -984,7 +1000,28 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
: undefined;
|
||||
}
|
||||
|
||||
async function refreshGitHubAccess() {
|
||||
state._preservingDraft = true;
|
||||
try { await state.urlSelected(true); }
|
||||
finally { state._preservingDraft = false; }
|
||||
}
|
||||
|
||||
async function restoreGitHubDraft() {
|
||||
let saved;
|
||||
try { saved = JSON.parse(sessionStorage.getItem("github-access-draft") || "null"); }
|
||||
catch (_) { return false; }
|
||||
if (!saved || saved.path !== location.path() || Date.now() - saved.savedAt >= 30 * 60000) return false;
|
||||
for (const key of ["sourceUrl", "terms", "repoId", "pullRequestId", "gistId", "source", "options", "conference", "githubConnection"]) {
|
||||
if (Object.prototype.hasOwnProperty.call(saved.draft, key)) state[key] = saved.draft[key];
|
||||
}
|
||||
if (state.options.expirationDate) state.options.expirationDate = new Date(state.options.expirationDate);
|
||||
await refreshGitHubAccess();
|
||||
sessionStorage.removeItem("github-access-draft");
|
||||
return true;
|
||||
}
|
||||
|
||||
getDefault(() => {
|
||||
if (!params.repoId && !params.pullRequestId && !params.gistId) timeout(restoreGitHubDraft, 0);
|
||||
// Edit mode: repo
|
||||
if (params.repoId && params.repoId != "") {
|
||||
state.isUpdate = true;
|
||||
@@ -992,6 +1029,7 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
state.repoId = params.repoId;
|
||||
http.get("/api/repo/" + state.repoId).then(
|
||||
async (res) => {
|
||||
state.githubConnection = res.data.connection || "oauth";
|
||||
state.sourceUrl = "https://github.com/" + res.data.source.fullName;
|
||||
state._originalFullName = res.data.source.fullName;
|
||||
state.terms = res.data.options.terms.filter((f) => f).join("\n");
|
||||
@@ -1012,6 +1050,7 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
if (res.data.options.expirationDate) {
|
||||
state.options.expirationDate = new Date(res.data.options.expirationDate);
|
||||
}
|
||||
if (await restoreGitHubDraft()) return;
|
||||
await Promise.all([getRepoDetails(), getReadme()]);
|
||||
anonymizeReadme();
|
||||
|
||||
@@ -1026,6 +1065,7 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
state.pullRequestId = params.pullRequestId;
|
||||
http.get("/api/pr/" + state.pullRequestId).then(
|
||||
async (res) => {
|
||||
state.githubConnection = res.data.connection || "oauth";
|
||||
state.sourceUrl = "https://github.com/" + res.data.source.repositoryFullName + "/pull/" + res.data.source.pullRequestId;
|
||||
state.terms = res.data.options.terms.filter((f) => f).join("\n");
|
||||
state.source = res.data.source;
|
||||
@@ -1035,8 +1075,9 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
if (res.data.options.expirationDate) {
|
||||
state.options.expirationDate = new Date(res.data.options.expirationDate);
|
||||
}
|
||||
if (await restoreGitHubDraft()) return;
|
||||
try {
|
||||
state.details = (await http.get(`/api/pr/${res.data.source.repositoryFullName}/${res.data.source.pullRequestId}`)).data;
|
||||
state.details = (await http.get(`/api/pr/${res.data.source.repositoryFullName}/${res.data.source.pullRequestId}`, { params: { connection: state.githubConnection } })).data;
|
||||
} catch (error) {
|
||||
const code = error && error.data && error.data.error;
|
||||
if (code) {
|
||||
@@ -1068,6 +1109,7 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
if (res.data.options.expirationDate) {
|
||||
state.options.expirationDate = new Date(res.data.options.expirationDate);
|
||||
}
|
||||
if (await restoreGitHubDraft()) return;
|
||||
state.details = (await http.get(`/api/gist/source/${res.data.source.gistId}`)).data;
|
||||
|
||||
},
|
||||
@@ -1076,17 +1118,19 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
}
|
||||
});
|
||||
|
||||
http.get("/github/connections").then(res => { state.githubConnections = res.data; }).catch(() => {});
|
||||
|
||||
// URL change handler - auto-detect type
|
||||
state.urlSelected = async () => {
|
||||
state.terms = state.defaultTerms;
|
||||
if (!state.isUpdate) {
|
||||
state.urlSelected = async (preserveDraft = false) => {
|
||||
if (!preserveDraft) state.terms = state.defaultTerms;
|
||||
if (!preserveDraft && !state.isUpdate) {
|
||||
state.repoId = "";
|
||||
state.pullRequestId = "";
|
||||
state.gistId = "";
|
||||
}
|
||||
state.details = null;
|
||||
state.branches = [];
|
||||
state.source = { type: "GitHubStream", branch: "", commit: "" };
|
||||
if (!preserveDraft) state.source = { type: "GitHubStream", branch: "", commit: "" };
|
||||
state.anonymize_readme = "";
|
||||
state.readme = "";
|
||||
state.html_readme = "";
|
||||
@@ -1136,7 +1180,7 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
state.isUpdate &&
|
||||
state._originalBranch === state.source.branch &&
|
||||
!!state.source.commit;
|
||||
if (!keepSavedCommit) {
|
||||
if (!keepSavedCommit && !(state._preservingDraft && state.source.commit)) {
|
||||
state.source.commit = selected.commit;
|
||||
}
|
||||
state.readme = selected.readme;
|
||||
@@ -1149,7 +1193,7 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
const o = parseGithubUrl(state.sourceUrl);
|
||||
try {
|
||||
const branches = await http.get(`/api/repo/${o.owner}/${o.repo}/branches`, {
|
||||
params: { force: force === true ? "1" : "0", repositoryID: sourceRepositoryID() },
|
||||
params: { anonymizedRepoId: state.isUpdate && params.repoId && parseRepoFullName(state.sourceUrl) === state._originalFullName ? params.repoId : undefined, connection: state.githubConnection, force: force === true ? "1" : "0", repositoryID: sourceRepositoryID() },
|
||||
});
|
||||
state.branches = branches.data;
|
||||
state.sourceUnreachable = false;
|
||||
@@ -1167,7 +1211,7 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
!state.options.update &&
|
||||
state._originalBranch === state.source.branch &&
|
||||
!!state.source.commit;
|
||||
if (!keepSavedCommit) {
|
||||
if (!keepSavedCommit && !(state._preservingDraft && state.source.commit)) {
|
||||
state.source.commit = selected[0].commit;
|
||||
}
|
||||
state.readme = selected[0].readme;
|
||||
@@ -1197,7 +1241,7 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
// #364) are reflected without waiting for the cached metadata to
|
||||
// expire. The endpoint hits the GitHub API once.
|
||||
const res = await http.get(`/api/repo/${o.owner}/${o.repo}/`, {
|
||||
params: { repositoryID: sourceRepositoryID(), force: "1" },
|
||||
params: { anonymizedRepoId: state.isUpdate && params.repoId && parseRepoFullName(state.sourceUrl) === state._originalFullName ? params.repoId : undefined, connection: state.githubConnection, repositoryID: sourceRepositoryID(), force: "1" },
|
||||
});
|
||||
state.details = res.data;
|
||||
if (state.details && state.details.id) {
|
||||
@@ -1225,7 +1269,7 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
const o = parseGithubUrl(state.sourceUrl);
|
||||
try {
|
||||
const res = await http.get(`/api/repo/${o.owner}/${o.repo}/readme`, {
|
||||
params: { force: force === true ? "1" : "0", branch: state.source.branch, repositoryID: sourceRepositoryID() },
|
||||
params: { anonymizedRepoId: state.isUpdate && params.repoId && parseRepoFullName(state.sourceUrl) === state._originalFullName ? params.repoId : undefined, connection: state.githubConnection, force: force === true ? "1" : "0", branch: state.source.branch, repositoryID: sourceRepositoryID() },
|
||||
});
|
||||
state.readme = res.data;
|
||||
} catch (error) {
|
||||
@@ -1322,7 +1366,7 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
const o = parseGithubUrl(state.sourceUrl);
|
||||
try {
|
||||
resetValidity();
|
||||
const res = await http.get(`/api/pr/${o.owner}/${o.repo}/${o.pullRequestId}`);
|
||||
const res = await http.get(`/api/pr/${o.owner}/${o.repo}/${o.pullRequestId}`, { params: { connection: state.githubConnection } });
|
||||
state.details = res.data;
|
||||
if (!state.pullRequestId) {
|
||||
state.pullRequestId = o.repo + "-PR" + o.pullRequestId + "-" + generateRandomId(4);
|
||||
@@ -1640,6 +1684,7 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
const payload = {
|
||||
repoId: state.repoId,
|
||||
terms: state.terms.trim().split("\n").filter((f) => f),
|
||||
connection: state.githubConnection,
|
||||
fullName: `${o.owner}/${o.repo}`,
|
||||
repository: state.sourceUrl,
|
||||
options: state.options,
|
||||
@@ -1692,6 +1737,7 @@ export const anonymizeController = function (state, http, html, params, location
|
||||
const o = parseGithubUrl(state.sourceUrl);
|
||||
const payload = {
|
||||
pullRequestId: state.pullRequestId,
|
||||
connection: state.githubConnection,
|
||||
terms: state.terms.trim().split("\n").filter((f) => f),
|
||||
source: { repositoryFullName: `${o.owner}/${o.repo}`, pullRequestId: o.pullRequestId },
|
||||
options: state.options,
|
||||
@@ -2749,3 +2795,33 @@ export const conferenceController = function (state, http, location, params) {
|
||||
}
|
||||
getConference();
|
||||
};
|
||||
|
||||
|
||||
export const connectionsController = function (state, http) {
|
||||
state.connections = null;
|
||||
state.connectionError = "";
|
||||
state.busy = false;
|
||||
state.loadConnections = () => http.get("/github/connections").then(res => {
|
||||
state.connections = res.data;
|
||||
}).catch(error => { state.connectionError = error.data?.error || "Unable to load connections."; });
|
||||
state.changeConnection = async (resource, connection, preview) => {
|
||||
state.busy = true;
|
||||
state.connectionError = "";
|
||||
try {
|
||||
const result = await http.post("/github/connections/migrate", { type: resource.type, id: resource.id, connection, preview },
|
||||
{ headers: { "X-CSRF-Token": state.connections.csrf } });
|
||||
if (preview) resource.eligible = result.data.eligible;
|
||||
else await state.loadConnections();
|
||||
} catch (error) { state.connectionError = error.data?.error || "Unable to change connection."; }
|
||||
finally { state.busy = false; }
|
||||
};
|
||||
state.disconnectOAuth = async () => {
|
||||
state.busy = true;
|
||||
try {
|
||||
await http.post("/github/connections/disconnect-oauth", {}, { headers: { "X-CSRF-Token": state.connections.csrf } });
|
||||
await state.loadConnections();
|
||||
} catch (error) { state.connectionError = error.data?.error || "Unable to disconnect OAuth."; }
|
||||
finally { state.busy = false; }
|
||||
};
|
||||
state.loadConnections();
|
||||
};
|
||||
|
||||
@@ -2,6 +2,8 @@ import * as pages from "./app.js";
|
||||
import * as admin from "./admin.js";
|
||||
|
||||
export const pageRoutes = [
|
||||
{path: "/connections", template: "partials/connections.htm", title: "GitHub connections – Anonymous GitHub", preserveExplorer: false, setup: (state, services) => pages.connectionsController(state, services.http)},
|
||||
{path: "/signin", template: "partials/signin.htm", title: "Sign in – Anonymous GitHub", preserveExplorer: false, setup: () => {}},
|
||||
{path: "/", template: "partials/home.htm", title: "Anonymous GitHub – Share the code, not the author", preserveExplorer: false, setup: (state, services) => pages.homeController(state, services.http, services.location, services.window, services.timeout)},
|
||||
{path: "/dashboard", template: "partials/dashboard.htm", title: "Your anonymizations – Anonymous GitHub", preserveExplorer: false, setup: (state, services) => pages.unifiedDashboardController(state, services.http, services.location, services.promises, services.window, services.quotaService)},
|
||||
{"path":"/pr-dashboard","redirect":"/dashboard"},
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { render as connectionsTemplate } from "../partials/connections.htm";
|
||||
import { render as signinTemplate } from "../partials/signin.htm";
|
||||
import { render as template0 } from "../partials/404.htm";
|
||||
import { render as template1 } from "../partials/admin/conferences.htm";
|
||||
import { render as template2 } from "../partials/admin/errors.htm";
|
||||
@@ -25,6 +27,8 @@ import { render as template23 } from "../partials/profile.htm";
|
||||
import { render as template24 } from "../partials/pullRequest.htm";
|
||||
import { render as template25 } from "../partials/status.htm";
|
||||
export const templates = {
|
||||
"partials/connections.htm": connectionsTemplate,
|
||||
"partials/signin.htm": signinTemplate,
|
||||
"partials/404.htm": template0,
|
||||
"partials/admin/conferences.htm": template1,
|
||||
"partials/admin/errors.htm": template2,
|
||||
|
||||
Vendored
+20
-20
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user