2023-11-16 17:23:35 -08:00
|
|
|
import React, { useCallback } from "react"
|
|
|
|
import { apiFetch } from "src/api"
|
2023-10-25 17:58:53 -04:00
|
|
|
import { NodeData } from "src/hooks/node-data"
|
|
|
|
import { ReactComponent as TailscaleIcon } from "src/icons/tailscale-icon.svg"
|
|
|
|
|
|
|
|
/**
|
2023-11-16 17:23:35 -08:00
|
|
|
* LoginView is rendered when the client is not authenticated
|
2023-10-25 17:58:53 -04:00
|
|
|
* to a tailnet.
|
|
|
|
*/
|
2023-11-16 17:23:35 -08:00
|
|
|
export default function LoginView({
|
2023-10-25 17:58:53 -04:00
|
|
|
data,
|
2023-11-16 17:23:35 -08:00
|
|
|
refreshData,
|
2023-10-25 17:58:53 -04:00
|
|
|
}: {
|
|
|
|
data: NodeData
|
2023-11-16 17:23:35 -08:00
|
|
|
refreshData: () => void
|
2023-10-25 17:58:53 -04:00
|
|
|
}) {
|
2023-11-16 17:23:35 -08:00
|
|
|
const login = useCallback(
|
|
|
|
(opt: TailscaleUpOptions) => {
|
|
|
|
tailscaleUp(opt).then(refreshData)
|
|
|
|
},
|
|
|
|
[refreshData]
|
|
|
|
)
|
|
|
|
|
2023-10-25 17:58:53 -04:00
|
|
|
return (
|
|
|
|
<div className="mb-8 py-6 px-8 bg-white rounded-md shadow-2xl">
|
|
|
|
<TailscaleIcon className="my-2 mb-8" />
|
2023-11-16 17:23:35 -08:00
|
|
|
{data.Status == "Stopped" ? (
|
|
|
|
<>
|
|
|
|
<div className="mb-6">
|
|
|
|
<h3 className="text-3xl font-semibold mb-3">Connect</h3>
|
|
|
|
<p className="text-gray-700">
|
|
|
|
Your device is disconnected from Tailscale.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<button
|
|
|
|
onClick={() => login({})}
|
|
|
|
className="button button-blue w-full mb-4"
|
|
|
|
>
|
|
|
|
Connect to Tailscale
|
|
|
|
</button>
|
|
|
|
</>
|
|
|
|
) : data.IP ? (
|
2023-10-25 17:58:53 -04:00
|
|
|
<>
|
|
|
|
<div className="mb-6">
|
|
|
|
<p className="text-gray-700">
|
|
|
|
Your device's key has expired. Reauthenticate this device by
|
|
|
|
logging in again, or{" "}
|
|
|
|
<a
|
|
|
|
href="https://tailscale.com/kb/1028/key-expiry"
|
|
|
|
className="link"
|
|
|
|
target="_blank"
|
|
|
|
>
|
|
|
|
learn more
|
|
|
|
</a>
|
|
|
|
.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<button
|
2023-11-16 17:23:35 -08:00
|
|
|
onClick={() => login({ Reauthenticate: true })}
|
2023-10-25 17:58:53 -04:00
|
|
|
className="button button-blue w-full mb-4"
|
|
|
|
>
|
|
|
|
Reauthenticate
|
|
|
|
</button>
|
|
|
|
</>
|
|
|
|
) : (
|
|
|
|
<>
|
|
|
|
<div className="mb-6">
|
|
|
|
<h3 className="text-3xl font-semibold mb-3">Log in</h3>
|
|
|
|
<p className="text-gray-700">
|
|
|
|
Get started by logging in to your Tailscale network.
|
|
|
|
Or, learn more at{" "}
|
|
|
|
<a href="https://tailscale.com/" className="link" target="_blank">
|
|
|
|
tailscale.com
|
|
|
|
</a>
|
|
|
|
.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<button
|
2023-11-16 17:23:35 -08:00
|
|
|
onClick={() => login({ Reauthenticate: true })}
|
2023-10-25 17:58:53 -04:00
|
|
|
className="button button-blue w-full mb-4"
|
|
|
|
>
|
|
|
|
Log In
|
|
|
|
</button>
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
2023-11-16 17:23:35 -08:00
|
|
|
|
|
|
|
type TailscaleUpOptions = {
|
|
|
|
Reauthenticate?: boolean // force reauthentication
|
|
|
|
}
|
|
|
|
|
|
|
|
function tailscaleUp(options: TailscaleUpOptions) {
|
|
|
|
return apiFetch("/up", "POST", options)
|
|
|
|
.then((r) => r.json())
|
|
|
|
.then((d) => {
|
|
|
|
d.url && window.open(d.url, "_blank")
|
|
|
|
})
|
|
|
|
.catch((e) => {
|
|
|
|
console.error("Failed to login:", e)
|
|
|
|
})
|
|
|
|
}
|