UNPKG

8.23 kBPlain TextView Raw
1// (C) 2007-2020 GoodData Corporation
2import { XhrModule, ApiResponseError, ApiResponse } from "./xhr";
3import { ProjectModule } from "./project";
4import qs from "qs";
5
6export interface IUserConfigsSettingItem {
7 settingItem: {
8 key: string;
9 links: {
10 self: string;
11 };
12 source: string;
13 value: string;
14 };
15}
16
17export interface IUserConfigsResponse {
18 settings: {
19 items: IUserConfigsSettingItem[];
20 };
21}
22
23export class UserModule {
24 constructor(private xhr: XhrModule) {}
25
26 /**
27 * Find out whether a user is logged in
28 *
29 * @return {Promise} resolves with true if user logged in, false otherwise
30 * @method isLoggedIn
31 */
32 public isLoggedIn(): Promise<boolean> {
33 return new Promise((resolve, reject) => {
34 this.xhr.get("/gdc/account/token").then(
35 r => {
36 if (r.response.ok) {
37 resolve(true);
38 }
39
40 resolve(false);
41 },
42 (err: any) => {
43 if (err.response.status === 401) {
44 resolve(false);
45 } else {
46 reject(err);
47 }
48 },
49 );
50 });
51 }
52
53 /**
54 * Find out whether a specified project is available to a currently logged user
55 *
56 * @method isLoggedInProject
57 * @param {String} projectId A project identifier
58 * @return {Promise} Resolves with true if user logged in and project available,
59 * resolves with false if user logged in and project not available,
60 * rejects if user not logged in
61 */
62 public isLoggedInProject(projectId: string) {
63 return this.getCurrentProfile().then(profile => {
64 return new Promise((resolve, reject) => {
65 const projectModule = new ProjectModule(this.xhr);
66
67 projectModule.getProjects(profile.links.self.split("/")[4]).then(
68 projects => {
69 if (projects.find((p: any) => p.links.self === `/gdc/projects/${projectId}`)) {
70 resolve(true);
71 } else {
72 resolve(false);
73 }
74 },
75 (err: ApiResponseError) => {
76 reject(err);
77 },
78 );
79 });
80 });
81 }
82
83 /**
84 * This function provides an authentication entry point to the GD API. It is needed to authenticate
85 * by calling this function prior any other API calls. After providing valid credentials
86 * every subsequent API call in a current session will be authenticated.
87 *
88 * @method login
89 * @param {String} username
90 * @param {String} password
91 */
92 public login(username: string, password: string) {
93 return this.xhr
94 .post("/gdc/account/login", {
95 body: JSON.stringify({
96 postUserLogin: {
97 login: username,
98 password,
99 remember: 1,
100 captcha: "",
101 verifyCaptcha: "",
102 },
103 }),
104 })
105 .then(r => r.getData());
106 }
107
108 /**
109 * This function provides an authentication entry point to the GD API via SSO
110 * https://help.gooddata.com/display/developer/GoodData+PGP+Single+Sign-On
111 *
112 * @method loginSso
113 * @param {String} encryptedClaims PGP message
114 * @param {String} ssoProvider
115 * @param {String} targetUrl
116 */
117 public loginSso(encryptedClaims: string, ssoProvider: string, targetUrl: string) {
118 return this.xhr.post("/gdc/account/customerlogin", {
119 data: {
120 pgpLoginRequest: {
121 targetUrl,
122 ssoProvider,
123 encryptedClaims,
124 },
125 },
126 });
127 }
128
129 /**
130 * Logs out current user
131 * @method logout
132 */
133 public logout(): Promise<ApiResponse | void> {
134 return this.isLoggedIn().then(
135 (loggedIn: boolean): Promise<ApiResponse | void> => {
136 if (loggedIn) {
137 return this.xhr.get("/gdc/app/account/bootstrap").then((result: any) => {
138 const data = result.getData();
139 const userUri = data.bootstrapResource.accountSetting.links.self;
140 const userId = userUri.match(/([^\/]+)\/?$/)[1];
141
142 return this.xhr.del(`/gdc/account/login/${userId}`);
143 });
144 }
145
146 return Promise.resolve();
147 },
148 (err: ApiResponseError) => Promise.reject(err),
149 );
150 }
151
152 /**
153 * Gets current user's profile
154 * @method getCurrentProfile
155 * @return {Promise} Resolves with account setting object
156 */
157 public getCurrentProfile() {
158 return this.xhr.get("/gdc/account/profile/current").then(r => r.getData().accountSetting);
159 }
160
161 /**
162 * Updates user's profile settings
163 * @method updateProfileSettings
164 * @param {String} profileId - User profile identifier
165 * @param {Object} profileSetting
166 */
167 public updateProfileSettings(profileId: string, profileSetting: any): Promise<ApiResponse> {
168 // TODO
169 return this.xhr.put(`/gdc/account/profile/${profileId}/settings`, {
170 body: profileSetting,
171 });
172 }
173
174 /**
175 * Returns info about currently logged in user from bootstrap resource
176 * @method getAccountInfo
177 */
178 public getAccountInfo() {
179 return this.xhr.get("/gdc/app/account/bootstrap").then((result: any) => {
180 const data = result.getData();
181 return this.getAccountInfoInBootstrap(data);
182 });
183 }
184
185 /**
186 * Returns current user info from bootstrapData
187 * @method getAccountInfoInBootstrap
188 * @param bootstrapData - data was got from bootstrap resource
189 */
190 public getAccountInfoInBootstrap(bootstrapData: any) {
191 const {
192 bootstrapResource: {
193 accountSetting: {
194 login,
195 firstName,
196 lastName,
197 links: { self: profileUri },
198 },
199 current: { loginMD5 },
200 settings: { organizationName },
201 },
202 } = bootstrapData;
203 return {
204 login,
205 loginMD5,
206 firstName,
207 lastName,
208 organizationName,
209 profileUri,
210 };
211 }
212
213 /**
214 * Gets user configs including user specific feature flags
215 *
216 * @param {String} userId - A user identifier
217 * @return {IUserConfigsSettingItem[]} An array of user configs setting item
218 */
219 public getUserConfigs(userId: string): Promise<IUserConfigsSettingItem[]> {
220 return this.xhr.get(`/gdc/account/profile/${userId}/config`).then((apiResponse: ApiResponse) => {
221 const userConfigs: IUserConfigsResponse = apiResponse.getData();
222 const {
223 settings: { items },
224 } = userConfigs;
225
226 return items || [];
227 });
228 }
229
230 /**
231 * Returns the feature flags valid for the currently logged in user.
232 * @method getFeatureFlags
233 */
234 public getFeatureFlags() {
235 return this.xhr
236 .get("/gdc/app/account/bootstrap")
237 .then((r: any) => r.getData())
238 .then((result: any) => result.bootstrapResource.current.featureFlags);
239 }
240
241 /**
242 * Initiates SPI SAML SSO
243 * @param relayState URL of the page where the user is redirected after a successful login
244 */
245 public initiateSamlSso(relayState: string) {
246 this.xhr
247 .get(`/gdc/account/samlrequest?${qs.stringify({ relayState })}`)
248 .then(data => data.getData())
249 .then(response => {
250 const loginUrl = response.samlRequests.items[0].samlRequest.loginUrl;
251 window.location.assign(loginUrl);
252 });
253 }
254}