feat: rendering auth page, added google & gitlab
This commit is contained in:
parent
a8cbdeada0
commit
dd5d255742
|
@ -546,18 +546,10 @@ video {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-auto {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-1 {
|
.flex-1 {
|
||||||
flex: 1 1 0%;
|
flex: 1 1 0%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grow {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-row {
|
.flex-row {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
@ -586,10 +578,6 @@ video {
|
||||||
border-width: 4px;
|
border-width: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.border {
|
|
||||||
border-width: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-b-8 {
|
.border-b-8 {
|
||||||
border-bottom-width: 8px;
|
border-bottom-width: 8px;
|
||||||
}
|
}
|
||||||
|
@ -599,11 +587,6 @@ video {
|
||||||
border-color: rgb(96 165 250 / var(--tw-border-opacity));
|
border-color: rgb(96 165 250 / var(--tw-border-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-black {
|
|
||||||
--tw-border-opacity: 1;
|
|
||||||
border-color: rgb(0 0 0 / var(--tw-border-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-blue-100 {
|
.bg-blue-100 {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(219 234 254 / var(--tw-bg-opacity));
|
background-color: rgb(219 234 254 / var(--tw-bg-opacity));
|
||||||
|
|
|
@ -21,26 +21,46 @@
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
|
||||||
<main class="bg-blue-100 h-screen w-screen grid place-content-center">
|
<main class="bg-blue-100 h-screen w-screen grid place-content-center">
|
||||||
<section class="p-32 border-4 border-b-8 border-blue-400 bg-blue-50 rounded-xl grid gap-4">
|
<section
|
||||||
<h2
|
class="p-32 border-4 border-b-8 border-blue-400 bg-blue-50 rounded-xl grid gap-4"
|
||||||
class="text-2xl text-blue-400 font-bold"
|
>
|
||||||
>Authorizatoin options</h2>
|
<h2 class="text-2xl text-blue-400 font-bold">Authorizatoin options</h2>
|
||||||
<div class="flex flex-row justify-center gap-2">
|
<div class="flex flex-row justify-center gap-2">
|
||||||
<img src="../public/icons/github-svgrepo-com(1).svg" alt="log in via github"
|
<a th:each="oauthProvider: ${oauthProvidersList}"
|
||||||
class="w-10 h-10"
|
href="#"
|
||||||
/>
|
th:href="|${oauthProvider.authUrl}${redirectUrl.get(oauthProvider.name)}|"
|
||||||
<img src="../public/icons/apple-svgrepo-com.svg" alt="log in via github"
|
>
|
||||||
class="w-10 h-10"
|
<img
|
||||||
/>
|
src="../public/icons/github-svgrepo-com(1).svg"
|
||||||
<img src="../public/icons/google-svgrepo-com.svg" alt="log in via github"
|
th:src="${iconLocationsMap.get(oauthProvider.name)}"
|
||||||
class="w-10 h-10"
|
alt="log in via github"
|
||||||
/>
|
class="w-10 h-10"
|
||||||
<img src="../public/icons/facebook-f-svgrepo-com.svg" alt="log in via github"
|
|
||||||
class="w-10 h-10"
|
|
||||||
/>
|
|
||||||
<img src="../public/icons/gitlab-svgrepo-com(1).svg" alt="log in via github"
|
|
||||||
class="w-10 h-10"
|
|
||||||
/>
|
/>
|
||||||
|
</a>
|
||||||
|
<img
|
||||||
|
src="../public/icons/apple-svgrepo-com.svg"
|
||||||
|
alt="log in via github"
|
||||||
|
class="w-10 h-10"
|
||||||
|
th:remove="all"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="../public/icons/google-svgrepo-com.svg"
|
||||||
|
alt="log in via github"
|
||||||
|
class="w-10 h-10"
|
||||||
|
th:remove="all"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="../public/icons/facebook-f-svgrepo-com.svg"
|
||||||
|
alt="log in via github"
|
||||||
|
class="w-10 h-10"
|
||||||
|
th:remove="all"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="../public/icons/gitlab-svgrepo-com(1).svg"
|
||||||
|
alt="log in via github"
|
||||||
|
class="w-10 h-10"
|
||||||
|
th:remove="all"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -8,6 +8,7 @@ import java.time.Instant
|
||||||
import org.thymeleaf.TemplateEngine
|
import org.thymeleaf.TemplateEngine
|
||||||
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver
|
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver
|
||||||
import org.thymeleaf.context.{Context => PageContext}
|
import org.thymeleaf.context.{Context => PageContext}
|
||||||
|
import scala.jdk.CollectionConverters._
|
||||||
|
|
||||||
case class AuthService()(implicit cc: castor.Context, log: cask.Logger)
|
case class AuthService()(implicit cc: castor.Context, log: cask.Logger)
|
||||||
extends cask.Routes {
|
extends cask.Routes {
|
||||||
|
@ -21,13 +22,15 @@ case class AuthService()(implicit cc: castor.Context, log: cask.Logger)
|
||||||
case None =>
|
case None =>
|
||||||
println("cookie was None")
|
println("cookie was None")
|
||||||
val redirectToLogin = renderRedirectPage(
|
val redirectToLogin = renderRedirectPage(
|
||||||
"/login", "You will be redirected to login page soon", 0
|
"/login",
|
||||||
|
"You will be redirected to login page soon",
|
||||||
|
0
|
||||||
)
|
)
|
||||||
cask.Response(
|
cask.Response(
|
||||||
redirectToLogin,
|
redirectToLogin,
|
||||||
200,
|
200,
|
||||||
Seq(
|
Seq(
|
||||||
"Content-Type" -> "text/html;charset=UTF-8",
|
"Content-Type" -> "text/html;charset=UTF-8"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
case Some(authCookie) =>
|
case Some(authCookie) =>
|
||||||
|
@ -72,28 +75,42 @@ case class AuthService()(implicit cc: castor.Context, log: cask.Logger)
|
||||||
println("landed on login page")
|
println("landed on login page")
|
||||||
val authOptions = pocketbaseApi.listAuthMethods()
|
val authOptions = pocketbaseApi.listAuthMethods()
|
||||||
|
|
||||||
val options = s"got following auth opitons: $authOptions"
|
val iconLocations = Map(
|
||||||
// save states and verifiers into cookie
|
"github" -> "public/icons/github-svgrepo-com(1).svg",
|
||||||
|
"apple" -> "public/icons/apple-svgrepo-com.svg",
|
||||||
|
"google" -> "public/icons/google-svgrepo-com.svg",
|
||||||
|
"facebook" -> "public/icons/facebook-f-svgrepo-com.svg",
|
||||||
|
"gitlab" -> "public/icons/gitlab-svgrepo-com(1).svg"
|
||||||
|
)
|
||||||
|
|
||||||
|
val oauthLinks = authOptions.authProviders
|
||||||
|
.map(provider => provider.name -> getRedirectLandingUrl(provider.name))
|
||||||
|
.toMap
|
||||||
|
|
||||||
|
val context = new PageContext()
|
||||||
|
context.setVariable("iconLocationsMap", iconLocations.asJava)
|
||||||
|
context.setVariable("oauthProvidersList", authOptions.authProviders.sortBy(_.name).asJava)
|
||||||
|
context.setVariable("redirectUrl", oauthLinks.asJava)
|
||||||
|
|
||||||
|
val authPage = templateEngine.process("auth", context)
|
||||||
|
|
||||||
val oauthVerificationCookie = authOptions.toOauthCookieInfo()
|
val oauthVerificationCookie = authOptions.toOauthCookieInfo()
|
||||||
val yoyo = write(oauthVerificationCookie)
|
val oauthCookieEncoded = write(oauthVerificationCookie)
|
||||||
|
|
||||||
val githubOption = authOptions.authProviders.find(_.name == "github")
|
val githubOption = authOptions.authProviders.find(_.name == "github")
|
||||||
|
|
||||||
val githubRedirect =
|
val githubRedirect =
|
||||||
githubOption.map(_.authUrl).getOrElse("") ++ getRedirectUrl("github")
|
githubOption.map(_.authUrl).getOrElse("") ++ getRedirectLandingUrl("github")
|
||||||
|
|
||||||
val html = s"""
|
|
||||||
<h1>good enough, right</h1>
|
|
||||||
<p>$options</p>
|
|
||||||
<p>will use ${githubRedirect}</p>
|
|
||||||
<a href="${githubRedirect}">Go to github</a>
|
|
||||||
"""
|
|
||||||
cask.Response(
|
cask.Response(
|
||||||
html,
|
authPage,
|
||||||
headers = Seq("Content-Type" -> "text/html;charset=UTF-8"),
|
headers = Seq("Content-Type" -> "text/html;charset=UTF-8"),
|
||||||
cookies = Seq(
|
cookies = Seq(
|
||||||
cask.Cookie(name = oauthVerifiersCookieName, value = yoyo, path = "/")
|
cask.Cookie(
|
||||||
|
name = oauthVerifiersCookieName,
|
||||||
|
value = oauthCookieEncoded,
|
||||||
|
path = "/"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -108,6 +125,9 @@ case class AuthService()(implicit cc: castor.Context, log: cask.Logger)
|
||||||
provider: String,
|
provider: String,
|
||||||
state: String,
|
state: String,
|
||||||
code: String,
|
code: String,
|
||||||
|
scope: Option[String] = None,
|
||||||
|
prompt: Option[String] = None,
|
||||||
|
authuser: Option[String] = None,
|
||||||
request: cask.Request
|
request: cask.Request
|
||||||
) = {
|
) = {
|
||||||
println(
|
println(
|
||||||
|
@ -127,7 +147,7 @@ case class AuthService()(implicit cc: castor.Context, log: cask.Logger)
|
||||||
provider = provider,
|
provider = provider,
|
||||||
code = code,
|
code = code,
|
||||||
verifier = authVerifier.codeVerifier,
|
verifier = authVerifier.codeVerifier,
|
||||||
redirectUrl = getRedirectUrl(provider)
|
redirectUrl = getRedirectLandingUrl(provider)
|
||||||
)
|
)
|
||||||
.toOption
|
.toOption
|
||||||
} yield pocketbaseAuthResult
|
} yield pocketbaseAuthResult
|
||||||
|
@ -145,7 +165,9 @@ case class AuthService()(implicit cc: castor.Context, log: cask.Logger)
|
||||||
case Some(result) =>
|
case Some(result) =>
|
||||||
// this is already fully successful auth
|
// this is already fully successful auth
|
||||||
val redirectToIndex = renderRedirectPage(
|
val redirectToIndex = renderRedirectPage(
|
||||||
"/", "You will be redirected to home page soon", 0
|
"/",
|
||||||
|
"You will be redirected to home page soon",
|
||||||
|
0
|
||||||
)
|
)
|
||||||
|
|
||||||
cask.Response(
|
cask.Response(
|
||||||
|
@ -206,7 +228,7 @@ object AuthService {
|
||||||
* it's possible, but path param looks simpler right now
|
* it's possible, but path param looks simpler right now
|
||||||
* github redirect : http://127.0.0.1:8080/api/oauth2-redirect/github
|
* github redirect : http://127.0.0.1:8080/api/oauth2-redirect/github
|
||||||
*/
|
*/
|
||||||
def getRedirectUrl(provider: String): String =
|
def getRedirectLandingUrl(provider: String): String =
|
||||||
s"${selfUri}${baseRedirectUrl}/${provider}"
|
s"${selfUri}${baseRedirectUrl}/${provider}"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue