Merge dev into added_docs

This commit is contained in:
Konsti Wohlwend 2025-07-04 04:32:46 -07:00 committed by GitHub
commit daab72c048
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 120 additions and 46 deletions

View File

@ -13,7 +13,7 @@ concurrency:
jobs:
build-server:
name: Docker Build and Push Server
runs-on: ubuntu-latest
runs-on: ubicloud-standard-8
steps:
- name: Checkout
uses: actions/checkout@v4

View File

@ -0,0 +1,56 @@
import time
import requests
import webbrowser
import urllib.parse
def prompt_cli_login(
*,
base_url: str = "https://api.stack-auth.com",
app_url: str,
project_id: str,
publishable_client_key: str,
):
if not app_url:
raise Exception("app_url is required and must be set to the URL of the app you're authenticating with")
if not project_id:
raise Exception("project_id is required")
if not publishable_client_key:
raise Exception("publishable_client_key is required")
def post(endpoint, json):
return requests.request(
'POST',
f'{base_url}{endpoint}',
headers={
'Content-Type': 'application/json',
'x-stack-project-id': project_id,
'x-stack-access-type': 'client',
'x-stack-publishable-client-key': publishable_client_key,
},
json=json,
)
# Step 1: Initiate the CLI auth process
init = post('/api/v1/auth/cli', {
'expires_in_millis': 10 * 60 * 1000,
})
if init.status_code != 200:
raise Exception(f"Failed to initiate CLI auth: {init.status_code} {init.text}")
polling_code = init.json()['polling_code']
login_code = init.json()['login_code']
# Step 2: Open the browser for the user to authenticate
url = f'{app_url}/handler/cli-auth-confirm?login_code={urllib.parse.quote(login_code)}'
print(f"Opening browser to authenticate. If it doesn't open automatically, please visit:\n{url}")
webbrowser.open(url)
# Step 3: Retrieve the token
while True:
status = post('/api/v1/auth/cli/poll', {
'polling_code': polling_code,
})
if status.status_code != 200 and status.status_code != 201:
raise Exception(f"Failed to get CLI auth status: {status.status_code} {status.text}")
if status.json()['status'] == 'success':
return status.json()['refresh_token']
time.sleep(2)

View File

@ -247,56 +247,74 @@ export function ApiSidebarContent({ pages = [] }: { pages?: PageData[] }) {
Overview
</ApiSidebarLink>
{Object.entries(organizedPages).map(([sectionKey, section]) => (
<div key={sectionKey} className="mb-4">
<ApiSeparator>{section.title}</ApiSeparator>
{Object.entries(organizedPages)
.filter(([sectionKey]) => sectionKey !== 'admin') // Hide admin section from sidebar
.sort(([aKey], [bKey]) => {
// Define the desired order of sections
const sectionOrder = ['client', 'server', 'webhooks'];
const aIndex = sectionOrder.indexOf(aKey);
const bIndex = sectionOrder.indexOf(bKey);
// If both sections are in our defined order, sort by that order
if (aIndex !== -1 && bIndex !== -1) {
return aIndex - bIndex;
}
// If only one is in our defined order, prioritize it
if (aIndex !== -1) return -1;
if (bIndex !== -1) return 1;
// If neither is in our defined order, sort alphabetically
//eslint-disable-next-line
return aKey.localeCompare(bKey);
})
.map(([sectionKey, section]) => (
<div key={sectionKey} className="mb-4">
<ApiSeparator>{section.title}</ApiSeparator>
{/* Section-level pages */}
{section.pages.length > 0 && section.pages.map((page: PageData) => (
<ApiSidebarLink
key={page.url}
href={page.url}
method={getHttpMethod(page)}
>
{page.data.title || formatTitle(page.slugs[page.slugs.length - 1])}
</ApiSidebarLink>
))}
{/* Section-level pages */}
{section.pages.length > 0 && section.pages.map((page: PageData) => (
<ApiSidebarLink
key={page.url}
href={page.url}
method={getHttpMethod(page)}
>
{page.data.title || formatTitle(page.slugs[page.slugs.length - 1])}
</ApiSidebarLink>
))}
{/* Grouped pages */}
{Object.entries(section.groups).map(([groupKey, group]: [string, OrganizedGroup]) => (
<CollapsibleSection key={groupKey} title={group.title}>
{group.pages.map((page: PageData) => {
const method = getHttpMethod(page);
const title = page.data.title || formatTitle(page.slugs[page.slugs.length - 1]);
{/* Grouped pages */}
{Object.entries(section.groups).map(([groupKey, group]: [string, OrganizedGroup]) => (
<CollapsibleSection key={groupKey} title={group.title}>
{group.pages.map((page: PageData) => {
const method = getHttpMethod(page);
const title = page.data.title || formatTitle(page.slugs[page.slugs.length - 1]);
// Special handling for webhooks (EVENT badge instead of HTTP method)
if (sectionKey === 'webhooks') {
return (
<ApiSidebarLink key={page.url} href={page.url}>
<div className="flex items-center gap-2">
<span className="inline-flex items-center px-1 py-0.5 rounded text-xs font-medium border bg-purple-100 text-purple-800 border-purple-200 dark:bg-purple-900/30 dark:text-purple-300 dark:border-purple-700 leading-none">
EVENT
</span>
<span>{title}</span>
</div>
</ApiSidebarLink>
);
}
// Special handling for webhooks (EVENT badge instead of HTTP method)
if (sectionKey === 'webhooks') {
return (
<ApiSidebarLink key={page.url} href={page.url}>
<div className="flex items-center gap-2">
<span className="inline-flex items-center px-1 py-0.5 rounded text-xs font-medium border bg-purple-100 text-purple-800 border-purple-200 dark:bg-purple-900/30 dark:text-purple-300 dark:border-purple-700 leading-none">
EVENT
</span>
<span>{title}</span>
</div>
<ApiSidebarLink
key={page.url}
href={page.url}
method={method}
>
{title}
</ApiSidebarLink>
);
}
return (
<ApiSidebarLink
key={page.url}
href={page.url}
method={method}
>
{title}
</ApiSidebarLink>
);
})}
</CollapsibleSection>
))}
</div>
))}
})}
</CollapsibleSection>
))}
</div>
))}
</ScrollViewport>
</ScrollArea>

View File

@ -5,7 +5,7 @@ description: How to authenticate a command line application using Stack Auth
If you're building a command line application that runs in a terminal, you can use Stack Auth to let your users log in to their accounts.
To do so, we provide a Python template that you can use as a starting point. [Download it here](https://github.com/stack-auth/stack-auth/tree/main/docs/examples/stack_auth_cli_template.py) and copy it into your project, for example:
To do so, we provide a Python template that you can use as a starting point. [Download it here](https://github.com/stack-auth/stack-auth/tree/main/docs/public/stack_auth_cli_template.py) and copy it into your project, for example:
```py
└─ my-python-app