1 | /*
|
2 | * Copyright 2021 Inrupt Inc.
|
3 | *
|
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
5 | * of this software and associated documentation files (the "Software"), to deal in
|
6 | * the Software without restriction, including without limitation the rights to use,
|
7 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
8 | * Software, and to permit persons to whom the Software is furnished to do so,
|
9 | * subject to the following conditions:
|
10 | *
|
11 | * The above copyright notice and this permission notice shall be included in
|
12 | * all copies or substantial portions of the Software.
|
13 | *
|
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
15 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
16 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
17 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
18 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
19 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20 | */
|
21 |
|
22 | /**
|
23 | * @hidden
|
24 | * @packageDocumentation
|
25 | */
|
26 |
|
27 | import { inject, injectable } from "tsyringe";
|
28 | import {
|
29 | ISessionInfo,
|
30 | ISessionInfoManager,
|
31 | ISessionInfoManagerOptions,
|
32 | IStorageUtility,
|
33 | } from "@inrupt/solid-client-authn-core";
|
34 | import { v4 } from "uuid";
|
35 | import { clearOidcPersistentStorage } from "@inrupt/oidc-client-ext";
|
36 | import { fetchWithCookies } from "../ClientAuthentication";
|
37 |
|
38 | export function getUnauthenticatedSession(): ISessionInfo & {
|
39 | fetch: typeof fetch;
|
40 | } {
|
41 | return {
|
42 | isLoggedIn: false,
|
43 | sessionId: v4(),
|
44 | fetch: fetchWithCookies,
|
45 | };
|
46 | }
|
47 |
|
48 | /**
|
49 | * @param sessionId
|
50 | * @param storage
|
51 | * @hidden
|
52 | */
|
53 | export async function clear(
|
54 | sessionId: string,
|
55 | storage: IStorageUtility
|
56 | ): Promise<void> {
|
57 | // The type assertion is okay, because it throws on undefined.
|
58 | const webId = await storage.getForUser(sessionId, "webId", {
|
59 | secure: true,
|
60 | });
|
61 | if (webId !== undefined) {
|
62 | const webIdAsUrl = new URL(webId);
|
63 | const resourceServerIri = webIdAsUrl.origin;
|
64 | await storage.clearResourceServerSessionInfo(resourceServerIri);
|
65 | }
|
66 | await Promise.all([
|
67 | storage.deleteAllUserData(sessionId, { secure: false }),
|
68 | storage.deleteAllUserData(sessionId, { secure: true }),
|
69 | // FIXME: This is needed until the DPoP key is stored safely
|
70 | storage.delete("clientKey", { secure: false }),
|
71 | ]);
|
72 | await clearOidcPersistentStorage();
|
73 | }
|
74 |
|
75 | /**
|
76 | * @hidden
|
77 | */
|
78 | ()
|
79 | export class SessionInfoManager implements ISessionInfoManager {
|
80 | constructor(
|
81 | "storageUtility") private storageUtility: IStorageUtility
( |
82 | ) {}
|
83 |
|
84 | // eslint-disable-next-line class-methods-use-this
|
85 | update(
|
86 | _sessionId: string,
|
87 | _options: ISessionInfoManagerOptions
|
88 | ): Promise<void> {
|
89 | // const localUserId: string = options.localUserId || this.uuidGenerator.v4();
|
90 | // if (options.loggedIn) {
|
91 | // return {
|
92 | // sessionId,
|
93 | // loggedIn: true,
|
94 | // webId: options.webId as string,
|
95 | // neededAction: options.neededAction || { actionType: "inaction" },
|
96 | // state: options.state,
|
97 | // logout: async (): Promise<void> => {
|
98 | // // TODO: handle if webid isn't here
|
99 | // return this.logoutHandler.handle(localUserId);
|
100 | // },
|
101 | // fetch: (url: RequestInfo, init?: RequestInit): Promise<Response> => {
|
102 | // // TODO: handle if webid isn't here
|
103 | // return this.authenticatedFetcher.handle(
|
104 | // {
|
105 | // localUserId,
|
106 | // type: "dpop"
|
107 | // },
|
108 | // url,
|
109 | // init
|
110 | // );
|
111 | // }
|
112 | // };
|
113 | // } else {
|
114 | // return {
|
115 | // localUserId,
|
116 | // loggedIn: false,
|
117 | // neededAction: options.neededAction || { actionType: "inaction" }
|
118 | // };
|
119 | // }
|
120 | throw new Error("Not Implemented");
|
121 | }
|
122 |
|
123 | async get(sessionId: string): Promise<ISessionInfo | undefined> {
|
124 | const webId = await this.storageUtility.getForUser(sessionId, "webId", {
|
125 | secure: true,
|
126 | });
|
127 | const isLoggedIn = await this.storageUtility.getForUser(
|
128 | sessionId,
|
129 | "isLoggedIn",
|
130 | {
|
131 | secure: true,
|
132 | }
|
133 | );
|
134 | if (isLoggedIn !== undefined) {
|
135 | return {
|
136 | sessionId,
|
137 | webId,
|
138 | isLoggedIn: isLoggedIn === "true",
|
139 | };
|
140 | }
|
141 | return undefined;
|
142 | }
|
143 |
|
144 | // eslint-disable-next-line class-methods-use-this
|
145 | async getAll(): Promise<ISessionInfo[]> {
|
146 | throw new Error("Not implemented");
|
147 | }
|
148 |
|
149 | /**
|
150 | * This function removes all session-related information from storage.
|
151 | * @param sessionId the session identifier
|
152 | * @param storage the storage where session info is stored
|
153 | * @hidden
|
154 | */
|
155 | async clear(sessionId: string): Promise<void> {
|
156 | return clear(sessionId, this.storageUtility);
|
157 | }
|
158 | }
|