autherr 2.0.3 → 2.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -6,12 +6,13 @@ export async function createClientAssertion(clientId, privateKeyPem) {
|
|
|
6
6
|
name: "RSASSA-PKCS1-v1_5",
|
|
7
7
|
hash: "SHA-256",
|
|
8
8
|
}, false, ["sign"]);
|
|
9
|
-
|
|
10
|
-
return await new SignJWT({ clientId })
|
|
9
|
+
return await new SignJWT({})
|
|
11
10
|
.setProtectedHeader({ alg: "RS256", typ: "JWT" })
|
|
12
|
-
.
|
|
13
|
-
.
|
|
14
|
-
.setAudience("autherr")
|
|
15
|
-
.
|
|
11
|
+
.setIssuer(clientId) // iss
|
|
12
|
+
.setSubject(clientId) // sub
|
|
13
|
+
.setAudience("autherr") // aud
|
|
14
|
+
.setIssuedAt() // iat = now
|
|
15
|
+
.setExpirationTime("2m") // exp = iat + 2 min
|
|
16
|
+
.setJti(crypto.randomUUID()) // anti-replay
|
|
16
17
|
.sign(key);
|
|
17
18
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export declare function useAutherr(): {
|
|
2
2
|
accessToken: string | null;
|
|
3
3
|
isAuthenticated: boolean;
|
|
4
|
-
login: () => void
|
|
5
|
-
signup: () => void
|
|
4
|
+
login: () => Promise<void>;
|
|
5
|
+
signup: () => Promise<void>;
|
|
6
6
|
logout: () => Promise<void>;
|
|
7
7
|
refreshSession: () => Promise<void>;
|
|
8
8
|
getAccessToken: () => string | null;
|
|
@@ -2,8 +2,8 @@ import React from "react";
|
|
|
2
2
|
interface AutherrContextValue {
|
|
3
3
|
accessToken: string | null;
|
|
4
4
|
isAuthenticated: boolean;
|
|
5
|
-
login: () => void
|
|
6
|
-
signup: () => void
|
|
5
|
+
login: () => Promise<void>;
|
|
6
|
+
signup: () => Promise<void>;
|
|
7
7
|
logout: () => Promise<void>;
|
|
8
8
|
getAccessToken: () => string | null;
|
|
9
9
|
refreshSession: () => Promise<void>;
|
|
@@ -3,13 +3,6 @@ import { createContext, useContext, useEffect, useMemo, useState, } from "react"
|
|
|
3
3
|
import { fetchSession } from "../api/session";
|
|
4
4
|
import { logoutSession } from "../api/logout";
|
|
5
5
|
import { createClientAssertion } from "../crypto/createClientAssertion";
|
|
6
|
-
function setClientAssertionCookie(token) {
|
|
7
|
-
document.cookie =
|
|
8
|
-
`autherr_client_assertion=${token};` +
|
|
9
|
-
`Path=/;` +
|
|
10
|
-
`Secure;` +
|
|
11
|
-
`SameSite=None`;
|
|
12
|
-
}
|
|
13
6
|
const AutherrContext = createContext(null);
|
|
14
7
|
export function AutherrProvider({ children, clientId, baseUrl, clientPrivateKey, }) {
|
|
15
8
|
const [accessToken, setAccessToken] = useState(null);
|
|
@@ -28,35 +21,31 @@ export function AutherrProvider({ children, clientId, baseUrl, clientPrivateKey,
|
|
|
28
21
|
useEffect(() => {
|
|
29
22
|
refreshSession();
|
|
30
23
|
}, [baseUrl, clientId]);
|
|
31
|
-
const
|
|
32
|
-
const state = crypto.randomUUID();
|
|
33
|
-
const assertion = await createClientAssertion(clientId, clientPrivateKey);
|
|
34
|
-
setClientAssertionCookie(assertion);
|
|
35
|
-
window.location.href =
|
|
36
|
-
`${baseUrl}/auth/login` +
|
|
37
|
-
`?client_id=${clientId}` +
|
|
38
|
-
`&redirect_uri=${encodeURIComponent(window.location.origin)}` +
|
|
39
|
-
`&state=${state}`;
|
|
40
|
-
};
|
|
41
|
-
const signup = async () => {
|
|
24
|
+
const buildRedirect = async (path) => {
|
|
42
25
|
const state = crypto.randomUUID();
|
|
43
26
|
const assertion = await createClientAssertion(clientId, clientPrivateKey);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
27
|
+
const url = new URL(`${baseUrl}/auth/${path}`);
|
|
28
|
+
url.searchParams.set("client_id", clientId);
|
|
29
|
+
url.searchParams.set("redirect_uri", window.location.origin);
|
|
30
|
+
url.searchParams.set("state", state);
|
|
31
|
+
// Attach assertion as header via fetch redirect
|
|
32
|
+
await fetch(url.toString(), {
|
|
33
|
+
method: "GET",
|
|
34
|
+
headers: {
|
|
35
|
+
"X-Client-Assertion": assertion,
|
|
36
|
+
},
|
|
37
|
+
credentials: "include",
|
|
38
|
+
}).then((res) => {
|
|
39
|
+
window.location.href = res.url;
|
|
40
|
+
});
|
|
50
41
|
};
|
|
42
|
+
const login = () => buildRedirect("login");
|
|
43
|
+
const signup = () => buildRedirect("signup");
|
|
51
44
|
const logout = async () => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
setAccessToken(null);
|
|
57
|
-
setIsAuthenticated(false);
|
|
58
|
-
window.location.href = window.location.origin;
|
|
59
|
-
}
|
|
45
|
+
await logoutSession(baseUrl, clientId);
|
|
46
|
+
setAccessToken(null);
|
|
47
|
+
setIsAuthenticated(false);
|
|
48
|
+
window.location.href = window.location.origin;
|
|
60
49
|
};
|
|
61
50
|
const value = useMemo(() => ({
|
|
62
51
|
accessToken,
|