@@ -179,8 +179,8 @@ defmodule Mix.Tasks.Hex do
179179 Hex.Shell . info ( "Waiting for authentication..." )
180180
181181 case poll_for_token ( device_code , interval ) do
182- { :ok , initial_token } ->
183- exchange_and_store_tokens ( initial_token )
182+ { :ok , token } ->
183+ store_token ( token )
184184
185185 :error ->
186186 :error
@@ -232,108 +232,15 @@ defmodule Mix.Tasks.Hex do
232232 "-" <> String . slice ( user_code , mid , String . length ( user_code ) )
233233 end
234234
235- defp exchange_and_store_tokens ( initial_token ) do
236- # Parse the granted scopes from the initial token
237- granted_scopes = parse_granted_scopes ( initial_token [ "scope" ] || "" )
235+ defp store_token ( token ) do
236+ # Create token data with expiration time
237+ token_data = Hex.OAuth . create_token_data ( token )
238238
239- # Determine what tokens we can create based on granted scopes
240- write_token = create_write_token ( initial_token , granted_scopes )
241- read_token = create_read_token ( initial_token , granted_scopes )
242-
243- # Store the tokens based on what we obtained
244- case { write_token , read_token } do
245- { nil , nil } ->
246- # Couldn't get proper tokens - this is an error condition
247- Hex.Shell . error ( "Failed to obtain proper access tokens" )
248- Hex.Shell . error ( "Please try authenticating again or check your permissions" )
249- :error
250-
251- { write , read } ->
252- tokens = % {
253- "write" => if ( write , do: Hex.OAuth . create_token_data ( write ) ) ,
254- "read" => if ( read , do: Hex.OAuth . create_token_data ( read ) )
255- }
256-
257- Hex.OAuth . store_tokens ( tokens )
258- Hex.Shell . info ( "Authentication completed successfully!" )
259- { :ok , tokens }
260- end
261- end
262-
263- defp parse_granted_scopes ( scope_string ) when is_binary ( scope_string ) do
264- String . split ( scope_string , " " , trim: true )
265- end
266-
267- defp parse_granted_scopes ( _ ) , do: [ ]
268-
269- defp create_write_token ( initial_token , granted_scopes ) do
270- # Check if we have write permission
271- cond do
272- "api" in granted_scopes || "api:write" in granted_scopes ->
273- # We have write permission, exchange for api:write token
274- case Hex.API.OAuth . exchange_token ( initial_token [ "access_token" ] , "api:write" ) do
275- { :ok , { 200 , _ , write_token_response } } ->
276- write_token_response
277-
278- { :ok , { status , _ , error } } ->
279- Hex.Shell . warn ( "Could not exchange for write token (#{ status } ): #{ inspect ( error ) } " )
280- nil
281-
282- { :error , reason } ->
283- Hex.Shell . warn ( "Write token exchange error: #{ inspect ( reason ) } " )
284- nil
285- end
286-
287- true ->
288- # No write permission granted
289- nil
290- end
291- end
292-
293- defp create_read_token ( initial_token , granted_scopes ) do
294- # Always create a separate read token - they have different refresh rates and conditions
295- # Determine what read scopes we can request
296- read_scopes = build_read_scopes ( granted_scopes )
297-
298- if read_scopes != "" do
299- case Hex.API.OAuth . exchange_token ( initial_token [ "access_token" ] , read_scopes ) do
300- { :ok , { 200 , _ , read_token_response } } ->
301- read_token_response
302-
303- { :ok , { status , _ , error } } ->
304- Hex.Shell . warn ( "Could not exchange for read token (#{ status } ): #{ inspect ( error ) } " )
305- nil
306-
307- { :error , reason } ->
308- Hex.Shell . warn ( "Read token exchange error: #{ inspect ( reason ) } " )
309- nil
310- end
311- else
312- # No read scopes available
313- nil
314- end
315- end
316-
317- defp build_read_scopes ( granted_scopes ) do
318- read_scopes = [ ]
319-
320- # Add repositories if granted
321- read_scopes =
322- if "repositories" in granted_scopes do
323- [ "repositories" | read_scopes ]
324- else
325- read_scopes
326- end
327-
328- # Add api:read if we have any API read permission
329- read_scopes =
330- if "api" in granted_scopes || "api:read" in granted_scopes || "api:write" in granted_scopes do
331- [ "api:read" | read_scopes ]
332- else
333- read_scopes
334- end
335-
336- Enum . join ( read_scopes , " " )
239+ # Store a single token for both read and write operations
240+ # With 2FA now required for write operations, we don't need separate tokens
241+ Hex.OAuth . store_token ( token_data )
242+ Hex.Shell . info ( "You are authenticated!" )
243+ { :ok , token_data }
337244 end
338245
339246 @ doc false
@@ -382,25 +289,22 @@ defmodule Mix.Tasks.Hex do
382289
383290 @ doc false
384291 def revoke_existing_oauth_tokens do
385- case Hex.Config . read ( ) [ :"$oauth_tokens " ] do
292+ case Hex.Config . read ( ) [ :"$oauth_token " ] do
386293 nil ->
387294 :ok
388295
389- tokens when is_map ( tokens ) ->
390- Enum . each ( tokens , fn { _type , token_data } ->
391- if access_token = token_data [ "access_token" ] do
392- case Hex.API.OAuth . revoke_token ( access_token ) do
393- { :ok , { code , _ , _ } } when code in 200 .. 299 ->
394- :ok
296+ token_data when is_map ( token_data ) ->
297+ if access_token = token_data [ "access_token" ] do
298+ case Hex.API.OAuth . revoke_token ( access_token ) do
299+ { :ok , { code , _ , _ } } when code in 200 .. 299 ->
300+ :ok
395301
396- _ ->
397- :ok
398- end
302+ _ ->
303+ :ok
399304 end
400- end )
305+ end
401306
402- Hex.Config . remove ( [ :"$oauth_tokens" ] )
403- Hex.Shell . info ( "Revoked existing OAuth tokens." )
307+ Hex.Config . remove ( [ :"$oauth_token" ] )
404308
405309 _ ->
406310 :ok
@@ -414,33 +318,19 @@ defmodule Mix.Tasks.Hex do
414318 # Check for old write key
415319 if write_key = config [ :"$write_key" ] do
416320 # Try to revoke on server (might fail if already revoked or invalid)
417- case Hex.API.Key . delete ( write_key , key: write_key ) do
418- { :ok , { code , _ , _ } } when code in 200 .. 299 ->
419- Hex.Shell . info ( "Revoked old write API key." )
420-
421- _ ->
422- # Key might already be invalid, continue anyway
423- :ok
424- end
321+ _ = Hex.API.Key . delete ( write_key , key: write_key )
425322 end
426323
427324 # Check for old read key (only if different from write key)
428325 if read_key = config [ :"$read_key" ] do
429326 if read_key != config [ :"$write_key" ] do
430- case Hex.API.Key . delete ( read_key , key: read_key ) do
431- { :ok , { code , _ , _ } } when code in 200 .. 299 ->
432- Hex.Shell . info ( "Revoked old read API key." )
433-
434- _ ->
435- :ok
436- end
327+ _ = Hex.API.Key . delete ( read_key , key: read_key )
437328 end
438329 end
439330
440331 # Remove from config if they existed
441332 if config [ :"$write_key" ] || config [ :"$read_key" ] do
442333 Hex.Config . remove ( [ :"$write_key" , :"$read_key" ] )
443- Hex.Shell . info ( "Removed deprecated API keys from config." )
444334 end
445335 end
446336
0 commit comments