Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 78 additions & 1 deletion internal/server/static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -394,13 +394,17 @@ body {
overflow: auto;
background-color: rgba(0,0,0,0.4);

li {
margin-bottom: 10px;
}

.header-modal-content {
background-color: #fefefe;
margin: 10% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 600px;
max-width: 50%;
border-radius: 8px;
display: flex;
flex-direction: column;
Expand All @@ -427,6 +431,79 @@ body {
gap: 30px;
width: 100%;
}

.auth-token-details {
width: 100%;
max-width: calc(100% - 16px);
margin-left: 8px;
margin-right: 8px;

summary {
cursor: pointer;
text-align: left;
padding: 5px 0;
}

.auth-token-content {
padding: 10px;
border: 1px solid #eee;
margin-top: 5px;
background-color: #f9f9f9;
text-align: left;
max-width: 100%;
overflow-wrap: break-word;

.auth-tab-group {
display: flex;
border-bottom: 1px solid #ccc;
margin-bottom: 10px;
}

.auth-tab-picker {
padding: 8px 12px;
cursor: pointer;
border: 1px solid transparent;
border-bottom: 1px solid transparent;
margin-bottom: -1px;
background-color: #f0f0f0;

&.active {
background-color: #fff;
border-color: #ccc;
border-bottom-color: #fff;
font-weight: bold;
}
}

.auth-tab-content {
display: none;
overflow-wrap: break-word;
word-wrap: break-word;
max-width: 100%;

&.active {
display: block;
}

pre {
white-space: pre-wrap;
word-wrap: break-word;
overflow-x: auto;
background-color: #f5f5f5;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
max-width: 100%;

code {
display: block;
word-wrap: break-word;
color: inherit;
}
}
}
}
}
}
}

Expand Down
62 changes: 62 additions & 0 deletions internal/server/static/js/toolDisplay.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ function createHeaderEditorModal(toolId, currentHeaders, saveCallback) {
const modalActions = document.createElement('div');
const closeButton = document.createElement('button');
const saveButton = document.createElement('button');
const authTokenDropdown = createAuthTokenInfoDropdown();

modalActions.className = 'header-modal-actions';
closeButton.textContent = 'Close';
Expand All @@ -201,6 +202,7 @@ function createHeaderEditorModal(toolId, currentHeaders, saveCallback) {
modalActions.appendChild(closeButton);
modalActions.appendChild(saveButton);
modalContent.appendChild(modalActions);
modalContent.appendChild(authTokenDropdown);
modal.appendChild(modalContent);

// Close modal if clicked outside
Expand Down Expand Up @@ -233,6 +235,66 @@ function closeHeaderEditor(toolId) {
}
}

/**
* Creates a dropdown element showing information on how to extract Google auth tokens.
* @return {HTMLDetailsElement} The details element representing the dropdown.
*/
function createAuthTokenInfoDropdown() {
const details = document.createElement('details');
const summary = document.createElement('summary');
const content = document.createElement('div');

details.className = 'auth-token-details';
details.appendChild(summary);
summary.textContent = 'How to extract Google OAuth ID Token';
content.className = 'auth-token-content';

// auth instruction dropdown
const tabButtons = document.createElement('div');
const leftTab = document.createElement('button');
const rightTab = document.createElement('button');

tabButtons.className = 'auth-tab-group';
leftTab.className = 'auth-tab-picker active';
leftTab.textContent = 'With Standard Account';
leftTab.setAttribute('data-tab', 'standard');
rightTab.className = 'auth-tab-picker';
rightTab.textContent = 'With Service Account';
rightTab.setAttribute('data-tab', 'service');

tabButtons.appendChild(leftTab);
tabButtons.appendChild(rightTab);
content.appendChild(tabButtons);

const tabContentContainer = document.createElement('div');
const standardTemplate = document.getElementById('auth-token-standard-template');
const standardAccount = document.importNode(standardTemplate.content, true).firstElementChild;
const serviceTemplate = document.getElementById('auth-token-service-template');
const serviceAccount = document.importNode(serviceTemplate.content, true).firstElementChild;

tabContentContainer.appendChild(standardAccount);
tabContentContainer.appendChild(serviceAccount);
content.appendChild(tabContentContainer);

// switching tabs logic
const tabBtns = [leftTab, rightTab];
tabBtns.forEach(btn => {
btn.addEventListener('click', () => {
// deactivate all buttons and contents
tabBtns.forEach(b => b.classList.remove('active'));
content.querySelectorAll('.auth-tab-content').forEach(c => c.classList.remove('active'));

// activate clicked button and corresponding content
btn.classList.add('active');
const tabId = btn.getAttribute('data-tab');
content.querySelector(`#auth-tab-${tabId}`).classList.add('active');
});
});

details.appendChild(content);
return details;
}

/**
* Renders the tool display area.
*/
Expand Down
54 changes: 53 additions & 1 deletion internal/server/static/tools.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,56 @@ <h4>My Tools</h4>
});
</script>
</body>
</html>
</html>

<!-- Templates for inserting token retrieval instructions into edit header modal -->
<template id="auth-token-standard-template">
<div id="auth-tab-standard" class="auth-tab-content active">
<p>To obtain a Google OAuth ID token using a standard account:</p>
<ol>
<li>Make sure you are on your intended standard account. Verify by running the command below.
<pre><code>gcloud auth list</code></pre>
</li>
<li>Within your Cloud Console, add the following link to the "Authorized Redirect URIs".</li>
<pre><code>https://developers.google.com/oauthplayground</code></pre>
<li>Go to the Google OAuth Playground site: <a href="https://developers.google.com/oauthplayground/" target="_blank">https://developers.google.com/oauthplayground/</a></li>
<li>In the top right settings menu, select "Use your own OAuth Credentials".</li>
<li>Input your clientID (from tools file), along with the client secret from Cloud Console.</li>
<li>Inside the Google OAuth Playground, select "Google OAuth2 API v2.</li>
<ul>
<li>Select "Authorize APIs".</li>
<li>Select "Exchange Authorization codes for tokens"</li>
<li>Copy the id_token field provided in the response.</li>
</ul>
<li>Paste this token into the header in JSON editor. The key should be the name of your auth service followed by <code>_token</code>
<pre><code>{
"Content-Type": "application/json",
"my-google-auth_token": "YOUR_ID_TOKEN_HERE"
} </code></pre>
</li>
</ol>
<p>This token is typically short-lived.</p>
</div>
</template>

<template id="auth-token-service-template">
<div id="auth-tab-service" class="auth-tab-content">
<p>To obtain a Google OAuth ID token using a service account:</p>
<ol>
<li>Make sure you are on the intended SERVICE account (typically contain iam.gserviceaccount.com). Verify by running the command below.
<pre><code>gcloud auth list</code></pre>
</li>
<li>Print an id token with the audience set to your clientID defined in tools file:
<pre><code>gcloud auth print-identity-token --audiences=YOUR_CLIENT_ID_HERE</code></pre>
</li>
<li>Copy the output token.</li>
<li>Paste this token into the header in JSON editor. The key should be the name of your auth service followed by <code>_token</code>
<pre><code>{
"Content-Type": "application/json",
"my-google-auth_token": "YOUR_ID_TOKEN_HERE"
} </code></pre>
</li>
</ol>
<p>This token is typically short-lived.</p>
</div>
</template>
Loading