Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4b58ea4

Browse files
committed
Add proper scopes
1 parent0cfb3e4 commit4b58ea4

File tree

1 file changed

+82
-14
lines changed

1 file changed

+82
-14
lines changed

‎src/oauth/oauthHelper.ts‎

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,28 @@ const CLIENT_NAME = "VS Code Coder Extension";
3030

3131
constREQUIRED_GRANT_TYPES=[AUTH_GRANT_TYPE,REFRESH_GRANT_TYPE]asconst;
3232

33-
// Token refresh timing constants
34-
constTOKEN_REFRESH_THRESHOLD_MS=5*60*1000;// 5 minutes before expiry
33+
// Token refresh timing constants (5 minutes before expiry)
34+
constTOKEN_REFRESH_THRESHOLD_MS=5*60*1000;
35+
36+
/**
37+
* Minimal scopes required by the VS Code extension:
38+
* - workspace:read: List and read workspace details
39+
* - workspace:update: Update workspace version
40+
* - workspace:start: Start stopped workspaces
41+
* - workspace:ssh: SSH configuration for remote connections
42+
* - workspace:application_connect: Connect to workspace agents/apps
43+
* - template:read: Read templates and versions
44+
* - user:read_personal: Read authenticated user info
45+
*/
46+
constDEFAULT_OAUTH_SCOPES=[
47+
"workspace:read",
48+
"workspace:update",
49+
"workspace:start",
50+
"workspace:ssh",
51+
"workspace:application_connect",
52+
"template:read",
53+
"user:read_personal",
54+
].join(" ");
3555

3656
exportclassCoderOAuthHelper{
3757
privateclientRegistration:ClientRegistrationResponse|undefined;
@@ -156,9 +176,22 @@ export class CoderOAuthHelper {
156176
privateasyncloadTokens():Promise<void>{
157177
consttokens=awaitthis.secretsManager.getOAuthTokens();
158178
if(tokens){
179+
if(!this.hasRequiredScopes(tokens.scope)){
180+
this.logger.warn(
181+
"Stored token missing required scopes, clearing tokens",
182+
{
183+
stored_scope:tokens.scope,
184+
required_scopes:DEFAULT_OAUTH_SCOPES,
185+
},
186+
);
187+
awaitthis.secretsManager.clearOAuthTokens();
188+
return;
189+
}
190+
159191
this.storedTokens=tokens;
160192
this.logger.info("Loaded stored OAuth tokens",{
161193
expires_at:newDate(tokens.expiry_timestamp).toISOString(),
194+
scope:tokens.scope,
162195
});
163196

164197
if(tokens.refresh_token){
@@ -167,6 +200,40 @@ export class CoderOAuthHelper {
167200
}
168201
}
169202

203+
/**
204+
* Check if granted scopes cover all required scopes.
205+
* Supports wildcard scopes like "workspace:*" which grant all "workspace:" prefixed scopes.
206+
*/
207+
privatehasRequiredScopes(grantedScope:string|undefined):boolean{
208+
if(!grantedScope){
209+
returnfalse;
210+
}
211+
212+
constgrantedScopes=newSet(grantedScope.split(" "));
213+
constrequiredScopes=DEFAULT_OAUTH_SCOPES.split(" ");
214+
215+
for(constrequiredofrequiredScopes){
216+
// Check exact match
217+
if(grantedScopes.has(required)){
218+
continue;
219+
}
220+
221+
// Check wildcard match (e.g., "workspace:*" grants "workspace:read")
222+
constcolonIndex=required.indexOf(":");
223+
if(colonIndex!==-1){
224+
constprefix=required.substring(0,colonIndex);
225+
constwildcard=`${prefix}:*`;
226+
if(grantedScopes.has(wildcard)){
227+
continue;
228+
}
229+
}
230+
231+
returnfalse;
232+
}
233+
234+
returntrue;
235+
}
236+
170237
privateasyncsaveClientRegistration(
171238
registration:ClientRegistrationResponse,
172239
):Promise<void>{
@@ -231,16 +298,19 @@ export class CoderOAuthHelper {
231298
clientId:string,
232299
state:string,
233300
challenge:string,
234-
scope="all",
301+
scope:string,
235302
):string{
236-
if(
237-
metadata.scopes_supported&&
238-
!metadata.scopes_supported.includes(scope)
239-
){
240-
this.logger.warn(
241-
`Requested scope "${scope}" not in server's supported scopes. Server may still accept it.`,
242-
{supported_scopes:metadata.scopes_supported},
303+
if(metadata.scopes_supported){
304+
constrequestedScopes=scope.split(" ");
305+
constunsupportedScopes=requestedScopes.filter(
306+
(s)=>!metadata.scopes_supported?.includes(s),
243307
);
308+
if(unsupportedScopes.length>0){
309+
this.logger.warn(
310+
`Requested scopes not in server's supported scopes:${unsupportedScopes.join(", ")}. Server may still accept them.`,
311+
{supported_scopes:metadata.scopes_supported},
312+
);
313+
}
244314
}
245315

246316
constparams:AuthorizationRequestParams={
@@ -264,9 +334,7 @@ export class CoderOAuthHelper {
264334
returnurl;
265335
}
266336

267-
asyncstartAuthorization(
268-
scope="all",
269-
):Promise<{code:string;verifier:string}>{
337+
asyncstartAuthorization():Promise<{code:string;verifier:string}>{
270338
constmetadata=awaitthis.getMetadata();
271339
constclientId=awaitthis.registerClient();
272340
conststate=generateState();
@@ -277,7 +345,7 @@ export class CoderOAuthHelper {
277345
clientId,
278346
state,
279347
challenge,
280-
scope,
348+
DEFAULT_OAUTH_SCOPES,
281349
);
282350

283351
returnnewPromise<{code:string;verifier:string}>(

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp