diff --git a/.env.development b/.env.development
index 764926d..f56945a 100644
--- a/.env.development
+++ b/.env.development
@@ -1,5 +1,5 @@
VITE_SSO_ORIGIN=http://localhost:9090
-VITE_OAUTH2_CLIENT_ID=abc123
+VITE_OAUTH2_CLIENT_ID=b5a9a8df-827c-4925-b1c1-1940abcf356b
VITE_API_VIOLET=http://localhost:9095/v1/violet
VITE_API_ORCHID=http://localhost:9095/v1/orchid
diff --git a/src/app.scss b/src/app.scss
index 5a9f9ce..acfdb72 100644
--- a/src/app.scss
+++ b/src/app.scss
@@ -82,6 +82,7 @@ code,
height: 50px;
padding: 4px 16px;
vertical-align: middle;
+ box-shadow: 0 4px 8px #0003, 0 6px 20px #00000030;
&:hover {
color: black;
@@ -89,7 +90,7 @@ code,
}
.btn-green {
- background-color: #04aa6d;
+ background-color: #209c6f;
}
table.main-table {
diff --git a/src/utils/login.ts b/src/utils/login.ts
index 486999a..6e78216 100644
--- a/src/utils/login.ts
+++ b/src/utils/login.ts
@@ -16,12 +16,10 @@ export const LOGIN = {
return POP2.clientRequest(resource, options, refresh);
},
userinfo: (popup: boolean) => {
- console.info("userinfo", popup);
POP2.getToken((token: string) => {
POP2.clientRequest(TOKEN_USERINFO_API, {}, popup)
.then(x => x.json())
.then(x => {
- console.log(token, x);
loginStore.set({
userinfo: x,
tokens: {access: token, refresh: ""},
diff --git a/src/utils/pop2.ts b/src/utils/pop2.ts
index 8f39705..0990149 100644
--- a/src/utils/pop2.ts
+++ b/src/utils/pop2.ts
@@ -32,7 +32,7 @@ export const POP2 = (function (w) {
parseInt(window.location.hash.replace(/^.*expires_in=([^&]+).*$/, "$1")),
);
}
- if (window.location.search.indexOf("error=")) {
+ if (window.location.search.indexOf("error=") !== -1) {
window.opener.POP2.receiveToken("ERROR");
}
}
@@ -108,8 +108,8 @@ export const POP2 = (function (w) {
alert("You need init() first. Check the program flow.");
return false;
}
- if (!popup) throw Error("missing access token");
- if (!access_token) {
+ if (access_token == null) {
+ if (!popup) throw Error("missing access token");
callbackWaitForToken = callback;
popupCenterScreen(
client_endpoint +
@@ -131,7 +131,7 @@ export const POP2 = (function (w) {
}
},
logout: function () {
- access_token = "";
+ access_token = null;
localStorage.removeItem("pop2_access_token");
},
clientRequest: function (resource: RequestInfo, options: RequestInit, refresh = false) {
@@ -166,7 +166,7 @@ export const POP2 = (function (w) {
};
if (!refresh) {
- if (!access_token) return Promise.reject("missing access token");
+ if (access_token == null) return Promise.reject("missing access token");
return sendRequest();
} else {
return new Promise(function (res, rej) {
diff --git a/src/views/GeneralView.svelte b/src/views/GeneralView.svelte
index f3cd28b..acdac2b 100644
--- a/src/views/GeneralView.svelte
+++ b/src/views/GeneralView.svelte
@@ -1,5 +1,15 @@
Warning: This is currently still under development
-
-
Status Dashboard
+
+
+
diff --git a/test-server/main.go b/test-server/main.go
index cd1a31b..e437b1b 100644
--- a/test-server/main.go
+++ b/test-server/main.go
@@ -6,6 +6,7 @@ import (
"fmt"
"log"
"net/http"
+ "net/url"
"strings"
"time"
@@ -32,106 +33,62 @@ func main() {
func ssoServer(signer mjwt.Signer) {
r := http.NewServeMux()
- r.HandleFunc("/popup", func(w http.ResponseWriter, r *http.Request) {
+ r.HandleFunc("/authorize", func(w http.ResponseWriter, r *http.Request) {
+ // request url: http://localhost:9090/authorize?response_type=token&redirect_uri=http://localhost:5173/&scope=openid%20profile%20name&client_id=b5a9a8df-827c-4925-b1c1-1940abcf356b
+ // redirect url: http://localhost:5173/#access_token=
&scope=openid%20profile%20name&token_type=Bearer
+ if r.FormValue("response_type") != "token" {
+ panic("invalid response_type")
+ }
+ if r.FormValue("redirect_uri") != "http://localhost:5173/" {
+ panic("invalid redirect_uri")
+ }
+ if r.FormValue("scope") != "openid profile name" {
+ panic("invalid scope")
+ }
+ if r.FormValue("client_id") != "b5a9a8df-827c-4925-b1c1-1940abcf356b" {
+ panic("invalid client_id")
+ }
+
ps := claims.NewPermStorage()
ps.Set("violet:route")
ps.Set("violet:redirect")
ps.Set("domain:owns=example.com")
ps.Set("domain:owns=example.org")
- accessToken, err := signer.GenerateJwt("81b99bd7-bf74-4cc2-9133-80ed2393dfe6", uuid.NewString(), jwt.ClaimStrings{"d0555671-df9d-42d0-a4d6-94b694251f0b"}, 10*time.Second, auth.AccessTokenClaims{
+ accessToken, err := signer.GenerateJwt("81b99bd7-bf74-4cc2-9133-80ed2393dfe6", uuid.NewString(), jwt.ClaimStrings{"b5a9a8df-827c-4925-b1c1-1940abcf356b"}, 15*time.Minute, auth.AccessTokenClaims{
Perms: ps,
})
if err != nil {
http.Error(w, "Failed to generate access token", http.StatusInternalServerError)
return
}
- w.WriteHeader(http.StatusOK)
- fmt.Fprintf(w, `
-
-
- Test SSO Service
-
-
-
-
-Loading...
-
-
-`, accessToken, "")
+ v := url.Values{}
+ v.Set("access_token", accessToken)
+ v.Set("scope", "openid profile name")
+ v.Set("token_type", "Bearer")
+ v.Set("expires_in", "900")
+ http.Redirect(w, r, "http://localhost:5173/#"+v.Encode(), http.StatusFound)
})
var corsAccessControl = cors.New(cors.Options{
AllowOriginFunc: func(origin string) bool {
- println(origin)
return origin == "http://localhost:5173"
},
- AllowedMethods: []string{http.MethodPost, http.MethodOptions},
- AllowedHeaders: []string{"Content-Type"},
+ AllowedMethods: []string{http.MethodGet, http.MethodOptions},
+ AllowedHeaders: []string{"Content-Type", "Authorization"},
AllowCredentials: true,
})
- r.HandleFunc("/refresh", func(w http.ResponseWriter, r *http.Request) {
+ r.HandleFunc("/userinfo", func(w http.ResponseWriter, r *http.Request) {
corsAccessControl.ServeHTTP(w, r, func(w http.ResponseWriter, r *http.Request) {
- ps := claims.NewPermStorage()
- ps.Set("violet:route")
- ps.Set("violet:redirect")
- ps.Set("domain:owns=example.com")
- ps.Set("domain:owns=example.org")
- accessToken, err := signer.GenerateJwt("81b99bd7-bf74-4cc2-9133-80ed2393dfe6", uuid.NewString(), jwt.ClaimStrings{"d0555671-df9d-42d0-a4d6-94b694251f0b"}, 10*time.Second, auth.AccessTokenClaims{
- Perms: ps,
- })
- if err != nil {
- http.Error(w, "Failed to generate access token", http.StatusInternalServerError)
- return
- }
w.WriteHeader(http.StatusOK)
- _ = json.NewEncoder(w).Encode(map[string]any{
- "target": "http://localhost:5173",
- "tokens": map[string]any{
- "access": accessToken,
- "refresh": "",
- },
- "userinfo": map[string]any{
- "aud": "d0555671-df9d-42d0-a4d6-94b694251f0b",
- "email": "admin@localhost",
- "email_verified": true,
- "name": "Admin",
- "preferred_username": "admin",
- "sub": "81b99bd7-bf74-4cc2-9133-80ed2393dfe6",
- "picture": "http://localhost:5173/1f349.svg",
- "updated_at": 0,
- },
- })
+ w.Write([]byte(`{"aud":"b5a9a8df-827c-4925-b1c1-1940abcf356b","name":"Test User","picture":"","profile":"http://localhost:9090/user/test-user","sub":"b429562a-20e9-4466-9e8e-bdeb55f2f4a3@localhost","updated_at":1572278406,"website":""}`))
})
})
log.Println("[SSO Server]", http.ListenAndServe(":9090", r))
}
var serveApiCors = cors.New(cors.Options{
- AllowedOrigins: []string{"*"}, // allow all origins for api requests
+ AllowOriginFunc: func(origin string) bool {
+ return origin == "http://localhost:5173"
+ }, // allow all origins for api requests
AllowedHeaders: []string{"Content-Type", "Authorization"},
AllowedMethods: []string{
http.MethodGet,