1- <!DOCTYPE html>
2- < html >
3- < head >
4- < title >
5- {{if .IsNew}}Add New Client{{else}}Edit Client{{end}} - Tailscale OIDC Identity Provider
6- </ title >
7- < link rel ="stylesheet " type ="text/css " href ="/style.css " />
8- < meta name ="viewport " content ="width=device-width, initial-scale=1.0 " />
9- </ head >
10-
11- < body >
12- {{template "header"}}
13-
1+ {{define "content"}}
142 < main >
153 < div class ="form-container ">
164 < div class ="form-header ">
3624 < div class ="client-info ">
3725 < h3 > Client Created Successfully!</ h3 >
3826 < p class ="warning "> ⚠️ Save both the Client ID and Secret now! The secret will not be shown again.</ p >
39-
40- < div class ="form-group ">
27+
28+ < div class ="form-group ">
4129 < label > Client ID</ label >
4230 < div class ="secret-field ">
43- < input type ="text " value ="{{.ID}} " readonly class ="secret-input " id =" client-id ">
44- < button type ="button " onclick ="copyClientId(event ) " class ="btn btn-secondary btn-small "> Copy</ button >
31+ < input type ="text " value ="{{.ID}} " readonly class ="secret-input " aria-label =" Client ID ">
32+ < button type ="button " onclick ="copyValue(this.previousElementSibling, this ) " class ="btn btn-secondary btn-small "> Copy</ button >
4533 </ div >
4634 </ div >
47-
35+
4836 < div class ="form-group ">
4937 < label > Client Secret</ label >
5038 < div class ="secret-field ">
51- < input type ="text " value ="{{.Secret}} " readonly class ="secret-input " id =" client-secret ">
52- < button type ="button " onclick ="copySecret(event ) " class ="btn btn-secondary btn-small "> Copy</ button >
39+ < input type ="text " value ="{{.Secret}} " readonly class ="secret-input " aria-label =" Client Secret ">
40+ < button type ="button " onclick ="copyValue(this.previousElementSibling, this ) " class ="btn btn-secondary btn-small "> Copy</ button >
5341 </ div >
5442 </ div >
5543 </ div >
@@ -60,20 +48,20 @@ <h3>Client Created Successfully!</h3>
6048 < h3 > New Client Secret</ h3 >
6149 < p class ="warning "> ⚠️ Save this secret now! It will not be shown again.</ p >
6250 < div class ="secret-field ">
63- < input type ="text " value ="{{.Secret}} " readonly class ="secret-input " id =" client-secret ">
64- < button type ="button " onclick ="copySecret(event ) " class ="btn btn-secondary btn-small "> Copy</ button >
51+ < input type ="text " value ="{{.Secret}} " readonly class ="secret-input " aria-label =" Client Secret ">
52+ < button type ="button " onclick ="copyValue(this.previousElementSibling, this ) " class ="btn btn-secondary btn-small "> Copy</ button >
6553 </ div >
6654 </ div >
6755 {{end}}
6856
6957 < form method ="POST " class ="client-form ">
7058 < div class ="form-group ">
7159 < label for ="name "> Client Name</ label >
72- < input
73- type ="text "
74- id ="name "
75- name ="name "
76- value ="{{.Name}} "
60+ < input
61+ type ="text "
62+ id ="name "
63+ name ="name "
64+ value ="{{.Name}} "
7765 placeholder ="e.g., My Application "
7866 class ="form-input "
7967 >
@@ -84,9 +72,9 @@ <h3>New Client Secret</h3>
8472
8573 < div class ="form-group ">
8674 < label for ="redirect_uris "> Redirect URIs < span class ="required "> *</ span > </ label >
87- < textarea
88- id ="redirect_uris "
89- name ="redirect_uris "
75+ < textarea
76+ id ="redirect_uris "
77+ name ="redirect_uris "
9078 placeholder ="https://example.com/auth/callback https://example.com/oauth/callback "
9179 class ="form-input "
9280 rows ="4 "
@@ -100,10 +88,10 @@ <h3>New Client Secret</h3>
10088 {{if .IsEdit}}
10189 < div class ="form-group ">
10290 < label > Client ID</ label >
103- < input
104- type ="text "
105- value ="{{.ID}} "
106- readonly
91+ < input
92+ type ="text "
93+ value ="{{.ID}} "
94+ readonly
10795 class ="form-input form-input-readonly "
10896 >
10997 < div class ="form-help ">
@@ -116,14 +104,14 @@ <h3>New Client Secret</h3>
116104 < button type ="submit " class ="btn btn-primary ">
117105 {{if .IsNew}}Create Client{{else}}Update Client{{end}}
118106 </ button >
119-
107+
120108 {{if .IsEdit}}
121- < button type ="submit " name ="action " value ="regenerate_secret " class ="btn btn-warning "
109+ < button type ="submit " name ="action " value ="regenerate_secret " class ="btn btn-warning "
122110 onclick ="return confirm('Are you sure you want to regenerate the client secret? The old secret will stop working immediately.') ">
123111 Regenerate Secret
124112 </ button >
125-
126- < button type ="submit " name ="action " value ="delete " class ="btn btn-danger "
113+
114+ < button type ="submit " name ="action " value ="delete " class ="btn btn-danger "
127115 onclick ="return confirm('Are you sure you want to delete this client? This cannot be undone.') ">
128116 Delete Client
129117 </ button >
@@ -152,47 +140,22 @@ <h3>Client Information</h3>
152140 </ main >
153141
154142 < script >
155- function copySecret ( event ) {
156- const secretInput = document . getElementById ( 'client-secret' ) ;
157- secretInput . select ( ) ;
158- secretInput . setSelectionRange ( 0 , 99999 ) ; // For mobile devices
159-
160- navigator . clipboard . writeText ( secretInput . value ) . then ( function ( ) {
161- const button = event . target ;
162- const originalText = button . textContent ;
163- button . textContent = 'Copied!' ;
164- button . classList . add ( 'btn-success' ) ;
165-
166- setTimeout ( function ( ) {
167- button . textContent = originalText ;
168- button . classList . remove ( 'btn-success' ) ;
169- } , 2000 ) ;
170- } ) . catch ( function ( err ) {
171- console . error ( 'Failed to copy: ' , err ) ;
172- alert ( 'Failed to copy to clipboard. Please copy manually.' ) ;
173- } ) ;
174- }
175-
176- function copyClientId ( event ) {
177- const clientIdInput = document . getElementById ( 'client-id' ) ;
178- clientIdInput . select ( ) ;
179- clientIdInput . setSelectionRange ( 0 , 99999 ) ; // For mobile devices
180-
181- navigator . clipboard . writeText ( clientIdInput . value ) . then ( function ( ) {
182- const button = event . target ;
143+ function copyValue ( input , button ) {
144+ input . select ( ) ;
145+ input . setSelectionRange ( 0 , 99999 ) ; // For mobile devices
146+
147+ navigator . clipboard . writeText ( input . value ) . then ( function ( ) {
183148 const originalText = button . textContent ;
184149 button . textContent = 'Copied!' ;
185150 button . classList . add ( 'btn-success' ) ;
186-
151+
187152 setTimeout ( function ( ) {
188153 button . textContent = originalText ;
189154 button . classList . remove ( 'btn-success' ) ;
190155 } , 2000 ) ;
191- } ) . catch ( function ( err ) {
192- console . error ( 'Failed to copy: ' , err ) ;
156+ } ) . catch ( function ( ) {
193157 alert ( 'Failed to copy to clipboard. Please copy manually.' ) ;
194158 } ) ;
195159 }
196160 </ script >
197- </ body >
198- </ html >
161+ {{end}}
0 commit comments