@@ -19,6 +19,7 @@ type OrgInfo = {
1919 name : string
2020 image : string | null
2121 plan : 'opensource' | 'team' | 'enterprise'
22+ slug : string
2223}
2324
2425type OrganizationsRecord = {
@@ -42,6 +43,16 @@ async function getOrganizations(apiKey: string): Promise<OrganizationsRecord | n
4243 return orgs
4344}
4445
46+ const orgSlugByApiKey = new Map < string , string > ( )
47+
48+ function getDefaultOrg ( organizations : OrganizationsRecord ) : OrgInfo | null {
49+ const org = Object . values ( organizations . organizations ) [ 0 ]
50+ if ( ! org || ! org . slug ) {
51+ return null
52+ }
53+ return org
54+ }
55+
4556export async function activate ( context : vscode . ExtensionContext , disposables : Array < vscode . Disposable > ) {
4657 //#region file path/watching
4758 // responsible for watching files to know when to sync from disk
@@ -103,12 +114,13 @@ export async function activate(context: vscode.ExtensionContext, disposables: Ar
103114 const sessionOnDisk : typeof liveSessions = new Map < vscode . AuthenticationSession [ 'accessToken' ] , vscode . AuthenticationSession > ( )
104115 if ( typeof apiKey === 'string' && apiKey . length > 0 && apiKey !== SOCKET_PUBLIC_API_TOKEN ) {
105116 const organizations = await getOrganizations ( apiKey )
106- const org = Object . values ( organizations ! . organizations ) [ 0 ]
107- if ( org ) {
117+ const defaultOrg = organizations ? getDefaultOrg ( organizations ) : null
118+ if ( defaultOrg ) {
108119 sessionOnDisk . set (
109120 apiKey ,
110- sessionFromAPIKey ( apiKey , org )
121+ sessionFromAPIKey ( apiKey , defaultOrg )
111122 )
123+ orgSlugByApiKey . set ( apiKey , defaultOrg . slug )
112124 }
113125 }
114126 let added : Array < vscode . AuthenticationSession > = [ ]
@@ -156,23 +168,41 @@ export async function activate(context: vscode.ExtensionContext, disposables: Ar
156168 return Array . from ( liveSessions . values ( ) )
157169 } ,
158170 async createSession ( scopes : readonly string [ ] , options : vscode . AuthenticationProviderSessionOptions ) : Promise < vscode . AuthenticationSession > {
159- let organizations : OrganizationsRecord
171+ let organizations : OrganizationsRecord | null = null
172+ let defaultOrg : OrgInfo | null = null
160173 let apiKey : string = await vscode . window . showInputBox ( {
161174 title : 'Socket Security API Token' ,
162175 placeHolder : 'Leave this blank to stay logged out' ,
163176 ignoreFocusOut : true ,
164177 prompt : 'Enter your API token from https://socket.dev/' ,
165178 async validateInput ( value ) {
166- if ( ! value ) return
167- organizations = ( await getOrganizations ( value ) ) !
168- if ( ! organizations ) return 'Invalid API key'
179+ if ( ! value ) {
180+ return
181+ }
182+
183+ organizations = await getOrganizations ( value )
184+ if ( ! organizations ) {
185+ return 'Invalid API key'
186+ }
187+
188+ defaultOrg = getDefaultOrg ( organizations )
189+ if ( ! defaultOrg ) {
190+ return 'No organizations found for API key'
191+ }
169192 }
170193 } ) ?? ''
171194 if ( ! apiKey ) {
172195 throw new Error ( 'User did not want to provide an API key' )
173196 }
174- const org = Object . values ( organizations ! . organizations ) [ 0 ]
175- const session = sessionFromAPIKey ( apiKey , org )
197+ if ( ! organizations ) {
198+ organizations = await getOrganizations ( apiKey )
199+ }
200+ defaultOrg = defaultOrg ?? ( organizations ? getDefaultOrg ( organizations ) : null )
201+ if ( ! defaultOrg ) {
202+ throw new Error ( 'No organizations found for API key' )
203+ }
204+ const session = sessionFromAPIKey ( apiKey , defaultOrg )
205+ orgSlugByApiKey . set ( apiKey , defaultOrg . slug )
176206 let oldSessions = Array . from ( liveSessions . values ( ) )
177207 await syncLiveSessionToDisk ( session )
178208 liveSessions = new Map ( [
@@ -195,6 +225,7 @@ export async function activate(context: vscode.ExtensionContext, disposables: Ar
195225 fs . unlinkSync ( settingsPath )
196226 } catch { }
197227 if ( session ) {
228+ orgSlugByApiKey . delete ( session . accessToken )
198229 diskSessionsChanges . fire ( {
199230 added : [ ] ,
200231 changed : [ ] ,
@@ -238,6 +269,24 @@ export async function getAPIKey() {
238269 }
239270}
240271
272+ export async function getOrgSlug ( apiKey ?: string ) {
273+ const resolvedApiKey = apiKey ?? await getAPIKey ( )
274+ if ( ! resolvedApiKey || resolvedApiKey === SOCKET_PUBLIC_API_TOKEN ) {
275+ return null
276+ }
277+ const cached = orgSlugByApiKey . get ( resolvedApiKey )
278+ if ( cached ) {
279+ return cached
280+ }
281+ const organizations = await getOrganizations ( resolvedApiKey )
282+ const defaultOrg = organizations ? getDefaultOrg ( organizations ) : null
283+ if ( ! defaultOrg ) {
284+ return null
285+ }
286+ orgSlugByApiKey . set ( resolvedApiKey , defaultOrg . slug )
287+ return defaultOrg . slug
288+ }
289+
241290export function getAuthHeader ( apiKey : string ) {
242291 return `Bearer ${ apiKey } `
243292}
@@ -256,4 +305,3 @@ function sessionFromAPIKey(apiKey: string, org: OrgInfo) {
256305 scopes : [ ] ,
257306 }
258307}
259-
0 commit comments