@@ -5,6 +5,8 @@ defmodule PlingWeb.RoomLive do
55 alias Pling.Rooms.Presence
66 require Logger
77
8+ @ playlist_id_length 22
9+
810 @ impl true
911 def mount (
1012 % { "room_code" => room_code , "game_mode" => game_mode } = params ,
@@ -116,11 +118,14 @@ defmodule PlingWeb.RoomLive do
116118
117119 @ impl true
118120 def handle_event ( "set_playlist" , % { "playlist_id" => playlist_id } , socket ) do
121+ cleaned_playlist_id = extract_playlist_id ( playlist_id )
122+
119123 { :noreply ,
120124 socket
121125 |> assign ( show_playlist_modal: false )
122126 |> push_patch (
123- to: ~p" /#{ socket . assigns . game_mode } /#{ socket . assigns . room_code } ?list=#{ playlist_id } "
127+ to:
128+ ~p" /#{ socket . assigns . game_mode } /#{ socket . assigns . room_code } ?list=#{ cleaned_playlist_id } "
124129 ) }
125130 end
126131
@@ -426,12 +431,12 @@ defmodule PlingWeb.RoomLive do
426431
427432 < div class = "mt-6 space-y-2 " >
428433 < label class = "text-sm text-gray-600 " > { gettext ( "Or use your own playlist:" ) } </ label >
429- < form class = "flex gap-2 " action = { ~p " / #{ @ game_mode } / #{ @ room_code } " } >
434+ < form class = "flex gap-2 " phx-submit = " set_playlist " >
430435 < . input
431436 type = "text "
432- name = "list "
437+ name = "playlist_id "
433438 value = ""
434- placeholder = { gettext ( "Spotify playlist ID" ) }
439+ placeholder = { gettext ( "Spotify playlist link or ID" ) }
435440 autocomplete = "off "
436441 />
437442 < . button type = "submit " >
@@ -464,10 +469,12 @@ defmodule PlingWeb.RoomLive do
464469 end
465470
466471 defp handle_playlist_join ( room_code , user_id , game_mode , playlist_id ) do
467- case Pling.Playlists.MusicLibrary . get_or_fetch_playlist ( playlist_id ) do
472+ cleaned_playlist_id = extract_playlist_id ( playlist_id )
473+
474+ case Pling.Playlists.MusicLibrary . get_or_fetch_playlist ( cleaned_playlist_id ) do
468475 { :ok , :first_track_saved , playlist } ->
469476 { :ok , _state } = Rooms . join_room ( room_code , user_id , self ( ) , game_mode , playlist )
470- { :ok , state } = Rooms . set_playlist ( room_code , playlist_id )
477+ { :ok , state } = Rooms . set_playlist ( room_code , cleaned_playlist_id )
471478 state
472479
473480 { :ok , _ , playlist } ->
@@ -479,9 +486,34 @@ defmodule PlingWeb.RoomLive do
479486 end
480487 end
481488
489+ defp extract_playlist_id ( "https://open.spotify.com/playlist/" <> potential_id ) do
490+ potential_id = String . slice ( potential_id , 0 , @ playlist_id_length )
491+ validate_playlist_id ( potential_id )
492+ end
493+
494+ defp extract_playlist_id ( potential_id ) when is_binary ( potential_id ) do
495+ validate_playlist_id ( potential_id )
496+ end
497+
498+ defp extract_playlist_id ( _ ) , do: nil
499+
500+ # IDs are 22 chars
501+ defp validate_playlist_id ( id ) do
502+ if byte_size ( id ) == @ playlist_id_length and id =~ ~r/ ^[a-zA-Z0-9]{#{ @ playlist_id_length } }$/ do
503+ id
504+ else
505+ nil
506+ end
507+ end
508+
482509 @ impl true
483510 def handle_params ( % { "list" => playlist_id } , _uri , socket ) do
484- Rooms . set_playlist ( socket . assigns . room_code , playlist_id )
511+ cleaned_playlist_id = extract_playlist_id ( playlist_id )
512+
513+ if cleaned_playlist_id do
514+ Rooms . set_playlist ( socket . assigns . room_code , cleaned_playlist_id )
515+ end
516+
485517 { :noreply , socket }
486518 end
487519
0 commit comments