commit c143dc25a65c9541fa18098e1e282dbc05f3b86b Author: efim Date: Sun Jul 23 08:08:58 2023 +0000 init: copied out of combined project diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6dbef33 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +.DS_Store +.idea +*.log +tmp/ + +pb_data +pb_migrations + +.bloop +.bsp +.direnv +.metals +target diff --git a/.project b/.project new file mode 100644 index 0000000..e69de29 diff --git a/.scalafmt.conf b/.scalafmt.conf new file mode 100644 index 0000000..db004c6 --- /dev/null +++ b/.scalafmt.conf @@ -0,0 +1,2 @@ +version = "3.7.3" +runner.dialect = scala3 \ No newline at end of file diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..670c0d5 --- /dev/null +++ b/build.sbt @@ -0,0 +1,4 @@ +ThisBuild / scalaVersion := "3.3.0" + +libraryDependencies += "com.lihaoyi" %% "upickle" % "3.1.2" +libraryDependencies += "com.lihaoyi" %% "requests" % "0.8.0" diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..f9bfc50 --- /dev/null +++ b/flake.lock @@ -0,0 +1,97 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1687171271, + "narHash": "sha256-BJlq+ozK2B1sJDQXS3tzJM5a+oVZmi1q0FlBK/Xqv7M=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "abfb11bd1aec8ced1c9bb9adfe68018230f4fb3c", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1687695299, + "narHash": "sha256-j3IcDoAPulOmwcsCDb7RxBmDoCF0itDZ5e0sgM4rgWY=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "1fb6a92b2005e6d0d3b0c1a111093a41947d27f8", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "sbt-derivation": "sbt-derivation" + } + }, + "sbt-derivation": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1675083208, + "narHash": "sha256-+sSFhSpV2jckr1qYlX/SaxQ6IdpagD6o4rru/3HAl0I=", + "owner": "zaninime", + "repo": "sbt-derivation", + "rev": "92d6d6d825e3f6ae5642d1cce8ff571c3368aaf7", + "type": "github" + }, + "original": { + "owner": "zaninime", + "repo": "sbt-derivation", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..e18edaa --- /dev/null +++ b/flake.nix @@ -0,0 +1,28 @@ +{ + description = "attempting sample app with oauth"; + inputs.nixpkgs.url = "github:nixos/nixpkgs"; + inputs.flake-utils.url = "github:numtide/flake-utils"; + # add this line + inputs.sbt-derivation.url = "github:zaninime/sbt-derivation"; + # recommended for first style of usage documented below, but not necessary + inputs.sbt-derivation.inputs.nixpkgs.follows = "nixpkgs"; + + outputs = { self, nixpkgs, flake-utils, sbt-derivation }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in { + devShells.default = pkgs.mkShell { + buildInputs = [ + pkgs.scala-cli + pkgs.sbt + pkgs.scalafmt + pkgs.nodePackages.tailwindcss + pkgs.nodePackages.prettier + pkgs.jdk + pkgs.pocketbase + ]; + }; + }); + # see https://serokell.io/blog/practical-nix-flakes +} diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..40b3b8e --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.9.0 diff --git a/project/metals.sbt b/project/metals.sbt new file mode 100644 index 0000000..05fd2b3 --- /dev/null +++ b/project/metals.sbt @@ -0,0 +1,6 @@ +// DO NOT EDIT! This file is auto-generated. + +// This file enables sbt-bloop to create bloop config files. + +addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.6") + diff --git a/project/project/metals.sbt b/project/project/metals.sbt new file mode 100644 index 0000000..05fd2b3 --- /dev/null +++ b/project/project/metals.sbt @@ -0,0 +1,6 @@ +// DO NOT EDIT! This file is auto-generated. + +// This file enables sbt-bloop to create bloop config files. + +addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.6") + diff --git a/src/input.css b/src/input.css new file mode 100644 index 0000000..b5c61c9 --- /dev/null +++ b/src/input.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/src/main/resources/icons/apple-svgrepo-com.svg b/src/main/resources/icons/apple-svgrepo-com.svg new file mode 100644 index 0000000..a2dac9a --- /dev/null +++ b/src/main/resources/icons/apple-svgrepo-com.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/main/resources/icons/facebook-f-svgrepo-com.svg b/src/main/resources/icons/facebook-f-svgrepo-com.svg new file mode 100644 index 0000000..39a2bb7 --- /dev/null +++ b/src/main/resources/icons/facebook-f-svgrepo-com.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/main/resources/icons/github-svgrepo-com(1).svg b/src/main/resources/icons/github-svgrepo-com(1).svg new file mode 100644 index 0000000..ffa502a --- /dev/null +++ b/src/main/resources/icons/github-svgrepo-com(1).svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/main/resources/icons/gitlab-svgrepo-com(1).svg b/src/main/resources/icons/gitlab-svgrepo-com(1).svg new file mode 100644 index 0000000..96e33fd --- /dev/null +++ b/src/main/resources/icons/gitlab-svgrepo-com(1).svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/main/resources/icons/google-svgrepo-com.svg b/src/main/resources/icons/google-svgrepo-com.svg new file mode 100644 index 0000000..5e89ad7 --- /dev/null +++ b/src/main/resources/icons/google-svgrepo-com.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/main/resources/out.css b/src/main/resources/out.css new file mode 100644 index 0000000..4dad71b --- /dev/null +++ b/src/main/resources/out.css @@ -0,0 +1,633 @@ +/* +! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com +*/ + +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: #e5e7eb; + /* 2 */ +} + +::before, +::after { + --tw-content: ''; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +*/ + +html { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; + /* 1 */ + line-height: inherit; + /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font family by default. +2. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +[type='button'], +[type='reset'], +[type='submit'] { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +[hidden] { + display: none; +} + +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +.flex { + display: flex; +} + +.grid { + display: grid; +} + +.h-10 { + height: 2.5rem; +} + +.h-screen { + height: 100vh; +} + +.w-10 { + width: 2.5rem; +} + +.w-screen { + width: 100vw; +} + +.flex-row { + flex-direction: row; +} + +.place-content-center { + place-content: center; +} + +.justify-center { + justify-content: center; +} + +.gap-2 { + gap: 0.5rem; +} + +.gap-4 { + gap: 1rem; +} + +.rounded-xl { + border-radius: 0.75rem; +} + +.border-4 { + border-width: 4px; +} + +.border-b-8 { + border-bottom-width: 8px; +} + +.border-t-8 { + border-top-width: 8px; +} + +.border-r-8 { + border-right-width: 8px; +} + +.border-blue-400 { + --tw-border-opacity: 1; + border-color: rgb(96 165 250 / var(--tw-border-opacity)); +} + +.bg-blue-100 { + --tw-bg-opacity: 1; + background-color: rgb(219 234 254 / var(--tw-bg-opacity)); +} + +.bg-blue-50 { + --tw-bg-opacity: 1; + background-color: rgb(239 246 255 / var(--tw-bg-opacity)); +} + +.p-32 { + padding: 8rem; +} + +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; +} + +.font-bold { + font-weight: 700; +} + +.uppercase { + text-transform: uppercase; +} + +.tracking-wide { + letter-spacing: 0.025em; +} + +.text-blue-400 { + --tw-text-opacity: 1; + color: rgb(96 165 250 / var(--tw-text-opacity)); +} + +.text-blue-600 { + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity)); +} diff --git a/src/main/resources/templates/auth.html b/src/main/resources/templates/auth.html new file mode 100644 index 0000000..35ddc8d --- /dev/null +++ b/src/main/resources/templates/auth.html @@ -0,0 +1,48 @@ + + + + + + Auth page + + + + + + + + + + +
+
+

Authorizatoin options

+
+ log in via github + log in via github + log in via github + log in via github + log in via github +
+
+
+ + diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html new file mode 100644 index 0000000..a34eedd --- /dev/null +++ b/src/main/resources/templates/index.html @@ -0,0 +1,31 @@ + + + + + + index page + + + + + + + + + +
+
+

Auth successful, yay

+

Here be some info

+
+
+ + diff --git a/src/main/scala/example/Main.scala b/src/main/scala/example/Main.scala new file mode 100644 index 0000000..248e040 --- /dev/null +++ b/src/main/scala/example/Main.scala @@ -0,0 +1,4 @@ +package example + +@main def main(args: String*): Unit = + println(s"Hello ${args.mkString}") diff --git a/src/main/scala/example/pocketbase/Api.scala b/src/main/scala/example/pocketbase/Api.scala new file mode 100644 index 0000000..9801cd4 --- /dev/null +++ b/src/main/scala/example/pocketbase/Api.scala @@ -0,0 +1,65 @@ +package example.pocketbase + +import upickle.default._ +import Api.Error +import Models._ +import requests.Response + +final case class Api(pocketbaseUrl: String, usersCollection: String = "users") { + def refreshSession(jwt: String): Either[Error, AuthReply] = { + val path = s"/api/collections/${pocketbaseUrl}/auth-refresh" + + val refreshResult = requests.post( + url = pocketbaseUrl ++ path, + headers = List("Authorization" -> jwt) + ) + + refreshResult.statusCode match { + case 200 => + val newAuth = read[AuthReply](refreshResult.text()) + Right(newAuth) + case 404 => Left(Error("not found")) + case _ => Left(Error("other error")) + } + } + + def listAuthMethods(): AvailableAuthMethods = { + val path = s"/api/collections/$usersCollection/auth-methods" + + val availableAuth = requests.get( + url = pocketbaseUrl ++ path + ) + + read[AvailableAuthMethods](availableAuth.text()) + } + + def authWithOauth( + provider: String, + code: String, + verifier: String, + redirectUrl: String + ): Either[Error, AuthReply] = { + val path = s"/api/collections/${usersCollection}/auth-with-oauth2" + + val authResult: Response = requests.post( + url = pocketbaseUrl ++ path, + data = Map( + "provider" -> provider, + "code" -> code, + "codeVerifier" -> verifier, + "redirectUri" -> redirectUrl + ) + ) + + authResult.statusCode match { + case 200 => + val result = read[AuthReply](authResult.text()) + Right(result) + case _ => Left(Error("auth not successful")) + } + } +} + +object Api { + final case class Error(msg: String) +} diff --git a/src/main/scala/example/pocketbase/Models.scala b/src/main/scala/example/pocketbase/Models.scala new file mode 100644 index 0000000..cd5fda0 --- /dev/null +++ b/src/main/scala/example/pocketbase/Models.scala @@ -0,0 +1,78 @@ +package example.pocketbase + +import upickle.default._ + +object Models { + + final case class AuthProviderInfo( + name: String, + state: String, + codeVerifier: String, + codeChallenge: String, + codeChallengeMethod: String, + authUrl: String + ) derives ReadWriter + + final case class AvailableAuthMethods( + usernamePassword: Boolean, + emailPassword: Boolean, + authProviders: List[AuthProviderInfo] + ) derives ReadWriter + + + // auth methods + /* + { + "usernamePassword": false, + "emailPassword": true, + "authProviders": [ + { + "name": "github", + "state": "3Yd8jNkK_6PJG6hPWwBjLqKwse6Ejd", + "codeVerifier": "KxFDWz1B3fxscCDJ_9gHQhLuh__ie7", + "codeChallenge": "NM1oVexB6Q6QH8uPtOUfK7tq4pmu4Jz6lNDIwoxHZNE=", + "codeChallengeMethod": "S256", + "authUrl": "https://github.com/login/oauth/authorize?client_id=demo&code_challenge=NM1oVexB6Q6QH8uPtOUfK7tq4pmu4Jz6lNDIwoxHZNE%3D&code_challenge_method=S256&response_type=code&scope=user&state=3Yd8jNkK_6PJG6hPWwBjLqKwse6Ejd&redirect_uri=" + } + ] + } + * + */ + + final case class BaseAccountData( + id: String, + collectionId: String, + collectionName: String, + created: String, + updated: String, + username: String, + email: String, + verified: Boolean, + emailVisibility: Boolean + ) derives ReadWriter + + final case class AuthReply( + token: String, + record: BaseAccountData + ) derives ReadWriter + + // auth reply + /* + * + *{ + "token": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjRxMXhsY2xtZmxva3UzMyIsInR5cGUiOiJhdXRoUmVjb3JkIiwiY29sbGVjdGlvbklkIjoiX3BiX3VzZXJzX2F1dGhfIiwiZXhwIjoyMjA4OTg1MjYxfQ.UwD8JvkbQtXpymT09d7J6fdA0aP9g4FJ1GPh_ggEkzc", + "record": { + "id": "8171022dc95a4ed", + "collectionId": "d2972397d45614e", + "collectionName": "users", + "created": "2022-06-24 06:24:18.434Z", + "updated": "2022-06-24 06:24:18.889Z", + "username": "test@example.com", + "email": "test@example.com", + "verified": true, + "emailVisibility": false, + "someCustomField": "example 123" + } + } + * */ +} diff --git a/src/test/scala/example/ExampleSuite.scala b/src/test/scala/example/ExampleSuite.scala new file mode 100644 index 0000000..26c55ab --- /dev/null +++ b/src/test/scala/example/ExampleSuite.scala @@ -0,0 +1,8 @@ +package example + +class ExampleSuite extends munit.FunSuite: + + test("addition") { + assert(1 + 1 == 2) + } +end ExampleSuite diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..67a9cd5 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,9 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./src/**/*.{html,scala}"], + theme: { + extend: {}, + }, + plugins: [], +} +