Skip to content

Commit c6397c8

Browse files
jottakkaFrancisco Liberal
andauthored
[TOO-272] Adding scope infos for Google OAuth docs (#611)
* [TOO-272] Adding scopes Google OAuth tools docs * auto fixed files * fixing bugs --------- Co-authored-by: Francisco Liberal <[email protected]>
1 parent 0213c8c commit c6397c8

File tree

132 files changed

+1079
-8
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+1079
-8
lines changed

app/_components/scope-picker.tsx

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
5+
interface Tool {
6+
name: string;
7+
scopes: string[];
8+
}
9+
10+
interface ScopePickerProps {
11+
tools: Tool[];
12+
}
13+
14+
export default function ScopePicker({ tools }: ScopePickerProps) {
15+
const [selectedTools, setSelectedTools] = useState<Set<string>>(new Set());
16+
17+
const toggleTool = (toolName: string) => {
18+
const newSelected = new Set(selectedTools);
19+
if (newSelected.has(toolName)) {
20+
newSelected.delete(toolName);
21+
} else {
22+
newSelected.add(toolName);
23+
}
24+
setSelectedTools(newSelected);
25+
};
26+
27+
const selectAll = () => {
28+
setSelectedTools(new Set(tools.map((t) => t.name)));
29+
};
30+
31+
const clearAll = () => {
32+
setSelectedTools(new Set());
33+
};
34+
35+
// Get unique scopes from selected tools
36+
const requiredScopes = Array.from(
37+
new Set(
38+
tools.filter((t) => selectedTools.has(t.name)).flatMap((t) => t.scopes)
39+
)
40+
).sort();
41+
42+
return (
43+
<div className="my-6 overflow-hidden rounded-lg border border-gray-200 dark:border-gray-700">
44+
<div className="border-gray-200 border-b bg-gray-50 px-4 py-3 dark:border-gray-700 dark:bg-gray-800">
45+
<div className="flex items-center justify-between">
46+
<h3 className="font-semibold text-gray-900 text-sm dark:text-gray-100">
47+
Scope calculator
48+
</h3>
49+
<div className="flex gap-2">
50+
<button
51+
className="rounded bg-blue-100 px-2 py-1 text-blue-700 text-xs transition-colors hover:bg-blue-200 dark:bg-blue-900 dark:text-blue-300 dark:hover:bg-blue-800"
52+
onClick={selectAll}
53+
>
54+
Select all
55+
</button>
56+
<button
57+
className="rounded bg-gray-100 px-2 py-1 text-gray-600 text-xs transition-colors hover:bg-gray-200 dark:bg-gray-700 dark:text-gray-400 dark:hover:bg-gray-600"
58+
onClick={clearAll}
59+
>
60+
Clear
61+
</button>
62+
</div>
63+
</div>
64+
<p className="mt-1 text-gray-500 text-xs dark:text-gray-400">
65+
Select the tools you plan to use to see the required OAuth scopes.
66+
</p>
67+
</div>
68+
69+
<div className="p-4">
70+
<div className="mb-4 grid grid-cols-1 gap-2 sm:grid-cols-2">
71+
{tools.map((tool) => (
72+
<label
73+
className={`flex cursor-pointer items-center gap-2 rounded p-2 transition-colors ${
74+
selectedTools.has(tool.name)
75+
? "border border-blue-200 bg-blue-50 dark:border-blue-700 dark:bg-blue-900/30"
76+
: "border border-gray-200 bg-gray-50 hover:bg-gray-100 dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700"
77+
}`}
78+
key={tool.name}
79+
>
80+
<input
81+
checked={selectedTools.has(tool.name)}
82+
className="rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600"
83+
onChange={() => toggleTool(tool.name)}
84+
type="checkbox"
85+
/>
86+
<span className="text-gray-700 text-sm dark:text-gray-300">
87+
{tool.name}
88+
</span>
89+
</label>
90+
))}
91+
</div>
92+
93+
<div className="border-gray-200 border-t pt-4 dark:border-gray-700">
94+
<h4 className="mb-2 font-medium text-gray-900 text-sm dark:text-gray-100">
95+
Required scopes{" "}
96+
{selectedTools.size > 0 && (
97+
<span className="font-normal text-gray-500 dark:text-gray-400">
98+
({requiredScopes.length})
99+
</span>
100+
)}
101+
</h4>
102+
{requiredScopes.length > 0 ? (
103+
<ul className="space-y-1">
104+
{requiredScopes.map((scope) => (
105+
<li
106+
className="rounded bg-gray-100 px-2 py-1 font-mono text-gray-700 text-xs dark:bg-gray-800 dark:text-gray-300"
107+
key={scope}
108+
>
109+
{scope}
110+
</li>
111+
))}
112+
</ul>
113+
) : (
114+
<p className="text-gray-500 text-sm italic dark:text-gray-400">
115+
Select tools above to see required scopes
116+
</p>
117+
)}
118+
</div>
119+
</div>
120+
</div>
121+
);
122+
}

app/en/home/auth-providers/google/page.mdx

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,57 @@ This auth provider is used by:
2222

2323
## Configuring Google auth
2424

25+
You can either use Arcade's default Google OAuth provider (fastest way to get started), or configure your own Google OAuth provider for production.
26+
27+
## Arcade's default Google OAuth provider
28+
29+
Arcade provides a default Google OAuth provider (the Arcade-managed Google app) that you can use to quickly get started. This provider supports a fixed set of scopes and is shared across all Arcade users.
30+
31+
### Supported scopes
32+
33+
The default Arcade Google OAuth provider supports the following scopes:
34+
35+
- `https://www.googleapis.com/auth/calendar.readonly`
36+
- `https://www.googleapis.com/auth/calendar.events`
37+
- `https://www.googleapis.com/auth/calendar.events.readonly`
38+
- `https://www.googleapis.com/auth/calendar.settings.readonly`
39+
- `https://www.googleapis.com/auth/contacts`
40+
- `https://www.googleapis.com/auth/contacts.readonly`
41+
- `https://www.googleapis.com/auth/drive.file`
42+
- `https://www.googleapis.com/auth/gmail.readonly`
43+
- `https://www.googleapis.com/auth/gmail.compose`
44+
- `https://www.googleapis.com/auth/gmail.send`
45+
- `https://www.googleapis.com/auth/gmail.modify`
46+
- `https://www.googleapis.com/auth/gmail.labels`
47+
- `https://www.googleapis.com/auth/userinfo.email`
48+
- `https://www.googleapis.com/auth/userinfo.profile`
49+
- `openid`
50+
51+
<Callout type="warning">
52+
If you try to use a scope that is not in this list with the default Arcade Google provider, you will get a `400 invalid authorization challenge: requesting unsupported scopes` error. For example, scopes like `https://www.googleapis.com/auth/drive.readonly` are not supported.
53+
54+
To use scopes beyond this list, you must create your own Google OAuth provider (see below).
55+
</Callout>
56+
57+
### Limitations
58+
59+
The default provider has some limitations:
60+
61+
- **Fixed scope list**: You can only use the scopes listed above
62+
- **Shared rate limits**: All Arcade users share the same rate limits
63+
- **Arcade branding**: Your users will see "Arcade" as the requesting application
64+
65+
<Callout type="info">
66+
For production use, we strongly recommend creating your own Google OAuth provider. This gives you:
67+
68+
- Full control over which scopes to request
69+
- Dedicated rate limits for your application
70+
- Your own branding in the OAuth consent screen
71+
- Better security and compliance with your organization's policies
72+
</Callout>
73+
74+
## Configuring your own Google OAuth provider
75+
2576
<Callout type="info">
2677
When using your own app credentials, make sure you configure your project to
2778
use a [custom user
@@ -40,14 +91,15 @@ Before showing how to configure your Google app credentials, let's go through th
4091
- Follow Google's guide to [setting up OAuth credentials](https://support.google.com/cloud/answer/6158849?hl=en)
4192
- Choose the [scopes](https://developers.google.com/identity/protocols/oauth2/scopes) (permissions) you need for your app
4293
- At a minimum, you must enable these scopes:
94+
4395
- `https://www.googleapis.com/auth/userinfo.email`
4496
- `https://www.googleapis.com/auth/userinfo.profile`
4597
- Add the redirect URL generated by Arcade (see below) to the Authorized redirect URIs list
4698
- Copy the client ID and client secret to use below
4799

48100
Next, add the Google app to Arcade.
49101

50-
## Configuring your own Google Auth Provider in Arcade
102+
### Setting up your Google OAuth provider in Arcade
51103

52104

53105
<Tabs items={["Dashboard GUI"]}>

app/en/home/landing-page.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ export function LandingPage() {
4040
<section className="relative isolate px-6 lg:px-8">
4141
<div
4242
aria-hidden="true"
43-
className="-top-24 -z-10 sm:-top-40 absolute inset-x-0 transform-gpu overflow-hidden blur-3xl"
43+
className="absolute inset-x-0 -top-24 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-40"
4444
>
4545
<div
46-
className="-translate-x-1/2 relative left-[calc(50%-11rem)] aspect-[1155/678] w-[24rem] rotate-[30deg] bg-gradient-to-tr from-[#ee175e] to-[#9089fc] opacity-20 sm:left-[calc(50%-30rem)] sm:w-[48rem]"
46+
className="relative left-[calc(50%-11rem)] aspect-[1155/678] w-[24rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#ee175e] to-[#9089fc] opacity-20 sm:left-[calc(50%-30rem)] sm:w-[48rem]"
4747
style={{
4848
clipPath:
4949
"polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)",
@@ -148,10 +148,10 @@ export function LandingPage() {
148148
</div>
149149
<div
150150
aria-hidden="true"
151-
className="-z-10 absolute inset-x-0 top-[calc(100%-13rem)] transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]"
151+
className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]"
152152
>
153153
<div
154-
className="-translate-x-1/2 relative left-[calc(50%+3rem)] aspect-[1155/678] w-[24rem] bg-gradient-to-tr from-[#ee175e] to-[#9089fc] opacity-20 sm:left-[calc(50%+36rem)] sm:w-[48rem]"
154+
className="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[24rem] -translate-x-1/2 bg-gradient-to-tr from-[#ee175e] to-[#9089fc] opacity-20 sm:left-[calc(50%+36rem)] sm:w-[48rem]"
155155
style={{
156156
clipPath:
157157
"polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)",

app/en/mcp-servers/components/filters-bar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export function FiltersBar({ resultsCount }: FiltersBarProps) {
5454
<div className="flex flex-wrap items-center justify-between gap-3">
5555
{/* Search */}
5656
<div className="relative w-full flex-1 sm:min-w-[200px] sm:max-w-md">
57-
<Search className="-translate-y-1/2 absolute top-1/2 left-3 h-4 w-4 text-gray-500 dark:text-gray-400" />
57+
<Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-500 dark:text-gray-400" />
5858
<Input
5959
className="pr-9 pl-9"
6060
onChange={handleSearchChange}
@@ -65,7 +65,7 @@ export function FiltersBar({ resultsCount }: FiltersBarProps) {
6565
{searchQuery && (
6666
<button
6767
aria-label="Clear search"
68-
className="-translate-y-1/2 absolute top-1/2 right-3 text-gray-500 transition-colors hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
68+
className="absolute top-1/2 right-3 -translate-y-1/2 text-gray-500 transition-colors hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
6969
onClick={() => setSearchQuery("")}
7070
type="button"
7171
>

0 commit comments

Comments
 (0)