forked from inrupt/solid-client-authn-js
-
Notifications
You must be signed in to change notification settings - Fork 7
/
obtainAuthHeaders.ts
126 lines (117 loc) · 4.21 KB
/
obtainAuthHeaders.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
* This project is a continuation of Inrupt's awesome solid-auth-fetcher project,
* see https://www.npmjs.com/package/@inrupt/solid-auth-fetcher.
* Copyright 2020 The Solid Project.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import { customAuthFetcher } from "./index";
import fetch from "cross-fetch";
import AuthFetcher from "./AuthFetcher";
import Debug from "debug";
const debug = Debug("SolidAuthFetcher");
export async function getAuthFetcher(
oidcIssuer: string,
oidcProviderCookie: string,
appOrigin: string,
allowUnauthenticated = true
): Promise<AuthFetcher | { fetch: any }> {
if (!oidcProviderCookie.length && allowUnauthenticated) {
return { fetch } as { fetch: any };
}
const authFetcher = await customAuthFetcher();
const session = await authFetcher.login({
oidcIssuer,
redirect: appOrigin
});
let redirectedTo = (session.neededAction as any).redirectUrl;
do {
debug(`curl -H 'cookie: ${oidcProviderCookie}' ${redirectedTo}`);
const result = await fetch(redirectedTo, {
headers: { cookie: oidcProviderCookie },
redirect: "manual"
});
redirectedTo = result.headers.get("location");
if (redirectedTo === null) {
throw new Error(
`Please make sure the cookie is valid, and add "${appOrigin}" as a trusted app!`
);
}
} while (!redirectedTo?.startsWith(appOrigin));
await authFetcher.handleRedirect(redirectedTo);
return authFetcher as AuthFetcher;
}
export async function getNodeSolidServerCookie(
serverRoot: string,
username: string,
password: string
): Promise<string | null> {
const authFetcher = await customAuthFetcher();
const serverLoginResult = await authFetcher.fetch(
`${serverRoot}/login/password`,
{
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: `username=${username}&password=${password}`,
method: "POST",
redirect: "manual"
}
);
return serverLoginResult.headers.get("set-cookie");
}
export async function getPhpSolidServerCookie(
serverRoot: string,
username: string,
password: string
): Promise<string | null> {
const authFetcher = await customAuthFetcher();
const serverLoginResult = await authFetcher.fetch(`${serverRoot}/login`, {
headers: {
"content-type": "application/x-www-form-urlencoded"
},
body: `username=${username}&password=${password}`,
method: "POST",
redirect: "manual"
});
return serverLoginResult.headers.get("set-cookie");
}
// FIXME: This is a total hack, obviously, second-guessing the
// DI architecture of solid-auth-fetcher:
export async function getAuthHeaders(
urlStr: string,
method: string,
authFetcher: AuthFetcher | { fetch: any }
): Promise<{ Authorization: string; DPop: string }> {
if (authFetcher instanceof AuthFetcher) {
return {
Authorization: JSON.parse(
(authFetcher as any).authenticatedFetcher.tokenRefresher.storageUtility
.storage.map["solidAuthFetcherUser:global"]
).accessToken,
DPop: await (authFetcher as any).authenticatedFetcher.tokenRefresher.tokenRequester.dpopHeaderCreator.createHeaderToken(
new URL(urlStr),
method
)
};
}
return {
Authorization: "",
DPop: ""
};
}