@touchtech/web-auth 0.0.1
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.
- package/README.md +1 -0
- package/dist/components/ProtectedRoute/ProtectedRoute.d.ts +9 -0
- package/dist/components/ProtectedRoute/ProtectedRoute.js +22 -0
- package/dist/components/ProtectedRoute/ProtectedRoute.js.map +1 -0
- package/dist/components/ProtectedRoute/__tests__/protectedRoute.test.d.ts +1 -0
- package/dist/components/ProtectedRoute/__tests__/protectedRoute.test.js +85 -0
- package/dist/components/ProtectedRoute/__tests__/protectedRoute.test.js.map +1 -0
- package/dist/components/ProtectedRoute/index.d.ts +1 -0
- package/dist/components/ProtectedRoute/index.js +2 -0
- package/dist/components/ProtectedRoute/index.js.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +2 -0
- package/dist/components/index.js.map +1 -0
- package/dist/contexts/AuthContext.d.ts +16 -0
- package/dist/contexts/AuthContext.js +28 -0
- package/dist/contexts/AuthContext.js.map +1 -0
- package/dist/contexts/ProtectedRouteContext.d.ts +15 -0
- package/dist/contexts/ProtectedRouteContext.js +11 -0
- package/dist/contexts/ProtectedRouteContext.js.map +1 -0
- package/dist/contexts/__tests__/AuthContext.test.d.ts +1 -0
- package/dist/contexts/__tests__/AuthContext.test.js +48 -0
- package/dist/contexts/__tests__/AuthContext.test.js.map +1 -0
- package/dist/contexts/index.d.ts +2 -0
- package/dist/contexts/index.js +3 -0
- package/dist/contexts/index.js.map +1 -0
- package/dist/features/auth/Auth.d.ts +5 -0
- package/dist/features/auth/Auth.js +30 -0
- package/dist/features/auth/Auth.js.map +1 -0
- package/dist/features/auth/index.d.ts +1 -0
- package/dist/features/auth/index.js +2 -0
- package/dist/features/auth/index.js.map +1 -0
- package/dist/features/index.d.ts +1 -0
- package/dist/features/index.js +2 -0
- package/dist/features/index.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/services/AuthConfiguration.d.ts +7 -0
- package/dist/services/AuthConfiguration.js +2 -0
- package/dist/services/AuthConfiguration.js.map +1 -0
- package/dist/services/AuthFlow.d.ts +38 -0
- package/dist/services/AuthFlow.js +183 -0
- package/dist/services/AuthFlow.js.map +1 -0
- package/dist/services/AuthService.d.ts +26 -0
- package/dist/services/AuthService.js +110 -0
- package/dist/services/AuthService.js.map +1 -0
- package/dist/services/IAuthService.d.ts +15 -0
- package/dist/services/IAuthService.js +2 -0
- package/dist/services/IAuthService.js.map +1 -0
- package/dist/services/__tests__/AuthService.test.d.ts +1 -0
- package/dist/services/__tests__/AuthService.test.js +58 -0
- package/dist/services/__tests__/AuthService.test.js.map +1 -0
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.js +5 -0
- package/dist/services/index.js.map +1 -0
- package/dist/types/Privileges.d.ts +6 -0
- package/dist/types/Privileges.js +7 -0
- package/dist/types/Privileges.js.map +1 -0
- package/dist/types/TenantIds.d.ts +3 -0
- package/dist/types/TenantIds.js +4 -0
- package/dist/types/TenantIds.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/user.d.ts +6 -0
- package/dist/types/user.js +2 -0
- package/dist/types/user.js.map +1 -0
- package/dist/utils/identityProvider.d.ts +1 -0
- package/dist/utils/identityProvider.js +12 -0
- package/dist/utils/identityProvider.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/roles.d.ts +2 -0
- package/dist/utils/roles.js +16 -0
- package/dist/utils/roles.js.map +1 -0
- package/package.json +70 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# DSR Authentication
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
declare type ProtectedRouteProps = {
|
|
3
|
+
component: React.ComponentType<any>;
|
|
4
|
+
path: string | string[];
|
|
5
|
+
exact?: boolean;
|
|
6
|
+
skipAuthorization?: boolean;
|
|
7
|
+
};
|
|
8
|
+
declare function ProtectedRoute({ component, path, exact, skipAuthorization, }: ProtectedRouteProps): JSX.Element;
|
|
9
|
+
export default ProtectedRoute;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { useContext } from "react";
|
|
2
|
+
import { Redirect, Route } from "react-router-dom";
|
|
3
|
+
import { userHasAccess } from "../../utils";
|
|
4
|
+
import { AuthContext, ProtectedRouteContext } from "../../contexts";
|
|
5
|
+
function ProtectedRoute({ component, path, exact, skipAuthorization, }) {
|
|
6
|
+
const { user, authService } = useContext(AuthContext);
|
|
7
|
+
const { tenantId, privilege, unauthorizedPath } = useContext(ProtectedRouteContext);
|
|
8
|
+
if (user) {
|
|
9
|
+
if (skipAuthorization || userHasAccess(user, tenantId, privilege)) {
|
|
10
|
+
return React.createElement(Route, { path: path, component: component, exact: exact });
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
return React.createElement(Redirect, { to: unauthorizedPath });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
authService.signIn();
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export default ProtectedRoute;
|
|
22
|
+
//# sourceMappingURL=ProtectedRoute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProtectedRoute.js","sourceRoot":"","sources":["../../../src/components/ProtectedRoute/ProtectedRoute.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AASpE,SAAS,cAAc,CAAC,EACtB,SAAS,EACT,IAAI,EACJ,KAAK,EACL,iBAAiB,GACG;IACpB,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACtD,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,UAAU,CAC1D,qBAAqB,CACtB,CAAC;IAEF,IAAI,IAAI,EAAE;QACR,IAAI,iBAAiB,IAAI,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE;YACjE,OAAO,oBAAC,KAAK,IAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAI,CAAC;SAClE;aAAM;YACL,OAAO,oBAAC,QAAQ,IAAC,EAAE,EAAE,gBAAgB,GAAI,CAAC;SAC3C;KACF;SAAM;QACL,WAAW,CAAC,MAAM,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;KACb;AACH,CAAC;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
3
|
+
import EventEmitter from "events";
|
|
4
|
+
import React from "react";
|
|
5
|
+
import { HashRouter as Router, Switch } from "react-router-dom";
|
|
6
|
+
import { render } from "@testing-library/react";
|
|
7
|
+
import { ProtectedRoute } from "..";
|
|
8
|
+
import { AuthContext, ProtectedRouteProvider } from "../../../contexts";
|
|
9
|
+
const signedInHeader = "user signed in";
|
|
10
|
+
const TestComponent = () => {
|
|
11
|
+
return React.createElement(React.Fragment, null, signedInHeader);
|
|
12
|
+
};
|
|
13
|
+
class AuthServiceMock extends EventEmitter {
|
|
14
|
+
get user() {
|
|
15
|
+
throw new Error("Method not implemented.");
|
|
16
|
+
}
|
|
17
|
+
signIn() {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () { });
|
|
19
|
+
}
|
|
20
|
+
signOut() {
|
|
21
|
+
throw new Error("Method not implemented.");
|
|
22
|
+
}
|
|
23
|
+
getAccessToken() {
|
|
24
|
+
throw new Error("Method not implemented.");
|
|
25
|
+
}
|
|
26
|
+
completeSignInIfPossible() {
|
|
27
|
+
throw new Error("Method not implemented.");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function renderRoutes(providerValues) {
|
|
31
|
+
return render(React.createElement(AuthContext.Provider, { value: providerValues },
|
|
32
|
+
React.createElement(Router, null,
|
|
33
|
+
React.createElement(ProtectedRouteProvider, { tenantId: "tenantId", privilege: "privilege", unauthorizedPath: "" },
|
|
34
|
+
React.createElement(Switch, null,
|
|
35
|
+
React.createElement(ProtectedRoute, { component: TestComponent, path: "/" }))))));
|
|
36
|
+
}
|
|
37
|
+
describe("Protected Route", () => {
|
|
38
|
+
const authService = new AuthServiceMock();
|
|
39
|
+
const signInSpy = jest.spyOn(authService, "signIn");
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
signInSpy.mockClear();
|
|
42
|
+
});
|
|
43
|
+
describe("logged in user", () => {
|
|
44
|
+
const providerValues = {
|
|
45
|
+
user: {
|
|
46
|
+
firstName: "given_name",
|
|
47
|
+
lastName: "family_name",
|
|
48
|
+
email: "test@example.com",
|
|
49
|
+
roles: ["tenantId:privilege"],
|
|
50
|
+
},
|
|
51
|
+
authService,
|
|
52
|
+
};
|
|
53
|
+
it("renders the route", () => {
|
|
54
|
+
const { getByText } = renderRoutes(providerValues);
|
|
55
|
+
expect(signInSpy).not.toHaveBeenCalled();
|
|
56
|
+
expect(getByText(signedInHeader)).toBeInTheDocument();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe("no logged in user", () => {
|
|
60
|
+
describe("sign-in in progress", () => {
|
|
61
|
+
const providerValues = {
|
|
62
|
+
isInProgress: true,
|
|
63
|
+
authService,
|
|
64
|
+
};
|
|
65
|
+
it("Does not try to sign in", () => {
|
|
66
|
+
renderRoutes(providerValues);
|
|
67
|
+
expect(signInSpy).not.toHaveBeenCalledTimes;
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe("sign-in not initiated", () => {
|
|
71
|
+
const providerValues = {
|
|
72
|
+
authService,
|
|
73
|
+
};
|
|
74
|
+
it("sign in the user", () => {
|
|
75
|
+
const { queryByText } = renderRoutes(providerValues);
|
|
76
|
+
expect(queryByText(signedInHeader)).not.toBeInTheDocument();
|
|
77
|
+
expect(signInSpy).toHaveBeenCalledTimes(1);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
// it("works", () => {
|
|
83
|
+
// expect(true).toBe(true);
|
|
84
|
+
// });
|
|
85
|
+
//# sourceMappingURL=protectedRoute.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protectedRoute.test.js","sourceRoot":"","sources":["../../../../src/components/ProtectedRoute/__tests__/protectedRoute.test.tsx"],"names":[],"mappings":";AAAA,yDAAyD;AACzD,OAAO,YAAY,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,IAAI,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,OAAO,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAGxE,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAExC,MAAM,aAAa,GAAG,GAAG,EAAE;IACzB,OAAO,0CAAG,cAAc,CAAI,CAAC;AAC/B,CAAC,CAAC;AAEF,MAAM,eAAgB,SAAQ,YAAY;IACxC,IAAI,IAAI;QACN,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAEK,MAAM;8DAAmB,CAAC;KAAA;IAEhC,OAAO;QACL,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IACD,cAAc;QACZ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IACD,wBAAwB;QACtB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;CACF;AAED,SAAS,YAAY,CAAC,cAQrB;IACC,OAAO,MAAM,CACX,oBAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,cAAc;QACzC,oBAAC,MAAM;YACL,oBAAC,sBAAsB,IACrB,QAAQ,EAAC,UAAU,EACnB,SAAS,EAAC,WAAW,EACrB,gBAAgB,EAAC,EAAE;gBAEnB,oBAAC,MAAM;oBACL,oBAAC,cAAc,IAAC,SAAS,EAAE,aAAa,EAAE,IAAI,EAAC,GAAG,GAAG,CAC9C,CACc,CAClB,CACY,CACxB,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,MAAM,WAAW,GAAG,IAAI,eAAe,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACpD,UAAU,CAAC,GAAG,EAAE;QACd,SAAS,CAAC,SAAS,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IACH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,MAAM,cAAc,GAAG;YACrB,IAAI,EAAE;gBACJ,SAAS,EAAE,YAAY;gBACvB,QAAQ,EAAE,aAAa;gBACvB,KAAK,EAAE,kBAAkB;gBACzB,KAAK,EAAE,CAAC,oBAAoB,CAAC;aAC9B;YACD,WAAW;SACZ,CAAC;QACF,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;YAC3B,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;YACnD,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACzC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;YACnC,MAAM,cAAc,GAAG;gBACrB,YAAY,EAAE,IAAI;gBAClB,WAAW;aACZ,CAAC;YACF,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;gBACjC,YAAY,CAAC,cAAc,CAAC,CAAC;gBAC7B,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC;YAC9C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;YACrC,MAAM,cAAc,GAAG;gBACrB,WAAW;aACZ,CAAC;YACF,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;gBAC1B,MAAM,EAAE,WAAW,EAAE,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;gBACrD,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;gBAC5D,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YAC7C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,sBAAsB;AACtB,6BAA6B;AAC7B,MAAM"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as ProtectedRoute } from "./ProtectedRoute";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ProtectedRoute/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ProtectedRoute";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { IAuthService } from "../services/IAuthService";
|
|
3
|
+
import { User } from "../types";
|
|
4
|
+
declare type Props = {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
authService: IAuthService;
|
|
7
|
+
onError: (error: Error) => void;
|
|
8
|
+
onUserIdentified: (user: User) => void;
|
|
9
|
+
};
|
|
10
|
+
declare type ProviderValue = {
|
|
11
|
+
user?: User;
|
|
12
|
+
authService: IAuthService;
|
|
13
|
+
};
|
|
14
|
+
export declare const AuthContext: React.Context<ProviderValue>;
|
|
15
|
+
export declare const AuthProvider: ({ children, authService, onError, onUserIdentified, }: Props) => JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React, { useState, useEffect, useMemo } from "react";
|
|
2
|
+
export const AuthContext = React.createContext(null);
|
|
3
|
+
export const AuthProvider = ({ children, authService, onError, onUserIdentified, }) => {
|
|
4
|
+
const [user, setUser] = useState(null);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
function trySetUser() {
|
|
7
|
+
const user = authService.user;
|
|
8
|
+
if (user) {
|
|
9
|
+
setUser(user);
|
|
10
|
+
onUserIdentified(user);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
trySetUser();
|
|
14
|
+
const handleUserChanged = () => {
|
|
15
|
+
trySetUser();
|
|
16
|
+
};
|
|
17
|
+
authService.on("userChanged", handleUserChanged).on("error", onError);
|
|
18
|
+
return () => {
|
|
19
|
+
authService.off("userChanged", handleUserChanged).off("error", onError);
|
|
20
|
+
};
|
|
21
|
+
}, [setUser, onUserIdentified, authService, onError]);
|
|
22
|
+
const providerValue = useMemo(() => ({
|
|
23
|
+
user,
|
|
24
|
+
authService,
|
|
25
|
+
}), [authService, user]);
|
|
26
|
+
return (React.createElement(AuthContext.Provider, { value: providerValue }, children));
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=AuthContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthContext.js","sourceRoot":"","sources":["../../src/contexts/AuthContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAgB5D,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAAgB,IAAI,CAAC,CAAC;AAEpE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,QAAQ,EACR,WAAW,EACX,OAAO,EACP,gBAAgB,GACV,EAAE,EAAE;IACV,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAO,IAAI,CAAC,CAAC;IAE7C,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,UAAU;YACjB,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC;YAE9B,IAAI,IAAI,EAAE;gBACR,OAAO,CAAC,IAAI,CAAC,CAAC;gBACd,gBAAgB,CAAC,IAAI,CAAC,CAAC;aACxB;QACH,CAAC;QAED,UAAU,EAAE,CAAC;QAEb,MAAM,iBAAiB,GAAG,GAAG,EAAE;YAC7B,UAAU,EAAE,CAAC;QACf,CAAC,CAAC;QACF,WAAW,CAAC,EAAE,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAEtE,OAAO,GAAG,EAAE;YACV,WAAW,CAAC,GAAG,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1E,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IAEtD,MAAM,aAAa,GAAkB,OAAO,CAC1C,GAAG,EAAE,CAAC,CAAC;QACL,IAAI;QACJ,WAAW;KACZ,CAAC,EACF,CAAC,WAAW,EAAE,IAAI,CAAC,CACpB,CAAC;IAEF,OAAO,CACL,oBAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,aAAa,IACvC,QAAQ,CACY,CACxB,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
declare type Props = {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
tenantId: string;
|
|
5
|
+
privilege: string;
|
|
6
|
+
unauthorizedPath: string;
|
|
7
|
+
};
|
|
8
|
+
declare type ProviderValue = {
|
|
9
|
+
tenantId: string;
|
|
10
|
+
privilege: string;
|
|
11
|
+
unauthorizedPath: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const ProtectedRouteContext: React.Context<ProviderValue>;
|
|
14
|
+
export declare const ProtectedRouteProvider: ({ children, tenantId, privilege, unauthorizedPath, }: Props) => JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React, { useMemo } from "react";
|
|
2
|
+
export const ProtectedRouteContext = React.createContext(null);
|
|
3
|
+
export const ProtectedRouteProvider = ({ children, tenantId, privilege, unauthorizedPath, }) => {
|
|
4
|
+
const providerValue = useMemo(() => ({
|
|
5
|
+
tenantId,
|
|
6
|
+
privilege,
|
|
7
|
+
unauthorizedPath,
|
|
8
|
+
}), [unauthorizedPath, privilege, tenantId]);
|
|
9
|
+
return (React.createElement(ProtectedRouteContext.Provider, { value: providerValue }, children));
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=ProtectedRouteContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProtectedRouteContext.js","sourceRoot":"","sources":["../../src/contexts/ProtectedRouteContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAevC,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC,aAAa,CAAgB,IAAI,CAAC,CAAC;AAE9E,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,EACrC,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,gBAAgB,GACV,EAAE,EAAE;IACV,MAAM,aAAa,GAAkB,OAAO,CAC1C,GAAG,EAAE,CAAC,CAAC;QACL,QAAQ;QACR,SAAS;QACT,gBAAgB;KACjB,CAAC,EACF,CAAC,gBAAgB,EAAE,SAAS,EAAE,QAAQ,CAAC,CACxC,CAAC;IAEF,OAAO,CACL,oBAAC,qBAAqB,CAAC,QAAQ,IAAC,KAAK,EAAE,aAAa,IACjD,QAAQ,CACsB,CAClC,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import React, { useContext } from "react";
|
|
3
|
+
import { render } from "@testing-library/react";
|
|
4
|
+
import { AuthContext, AuthProvider } from "../AuthContext";
|
|
5
|
+
import EventEmitter from "events";
|
|
6
|
+
const TestComponent = () => {
|
|
7
|
+
const { user } = useContext(AuthContext);
|
|
8
|
+
return (React.createElement(React.Fragment, null,
|
|
9
|
+
React.createElement("div", null, user === null || user === void 0 ? void 0 : user.firstName),
|
|
10
|
+
React.createElement("div", null, user === null || user === void 0 ? void 0 : user.lastName),
|
|
11
|
+
React.createElement("div", null, user === null || user === void 0 ? void 0 : user.email)));
|
|
12
|
+
};
|
|
13
|
+
const mockedUser = {
|
|
14
|
+
firstName: "John",
|
|
15
|
+
lastName: "Doe",
|
|
16
|
+
email: "johnDoe@example.com",
|
|
17
|
+
roles: ["tenantId:privilege"],
|
|
18
|
+
};
|
|
19
|
+
class AuthServiceMock extends EventEmitter {
|
|
20
|
+
get user() {
|
|
21
|
+
return mockedUser;
|
|
22
|
+
}
|
|
23
|
+
completeSignInIfPossible() {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () { });
|
|
25
|
+
}
|
|
26
|
+
signIn() {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () { });
|
|
28
|
+
}
|
|
29
|
+
signOut() {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () { });
|
|
31
|
+
}
|
|
32
|
+
getAccessToken() {
|
|
33
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
return "";
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
describe("AuthContext", () => {
|
|
39
|
+
const authServiceMock = new AuthServiceMock();
|
|
40
|
+
it("provides the user", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
|
+
const { findByText } = render(React.createElement(AuthProvider, { authService: authServiceMock, onUserIdentified: jest.fn(), onError: jest.fn() },
|
|
42
|
+
React.createElement(TestComponent, null)));
|
|
43
|
+
expect(yield findByText(mockedUser.firstName)).toBeInTheDocument();
|
|
44
|
+
expect(yield findByText(mockedUser.lastName)).toBeInTheDocument();
|
|
45
|
+
expect(yield findByText(mockedUser.email)).toBeInTheDocument();
|
|
46
|
+
}));
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=AuthContext.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthContext.test.js","sourceRoot":"","sources":["../../../src/contexts/__tests__/AuthContext.test.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG3D,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,MAAM,aAAa,GAAG,GAAG,EAAE;IACzB,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAEzC,OAAO,CACL;QACE,iCAAM,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,SAAS,CAAO;QAC5B,iCAAM,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,CAAO;QAC3B,iCAAM,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,CAAO,CACvB,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,UAAU,GAAS;IACvB,SAAS,EAAE,MAAM;IACjB,QAAQ,EAAE,KAAK;IACf,KAAK,EAAE,qBAAqB;IAC5B,KAAK,EAAE,CAAC,oBAAoB,CAAC;CAC9B,CAAC;AAEF,MAAM,eAAgB,SAAQ,YAAY;IACxC,IAAI,IAAI;QACN,OAAO,UAAU,CAAC;IACpB,CAAC;IAEK,wBAAwB;8DAAmB,CAAC;KAAA;IAE5C,MAAM;8DAAmB,CAAC;KAAA;IAE1B,OAAO;8DAAmB,CAAC;KAAA;IAE3B,cAAc;;YAClB,OAAO,EAAE,CAAC;QACZ,CAAC;KAAA;CACF;AAED,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAE9C,EAAE,CAAC,mBAAmB,EAAE,GAAS,EAAE;QACjC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAC3B,oBAAC,YAAY,IACX,WAAW,EAAE,eAAe,EAC5B,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE,EAC3B,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;YAElB,oBAAC,aAAa,OAAG,CACJ,CAChB,CAAC;QAEF,MAAM,CAAC,MAAM,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;QACnE,MAAM,CAAC,MAAM,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;QAClE,MAAM,CAAC,MAAM,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;IACjE,CAAC,CAAA,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/contexts/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useContext, useEffect } from "react";
|
|
2
|
+
import { useHistory, useLocation } from "react-router-dom";
|
|
3
|
+
import qs from "qs";
|
|
4
|
+
import { AuthContext } from "../../contexts";
|
|
5
|
+
function AuthComponent({ basename }) {
|
|
6
|
+
const history = useHistory();
|
|
7
|
+
const location = useLocation();
|
|
8
|
+
const { authService, user } = useContext(AuthContext);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (user) {
|
|
11
|
+
const { state: relativeUrl } = qs.parse(location.search, {
|
|
12
|
+
ignoreQueryPrefix: true,
|
|
13
|
+
});
|
|
14
|
+
if (relativeUrl != null && relativeUrl.startsWith(basename)) {
|
|
15
|
+
// Remove basename from URL
|
|
16
|
+
const path = relativeUrl.substring(basename.length);
|
|
17
|
+
history.replace(path);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
history.replace("/");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}, [basename, history, location.search, user]);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
authService.completeSignInIfPossible();
|
|
26
|
+
}, [authService]);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
export default AuthComponent;
|
|
30
|
+
//# sourceMappingURL=Auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Auth.js","sourceRoot":"","sources":["../../../src/features/auth/Auth.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAM7C,SAAS,aAAa,CAAC,EAAE,QAAQ,EAAS;IACxC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAEtD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,EAAE;YACR,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE;gBACvD,iBAAiB,EAAE,IAAI;aACxB,CAAsB,CAAC;YAExB,IAAI,WAAW,IAAI,IAAI,IAAI,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;gBAC3D,2BAA2B;gBAC3B,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACpD,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;aACvB;iBAAM;gBACL,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;aACtB;SACF;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAE/C,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,CAAC,wBAAwB,EAAE,CAAC;IACzC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as AuthComponent } from "./Auth";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/features/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./auth";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/features/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthConfiguration.js","sourceRoot":"","sources":["../../src/services/AuthConfiguration.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from "events";
|
|
3
|
+
import { AuthConfiguration } from "./AuthConfiguration";
|
|
4
|
+
interface AuthFlowEvents {
|
|
5
|
+
tokenResponse(): void;
|
|
6
|
+
}
|
|
7
|
+
export declare interface AuthFlow {
|
|
8
|
+
on<E extends keyof AuthFlowEvents>(event: E, listener: AuthFlowEvents[E]): this;
|
|
9
|
+
off<E extends keyof AuthFlowEvents>(event: E, listener: AuthFlowEvents[E]): this;
|
|
10
|
+
emit<E extends keyof AuthFlowEvents>(event: E, ...args: Parameters<AuthFlowEvents[E]>): boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class AuthFlow extends EventEmitter {
|
|
13
|
+
private static readonly TOKEN_RESPONSE_KEY;
|
|
14
|
+
private static readonly s_requestor;
|
|
15
|
+
private readonly _configuration;
|
|
16
|
+
private readonly _notifier;
|
|
17
|
+
private readonly _authorizationHandler;
|
|
18
|
+
private readonly _tokenHandler;
|
|
19
|
+
private _serviceConfiguration;
|
|
20
|
+
private _tokenResponse;
|
|
21
|
+
private _refreshTokenPromise;
|
|
22
|
+
constructor(configuration: AuthConfiguration);
|
|
23
|
+
initialize(): void;
|
|
24
|
+
private authorizationListener;
|
|
25
|
+
signIn(identityProvider: string, force?: boolean): Promise<void>;
|
|
26
|
+
completeSignInIfPossible(): Promise<void>;
|
|
27
|
+
isSignedIn(): boolean;
|
|
28
|
+
getAccessToken(): Promise<string>;
|
|
29
|
+
signOut(): Promise<void>;
|
|
30
|
+
private signOutCore;
|
|
31
|
+
private makeAuthorizationRequest;
|
|
32
|
+
private ensureServiceConfiguration;
|
|
33
|
+
private saveState;
|
|
34
|
+
private loadState;
|
|
35
|
+
private makeTokenRequest;
|
|
36
|
+
private refreshToken;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import { AuthorizationRequest } from "@openid/appauth/built/authorization_request";
|
|
3
|
+
import { AuthorizationNotifier, } from "@openid/appauth/built/authorization_request_handler";
|
|
4
|
+
import { AuthorizationServiceConfiguration } from "@openid/appauth/built/authorization_service_configuration";
|
|
5
|
+
import { GRANT_TYPE_AUTHORIZATION_CODE, GRANT_TYPE_REFRESH_TOKEN, TokenRequest, } from "@openid/appauth/built/token_request";
|
|
6
|
+
import { BaseTokenRequestHandler, } from "@openid/appauth/built/token_request_handler";
|
|
7
|
+
import { TokenResponse } from "@openid/appauth/built/token_response";
|
|
8
|
+
import { EventEmitter } from "events";
|
|
9
|
+
import { FetchRequestor, RedirectRequestHandler, BasicQueryStringUtils, LocalStorageBackend, } from "@openid/appauth";
|
|
10
|
+
class NoHashQueryStringUtils extends BasicQueryStringUtils {
|
|
11
|
+
parse(input) {
|
|
12
|
+
return super.parse(input, false);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class AuthFlow extends EventEmitter {
|
|
16
|
+
constructor(configuration) {
|
|
17
|
+
super();
|
|
18
|
+
this._configuration = configuration;
|
|
19
|
+
this._notifier = new AuthorizationNotifier();
|
|
20
|
+
this._authorizationHandler = new RedirectRequestHandler(new LocalStorageBackend(), new NoHashQueryStringUtils());
|
|
21
|
+
this._tokenHandler = new BaseTokenRequestHandler(AuthFlow.s_requestor);
|
|
22
|
+
this._authorizationHandler.setAuthorizationNotifier(this._notifier);
|
|
23
|
+
this._notifier.setAuthorizationListener(this.authorizationListener.bind(this));
|
|
24
|
+
}
|
|
25
|
+
initialize() {
|
|
26
|
+
this.loadState();
|
|
27
|
+
}
|
|
28
|
+
authorizationListener(request, response, error) {
|
|
29
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
console.debug("Authorization request complete", request, response, error);
|
|
31
|
+
if (response) {
|
|
32
|
+
let codeVerifier;
|
|
33
|
+
if (request.internal && request.internal.code_verifier) {
|
|
34
|
+
codeVerifier = request.internal.code_verifier;
|
|
35
|
+
}
|
|
36
|
+
yield this.makeTokenRequest(response.code, codeVerifier);
|
|
37
|
+
this.emit("tokenResponse");
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
signIn(identityProvider, force = false) {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
if (!this.isSignedIn()) {
|
|
44
|
+
yield this.makeAuthorizationRequest(identityProvider);
|
|
45
|
+
}
|
|
46
|
+
else if (force) {
|
|
47
|
+
this.signOutCore();
|
|
48
|
+
yield this.makeAuthorizationRequest(identityProvider);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
completeSignInIfPossible() {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
yield this._authorizationHandler.completeAuthorizationRequestIfPossible();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
isSignedIn() {
|
|
58
|
+
return !!this._tokenResponse && this._tokenResponse.isValid();
|
|
59
|
+
}
|
|
60
|
+
getAccessToken() {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
// Do we already have a valid access token?
|
|
63
|
+
if (this._tokenResponse && this._tokenResponse.isValid()) {
|
|
64
|
+
return this._tokenResponse.accessToken;
|
|
65
|
+
}
|
|
66
|
+
// Try to refresh and get a new access token
|
|
67
|
+
if (this._refreshTokenPromise) {
|
|
68
|
+
return yield this._refreshTokenPromise;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
if (!this._tokenResponse) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
let result;
|
|
75
|
+
try {
|
|
76
|
+
this._refreshTokenPromise = this.refreshToken();
|
|
77
|
+
result = yield this._refreshTokenPromise;
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
this._refreshTokenPromise = undefined;
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
signOut() {
|
|
87
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
// forget all cached token state
|
|
89
|
+
const idToken = this._tokenResponse.idToken;
|
|
90
|
+
this.signOutCore();
|
|
91
|
+
const serviceConfiguration = yield this.ensureServiceConfiguration();
|
|
92
|
+
// TODO: update when sign out is ready
|
|
93
|
+
const postLogoutRedirectUri = this._configuration.postLogoutRedirectUri;
|
|
94
|
+
const endSessionUrl = `${serviceConfiguration.endSessionEndpoint}?id_token_hint=${idToken}&post_logout_redirect_uri=${postLogoutRedirectUri}`;
|
|
95
|
+
console.debug(`[AuthFlow] Signing out using post_logout_redirect_uri '${postLogoutRedirectUri}' (full endSession URL: '${endSessionUrl}') ...`);
|
|
96
|
+
window.location.assign(endSessionUrl);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
signOutCore() {
|
|
100
|
+
this._tokenResponse = undefined;
|
|
101
|
+
window.sessionStorage.removeItem(AuthFlow.TOKEN_RESPONSE_KEY);
|
|
102
|
+
}
|
|
103
|
+
makeAuthorizationRequest(identityProvider) {
|
|
104
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
+
const extras = {
|
|
106
|
+
idp: identityProvider,
|
|
107
|
+
};
|
|
108
|
+
const request = new AuthorizationRequest({
|
|
109
|
+
client_id: this._configuration.clientId,
|
|
110
|
+
redirect_uri: this._configuration.redirectUri,
|
|
111
|
+
scope: this._configuration.scope,
|
|
112
|
+
response_type: AuthorizationRequest.RESPONSE_TYPE_CODE,
|
|
113
|
+
state: `${window.location.pathname}${window.location.search}`,
|
|
114
|
+
extras: extras,
|
|
115
|
+
});
|
|
116
|
+
this._authorizationHandler.performAuthorizationRequest(yield this.ensureServiceConfiguration(), request);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
ensureServiceConfiguration() {
|
|
120
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
121
|
+
if (!this._serviceConfiguration) {
|
|
122
|
+
const response = yield AuthorizationServiceConfiguration.fetchFromIssuer(this._configuration.openIdIssuerUrl, AuthFlow.s_requestor);
|
|
123
|
+
this._serviceConfiguration = response;
|
|
124
|
+
}
|
|
125
|
+
return this._serviceConfiguration;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
saveState() {
|
|
129
|
+
window.sessionStorage.setItem(AuthFlow.TOKEN_RESPONSE_KEY, JSON.stringify(this._tokenResponse.toJson()));
|
|
130
|
+
}
|
|
131
|
+
loadState() {
|
|
132
|
+
const responseString = window.sessionStorage.getItem(AuthFlow.TOKEN_RESPONSE_KEY);
|
|
133
|
+
if (responseString != null) {
|
|
134
|
+
const responseJson = JSON.parse(responseString);
|
|
135
|
+
const response = new TokenResponse(responseJson);
|
|
136
|
+
this._tokenResponse = response;
|
|
137
|
+
this.emit("tokenResponse");
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
makeTokenRequest(code, codeVerifier) {
|
|
141
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
142
|
+
const extras = {};
|
|
143
|
+
if (codeVerifier) {
|
|
144
|
+
extras.code_verifier = codeVerifier;
|
|
145
|
+
}
|
|
146
|
+
const request = new TokenRequest({
|
|
147
|
+
code,
|
|
148
|
+
extras,
|
|
149
|
+
client_id: this._configuration.clientId,
|
|
150
|
+
redirect_uri: this._configuration.redirectUri,
|
|
151
|
+
grant_type: GRANT_TYPE_AUTHORIZATION_CODE,
|
|
152
|
+
refresh_token: undefined,
|
|
153
|
+
});
|
|
154
|
+
const response = yield this._tokenHandler.performTokenRequest(yield this.ensureServiceConfiguration(), request);
|
|
155
|
+
this._tokenResponse = response;
|
|
156
|
+
this.saveState();
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
refreshToken() {
|
|
160
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
161
|
+
console.debug("Refreshing token ...");
|
|
162
|
+
const refreshToken = this._tokenResponse.refreshToken;
|
|
163
|
+
this._tokenResponse = undefined;
|
|
164
|
+
window.sessionStorage.removeItem(AuthFlow.TOKEN_RESPONSE_KEY);
|
|
165
|
+
const request = new TokenRequest({
|
|
166
|
+
client_id: this._configuration.clientId,
|
|
167
|
+
redirect_uri: this._configuration.redirectUri,
|
|
168
|
+
grant_type: GRANT_TYPE_REFRESH_TOKEN,
|
|
169
|
+
refresh_token: refreshToken,
|
|
170
|
+
code: undefined,
|
|
171
|
+
extras: undefined,
|
|
172
|
+
});
|
|
173
|
+
const response = yield this._tokenHandler.performTokenRequest(yield this.ensureServiceConfiguration(), request);
|
|
174
|
+
this._tokenResponse = response;
|
|
175
|
+
this.saveState();
|
|
176
|
+
console.debug("Refreshed token -->", response);
|
|
177
|
+
return response.accessToken;
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
AuthFlow.TOKEN_RESPONSE_KEY = "AuthFlow:tokenResponse";
|
|
182
|
+
AuthFlow.s_requestor = new FetchRequestor();
|
|
183
|
+
//# sourceMappingURL=AuthFlow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthFlow.js","sourceRoot":"","sources":["../../src/services/AuthFlow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import EventEmitter from "events";
|
|
3
|
+
import { IAuthServiceEvents, IAuthService } from "./IAuthService";
|
|
4
|
+
import { User } from "../types";
|
|
5
|
+
import { AuthConfiguration } from "./AuthConfiguration";
|
|
6
|
+
export declare interface AuthService {
|
|
7
|
+
on<E extends keyof IAuthServiceEvents>(event: E, listener: IAuthServiceEvents[E]): this;
|
|
8
|
+
off<E extends keyof IAuthServiceEvents>(event: E, listener: IAuthServiceEvents[E]): this;
|
|
9
|
+
emit<E extends keyof IAuthServiceEvents>(event: E, ...args: Parameters<IAuthServiceEvents[E]>): boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare class AuthService extends EventEmitter implements IAuthService {
|
|
12
|
+
private static s_instance;
|
|
13
|
+
private readonly _auth;
|
|
14
|
+
private _user;
|
|
15
|
+
private constructor();
|
|
16
|
+
static get instance(): AuthService;
|
|
17
|
+
static initialize(configuration: AuthConfiguration): void;
|
|
18
|
+
private setUser;
|
|
19
|
+
private handleTokenResponse;
|
|
20
|
+
private getUser;
|
|
21
|
+
get user(): User;
|
|
22
|
+
signIn(force?: boolean): Promise<void>;
|
|
23
|
+
completeSignInIfPossible(): Promise<void>;
|
|
24
|
+
getAccessToken(): Promise<string | null>;
|
|
25
|
+
signOut(): Promise<void>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import { Logger } from "@touchtech/web-logging";
|
|
3
|
+
import EventEmitter from "events";
|
|
4
|
+
import jwtDecode from "jwt-decode";
|
|
5
|
+
import { AuthFlow } from "./AuthFlow";
|
|
6
|
+
import { getIdentityProviderFromHostname } from "../utils";
|
|
7
|
+
class JwtClaimTypes {
|
|
8
|
+
}
|
|
9
|
+
// Standard claims
|
|
10
|
+
JwtClaimTypes.EMAIL = "email";
|
|
11
|
+
JwtClaimTypes.GIVEN_NAME = "given_name";
|
|
12
|
+
JwtClaimTypes.FAMILY_NAME = "family_name";
|
|
13
|
+
// Non-standard claims
|
|
14
|
+
JwtClaimTypes.ROLE = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role";
|
|
15
|
+
export class AuthService extends EventEmitter {
|
|
16
|
+
constructor(configuration) {
|
|
17
|
+
super();
|
|
18
|
+
this._auth = new AuthFlow(configuration);
|
|
19
|
+
this._auth.on("tokenResponse", this.handleTokenResponse.bind(this));
|
|
20
|
+
this._auth.initialize();
|
|
21
|
+
}
|
|
22
|
+
static get instance() {
|
|
23
|
+
if (!AuthService.s_instance) {
|
|
24
|
+
throw new Error("AuthService has not been initialized");
|
|
25
|
+
}
|
|
26
|
+
return AuthService.s_instance;
|
|
27
|
+
}
|
|
28
|
+
static initialize(configuration) {
|
|
29
|
+
if (AuthService.s_instance) {
|
|
30
|
+
throw new Error("AuthService has already been initialized");
|
|
31
|
+
}
|
|
32
|
+
AuthService.s_instance = new AuthService(configuration);
|
|
33
|
+
}
|
|
34
|
+
setUser(user) {
|
|
35
|
+
if (this._user !== user) {
|
|
36
|
+
this._user = user;
|
|
37
|
+
this.emit("userChanged");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
handleTokenResponse() {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
try {
|
|
43
|
+
this.setUser(yield this.getUser());
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
this.emit("error", error);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
getUser() {
|
|
51
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
const accessToken = yield this.getAccessToken();
|
|
53
|
+
const decoded = jwtDecode(accessToken);
|
|
54
|
+
const email = decoded[JwtClaimTypes.EMAIL];
|
|
55
|
+
const firstName = decoded[JwtClaimTypes.GIVEN_NAME];
|
|
56
|
+
const lastName = decoded[JwtClaimTypes.FAMILY_NAME];
|
|
57
|
+
const role = decoded[JwtClaimTypes.ROLE];
|
|
58
|
+
const roles = Array.isArray(role) ? role : [role];
|
|
59
|
+
return { email, firstName, lastName, roles };
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
get user() {
|
|
63
|
+
return this._user;
|
|
64
|
+
}
|
|
65
|
+
signIn(force = false) {
|
|
66
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
+
try {
|
|
68
|
+
const identityProvider = getIdentityProviderFromHostname(window.location.hostname);
|
|
69
|
+
console.debug(`[AuthService] Using identity provider '${identityProvider}' ...`);
|
|
70
|
+
yield this._auth.signIn(identityProvider, force);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
this.emit("error", error);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
completeSignInIfPossible() {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
try {
|
|
80
|
+
yield this._auth.completeSignInIfPossible();
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
this.emit("error", error);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
getAccessToken() {
|
|
88
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
+
try {
|
|
90
|
+
return yield this._auth.getAccessToken();
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
Logger.instance.error(error.message, error);
|
|
94
|
+
this.emit("error", error);
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
signOut() {
|
|
100
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
+
try {
|
|
102
|
+
yield this._auth.signOut();
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
this.emit("error", error);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=AuthService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthService.js","sourceRoot":"","sources":["../../src/services/AuthService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { User } from "../types";
|
|
2
|
+
export interface IAuthServiceEvents {
|
|
3
|
+
userChanged(): void;
|
|
4
|
+
error(error: Error): void;
|
|
5
|
+
}
|
|
6
|
+
export interface IAuthService {
|
|
7
|
+
on<E extends keyof IAuthServiceEvents>(event: E, listener: IAuthServiceEvents[E]): this;
|
|
8
|
+
off<E extends keyof IAuthServiceEvents>(event: E, listener: IAuthServiceEvents[E]): this;
|
|
9
|
+
emit<E extends keyof IAuthServiceEvents>(event: E, ...args: Parameters<IAuthServiceEvents[E]>): boolean;
|
|
10
|
+
get user(): User;
|
|
11
|
+
signIn(force?: boolean): Promise<void>;
|
|
12
|
+
completeSignInIfPossible(): Promise<void>;
|
|
13
|
+
getAccessToken(): Promise<string | null>;
|
|
14
|
+
signOut(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IAuthService.js","sourceRoot":"","sources":["../../src/services/IAuthService.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
3
|
+
import EventEmitter from "events";
|
|
4
|
+
const mockedUser = {
|
|
5
|
+
firstName: "John",
|
|
6
|
+
lastName: "Doe",
|
|
7
|
+
email: "johnDoe@example.com",
|
|
8
|
+
roles: ["tenantId:privilege"],
|
|
9
|
+
};
|
|
10
|
+
const mockedToken = "mockedToken";
|
|
11
|
+
class AuthServiceMock extends EventEmitter {
|
|
12
|
+
get user() {
|
|
13
|
+
return mockedUser;
|
|
14
|
+
}
|
|
15
|
+
completeSignInIfPossible() {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () { });
|
|
17
|
+
}
|
|
18
|
+
signIn() {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () { });
|
|
20
|
+
}
|
|
21
|
+
signOut() {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () { });
|
|
23
|
+
}
|
|
24
|
+
getAccessToken() {
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
return mockedToken;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
describe("AuthService", () => {
|
|
31
|
+
const authServiceMock = new AuthServiceMock();
|
|
32
|
+
it("signs in", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
const signInSpy = jest.spyOn(authServiceMock, "signIn");
|
|
34
|
+
yield authServiceMock.signIn();
|
|
35
|
+
expect(signInSpy).toBeCalledTimes(1);
|
|
36
|
+
}));
|
|
37
|
+
it("signs out", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
+
const signOutSpy = jest.spyOn(authServiceMock, "signOut");
|
|
39
|
+
yield authServiceMock.signOut();
|
|
40
|
+
expect(signOutSpy).toBeCalledTimes(1);
|
|
41
|
+
}));
|
|
42
|
+
describe("getUser", () => {
|
|
43
|
+
it("returns the user", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
44
|
+
const { firstName, lastName, email, roles } = authServiceMock.user;
|
|
45
|
+
expect(firstName).toEqual(mockedUser.firstName);
|
|
46
|
+
expect(lastName).toEqual(mockedUser.lastName);
|
|
47
|
+
expect(email).toEqual(mockedUser.email);
|
|
48
|
+
expect(roles).toEqual(mockedUser.roles);
|
|
49
|
+
}));
|
|
50
|
+
});
|
|
51
|
+
describe("getAccessToken", () => {
|
|
52
|
+
it("returns the access token", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
53
|
+
const token = yield authServiceMock.getAccessToken();
|
|
54
|
+
expect(token).toEqual(mockedToken);
|
|
55
|
+
}));
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=AuthService.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthService.test.js","sourceRoot":"","sources":["../../../src/services/__tests__/AuthService.test.ts"],"names":[],"mappings":";AAAA,yDAAyD;AACzD,OAAO,YAAY,MAAM,QAAQ,CAAC;AAIlC,MAAM,UAAU,GAAS;IACvB,SAAS,EAAE,MAAM;IACjB,QAAQ,EAAE,KAAK;IACf,KAAK,EAAE,qBAAqB;IAC5B,KAAK,EAAE,CAAC,oBAAoB,CAAC;CAC9B,CAAC;AACF,MAAM,WAAW,GAAG,aAAa,CAAC;AAElC,MAAM,eAAgB,SAAQ,YAAY;IACxC,IAAI,IAAI;QACN,OAAO,UAAU,CAAC;IACpB,CAAC;IAEK,wBAAwB;8DAAmB,CAAC;KAAA;IAE5C,MAAM;8DAAmB,CAAC;KAAA;IAE1B,OAAO;8DAAmB,CAAC;KAAA;IAE3B,cAAc;;YAClB,OAAO,WAAW,CAAC;QACrB,CAAC;KAAA;CACF;AAED,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAE9C,EAAE,CAAC,UAAU,EAAE,GAAS,EAAE;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;QAExD,MAAM,eAAe,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,CAAC,SAAS,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAA,CAAC,CAAC;IAEH,EAAE,CAAC,WAAW,EAAE,GAAS,EAAE;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;QAE1D,MAAM,eAAe,CAAC,OAAO,EAAE,CAAC;QAChC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC,CAAA,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,kBAAkB,EAAE,GAAS,EAAE;YAChC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC,IAAI,CAAC;YAEnE,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAChD,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC9C,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACxC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC1C,CAAC,CAAA,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,0BAA0B,EAAE,GAAS,EAAE;YACxC,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,CAAC;YACrD,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACrC,CAAC,CAAA,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export class Privileges {
|
|
2
|
+
}
|
|
3
|
+
Privileges.UNIVERSAL = "universal";
|
|
4
|
+
Privileges.SHOWROOM_APP = "showroom-app";
|
|
5
|
+
Privileges.MARKETING_ENGINE_APP = "marketing-engine-app";
|
|
6
|
+
Privileges.USER_MANAGEMENT_APP = "user-management-app";
|
|
7
|
+
//# sourceMappingURL=Privileges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Privileges.js","sourceRoot":"","sources":["../../src/types/Privileges.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,UAAU;;AACE,oBAAS,GAAG,WAAW,CAAC;AACxB,uBAAY,GAAG,cAAc,CAAC;AAC9B,+BAAoB,GAAG,sBAAsB,CAAC;AAC9C,8BAAmB,GAAG,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TenantIds.js","sourceRoot":"","sources":["../../src/types/TenantIds.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,SAAS;;AACG,mBAAS,GAAG,sCAAsC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/types/user.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getIdentityProviderFromHostname(hostname: string): any;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const DEFAULT_IDENTITY_PROVIDER = "touchtech";
|
|
2
|
+
export function getIdentityProviderFromHostname(hostname) {
|
|
3
|
+
var _a;
|
|
4
|
+
const hostnameToIdentityProviderMap = {
|
|
5
|
+
"bestseller.digitalvenue.dev": "bestseller",
|
|
6
|
+
"bestseller.digitalvenue.app": "bestseller",
|
|
7
|
+
"bestseller.digitalvenue.training": "bestseller",
|
|
8
|
+
"bestseller.localhost": "bestseller",
|
|
9
|
+
};
|
|
10
|
+
return (_a = hostnameToIdentityProviderMap[hostname]) !== null && _a !== void 0 ? _a : DEFAULT_IDENTITY_PROVIDER;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=identityProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identityProvider.js","sourceRoot":"","sources":["../../src/utils/identityProvider.ts"],"names":[],"mappings":"AAAA,MAAM,yBAAyB,GAAG,WAAW,CAAC;AAE9C,MAAM,UAAU,+BAA+B,CAAC,QAAgB;;IAC9D,MAAM,6BAA6B,GAAG;QACpC,6BAA6B,EAAE,YAAY;QAC3C,6BAA6B,EAAE,YAAY;QAC3C,kCAAkC,EAAE,YAAY;QAChD,sBAAsB,EAAE,YAAY;KACrC,CAAC;IAEF,OAAO,MAAA,6BAA6B,CAAC,QAAQ,CAAC,mCAAI,yBAAyB,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Privileges, TenantIds } from "../types";
|
|
2
|
+
export function userHasAccess(user, tenantId, privilege) {
|
|
3
|
+
if (user) {
|
|
4
|
+
for (const role of user.roles) {
|
|
5
|
+
if (role === `${tenantId}:${privilege}` || // specific privilege for specific tenant
|
|
6
|
+
role === `${tenantId}:${Privileges.UNIVERSAL}` || // universal privilege for specific tenant
|
|
7
|
+
role === `${TenantIds.UNIVERSAL}:${privilege}` || // specific privilege for universal tenant
|
|
8
|
+
role === `${TenantIds.UNIVERSAL}:${Privileges.UNIVERSAL}` // universal privilege for universal tenant
|
|
9
|
+
) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=roles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.js","sourceRoot":"","sources":["../../src/utils/roles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAQ,MAAM,UAAU,CAAC;AAEvD,MAAM,UAAU,aAAa,CAAC,IAAU,EAAE,QAAgB,EAAE,SAAiB;IAC3E,IAAI,IAAI,EAAE;QACR,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;YAC7B,IACE,IAAI,KAAK,GAAG,QAAQ,IAAI,SAAS,EAAE,IAAI,yCAAyC;gBAChF,IAAI,KAAK,GAAG,QAAQ,IAAI,UAAU,CAAC,SAAS,EAAE,IAAI,0CAA0C;gBAC5F,IAAI,KAAK,GAAG,SAAS,CAAC,SAAS,IAAI,SAAS,EAAE,IAAI,0CAA0C;gBAC5F,IAAI,KAAK,GAAG,SAAS,CAAC,SAAS,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC,2CAA2C;cACrG;gBACA,OAAO,IAAI,CAAC;aACb;SACF;KACF;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@touchtech/web-auth",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "DSR Auth",
|
|
5
|
+
"source": "index.ts",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "rm -rf ./dist && tsc",
|
|
13
|
+
"dev": "rm -rf ./dist && tsc --watch",
|
|
14
|
+
"lint": "eslint --ext .jsx,.js,.tsx,.ts src/",
|
|
15
|
+
"check": "yarn lint && yarn test",
|
|
16
|
+
"prepublishOnly": "yarn check && yarn run build",
|
|
17
|
+
"prepublish": "yarn run build",
|
|
18
|
+
"test": "jest --passWithNoTests",
|
|
19
|
+
"format": "yarn run tool-prettier --list-different \"**/*.{css,html,js,ts,tsx,json}\"",
|
|
20
|
+
"tool-prettier": "prettier --ignore-path .gitignore"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/TouchtechAB/web-auth.git"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"auth"
|
|
28
|
+
],
|
|
29
|
+
"author": "Touchtech",
|
|
30
|
+
"license": "UNLICENSED",
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/TouchtechAB/dsr-next/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/TouchtechAB/web-auth#readme",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@testing-library/jest-dom": "^5.14.1",
|
|
37
|
+
"@testing-library/react": "^12.0.0",
|
|
38
|
+
"@testing-library/react-hooks": "^7.0.1",
|
|
39
|
+
"@testing-library/user-event": "^13.2.1",
|
|
40
|
+
"@types/jest": "^27.0.0",
|
|
41
|
+
"@types/node": "^15.12.2",
|
|
42
|
+
"@types/react": "^17.0.15",
|
|
43
|
+
"@types/react-dom": "^17.0.9",
|
|
44
|
+
"@typescript-eslint/eslint-plugin": "^4.28.5",
|
|
45
|
+
"@typescript-eslint/parser": "^4.28.5",
|
|
46
|
+
"eslint": "^7.32.0",
|
|
47
|
+
"eslint-plugin-react": "^7.24.0",
|
|
48
|
+
"eslint-plugin-import": "^2.24.2",
|
|
49
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
50
|
+
"eslint-config-prettier": "^8.3.0",
|
|
51
|
+
"eslint-plugin-react-hooks": "^4.2.0",
|
|
52
|
+
"identity-obj-proxy": "^3.0.0",
|
|
53
|
+
"jest": "^27.0.6",
|
|
54
|
+
"prettier": "^2.3.2",
|
|
55
|
+
"react": "^17.0.2",
|
|
56
|
+
"react-dom": "^17.0.2",
|
|
57
|
+
"ts-jest": "^27.0.4",
|
|
58
|
+
"typescript": "^4.5.4",
|
|
59
|
+
"clean-webpack-plugin": "^4.0.0"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"@openid/appauth": "^1.3.1",
|
|
63
|
+
"jwt-decode": "^3.1.2",
|
|
64
|
+
"@touchtech/web-logging": "^0.0.1",
|
|
65
|
+
"react-router-dom": "^5.3.0",
|
|
66
|
+
"react": "^17.0.2",
|
|
67
|
+
"react-dom": "^17.0.2",
|
|
68
|
+
"qs": "^6.10.1"
|
|
69
|
+
}
|
|
70
|
+
}
|