Skip to content
This repository was archived by the owner on Jul 14, 2022. It is now read-only.

Commit 7c331e1

Browse files
authored
Merge pull request from GHSA-4279-h39w-2jqm
Do not store passwords in localStorage
2 parents df3b280 + 0b0842f commit 7c331e1

File tree

3 files changed

+131
-60
lines changed

3 files changed

+131
-60
lines changed

Diff for: CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable, unreleased changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
## 2.10.3
8+
9+
- Stop storing plain text passwords in localStorage - by @dominik-zeglen
10+
711
## 2.10.2
812

913
- Fix fetching `quantityAvailable` field - #738 by @AlicjaSzu

Diff for: src/@sdk/api/APIProxy.ts

+107-60
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ import { GraphQLError } from "graphql";
88

99
import { fireSignOut, getAuthToken, setAuthToken } from "../auth";
1010
import { MUTATIONS } from "../mutations";
11-
import { TokenAuth } from "../mutations/gqlTypes/TokenAuth";
11+
import { PasswordChange } from "../mutations/gqlTypes/PasswordChange";
12+
import { SetPassword } from "../mutations/gqlTypes/SetPassword";
13+
import {
14+
TokenAuth,
15+
TokenAuth_tokenCreatte,
16+
} from "../mutations/gqlTypes/TokenAuth";
1217
import { QUERIES } from "../queries";
1318
import { UserDetails } from "../queries/gqlTypes/UserDetails";
1419
import { RequireAtLeastOne } from "../tsHelpers";
@@ -25,67 +30,70 @@ import {
2530
isDataEmpty,
2631
mergeEdges,
2732
} from "../utils";
33+
import { SetPasswordChange, SetPasswordResult, SignIn } from "./types";
2834

2935
export class APIProxy {
30-
getAttributes = this.watchQuery(QUERIES.Attributes, data => data.attributes);
36+
getAttributes = this.watchQuery(
37+
QUERIES.Attributes,
38+
(data) => data.attributes
39+
);
3140

3241
getProductDetails = this.watchQuery(
3342
QUERIES.ProductDetails,
34-
data => data.product
43+
(data) => data.product
3544
);
3645

37-
getProductList = this.watchQuery(QUERIES.ProductList, data => data.products);
46+
getProductList = this.watchQuery(
47+
QUERIES.ProductList,
48+
(data) => data.products
49+
);
3850

3951
getCategoryDetails = this.watchQuery(
4052
QUERIES.CategoryDetails,
41-
data => data.category
53+
(data) => data.category
4254
);
4355

44-
getOrdersByUser = this.watchQuery(QUERIES.OrdersByUser, data =>
56+
getOrdersByUser = this.watchQuery(QUERIES.OrdersByUser, (data) =>
4557
data.me ? data.me.orders : null
4658
);
4759

4860
getOrderDetails = this.watchQuery(
4961
QUERIES.OrderDetails,
50-
data => data.orderByToken
62+
(data) => data.orderByToken
5163
);
5264

5365
getVariantsProducts = this.watchQuery(
5466
QUERIES.VariantsProducts,
55-
data => data.productVariants
67+
(data) => data.productVariants
5668
);
5769

58-
getShopDetails = this.watchQuery(QUERIES.GetShopDetails, data => data);
70+
getShopDetails = this.watchQuery(QUERIES.GetShopDetails, (data) => data);
5971

6072
setUserDefaultAddress = this.fireQuery(
6173
MUTATIONS.AddressTypeUpdate,
62-
data => data!.accountSetDefaultAddress
74+
(data) => data!.accountSetDefaultAddress
6375
);
6476

6577
setDeleteUserAddress = this.fireQuery(
6678
MUTATIONS.DeleteUserAddress,
67-
data => data!.accountAddressDelete
79+
(data) => data!.accountAddressDelete
6880
);
6981

7082
setCreateUserAddress = this.fireQuery(
7183
MUTATIONS.CreateUserAddress,
72-
data => data!.accountAddressCreate
84+
(data) => data!.accountAddressCreate
7385
);
7486

7587
setUpdateuserAddress = this.fireQuery(
7688
MUTATIONS.UpdateUserAddress,
77-
data => data!.accountAddressUpdate
89+
(data) => data!.accountAddressUpdate
7890
);
7991

8092
setAccountUpdate = this.fireQuery(
8193
MUTATIONS.AccountUpdate,
82-
data => data!.accountUpdate
94+
(data) => data!.accountUpdate
8395
);
8496

85-
setPasswordChange = this.fireQuery(MUTATIONS.PasswordChange, data => data);
86-
87-
setPassword = this.fireQuery(MUTATIONS.SetPassword, data => data);
88-
8997
client: ApolloClient<any>;
9098

9199
constructor(client: ApolloClient<any>) {
@@ -99,7 +107,7 @@ export class APIProxy {
99107
}
100108
) => {
101109
if (this.isLoggedIn()) {
102-
return this.watchQuery(QUERIES.UserDetails, data => data.me)(
110+
return this.watchQuery(QUERIES.UserDetails, (data) => data.me)(
103111
variables,
104112
options
105113
);
@@ -116,47 +124,40 @@ export class APIProxy {
116124
};
117125
};
118126

119-
signIn = (
127+
signIn = async (
120128
variables: InferOptions<MUTATIONS["TokenAuth"]>["variables"],
121129
options?: Omit<InferOptions<MUTATIONS["TokenAuth"]>, "variables">
122-
) =>
123-
new Promise<{ data: TokenAuth["tokenCreate"] }>(async (resolve, reject) => {
124-
try {
125-
this.client.resetStore();
126-
127-
const data = await this.fireQuery(
128-
MUTATIONS.TokenAuth,
129-
data => data!.tokenCreate
130-
)(variables, {
131-
...options,
132-
update: (proxy, data) => {
133-
const handledData = handleDataErrors(
134-
(data: any) => data.tokenCreate,
135-
data.data,
136-
data.errors
137-
);
138-
if (!handledData.errors && handledData.data) {
139-
setAuthToken(handledData.data.token);
140-
if (window.PasswordCredential && variables) {
141-
navigator.credentials.store(
142-
new window.PasswordCredential({
143-
id: variables.email,
144-
password: variables.password,
145-
})
146-
);
147-
}
148-
}
149-
if (options && options.update) {
150-
options.update(proxy, data);
151-
}
152-
},
153-
});
154-
155-
resolve(data);
156-
} catch (e) {
157-
reject(e);
158-
}
130+
): Promise<SignIn> => {
131+
await this.client.resetStore();
132+
let result: {
133+
data: TokenAuth_tokenCreate | null;
134+
} | null = null;
135+
136+
result = await this.fireQuery(
137+
MUTATIONS.TokenAuth,
138+
(mutationData) => mutationData!.tokenCreate
139+
)(variables, {
140+
...options,
141+
fetchPolicy: "no-cache",
159142
});
143+
const { data } = result;
144+
145+
if (data?.token && data.errors.length === 0) {
146+
setAuthToken(data.token);
147+
if (window.PasswordCredential && variables) {
148+
navigator.credentials.store(
149+
new window.PasswordCredential({
150+
id: variables.email,
151+
password: variables.password,
152+
})
153+
);
154+
}
155+
}
156+
return {
157+
data,
158+
error: null,
159+
};
160+
};
160161

161162
signOut = () =>
162163
new Promise(async (resolve, reject) => {
@@ -169,6 +170,52 @@ export class APIProxy {
169170
}
170171
});
171172

173+
setPassword = async (
174+
variables: InferOptions<MUTATIONS["SetPassword"]>["variables"],
175+
options?: Omit<InferOptions<MUTATIONS["SetPassword"]>, "variables">
176+
): Promise<SetPasswordResult> => {
177+
let result: {
178+
data: SetPassword | null;
179+
} | null = null;
180+
181+
result = await this.fireQuery(MUTATIONS.SetPassword, (data) => data!)(
182+
variables,
183+
{
184+
...options,
185+
fetchPolicy: "no-cache",
186+
}
187+
);
188+
const { data } = result;
189+
190+
return {
191+
data,
192+
error: null,
193+
};
194+
};
195+
196+
setPasswordChange = async (
197+
variables: InferOptions<MUTATIONS["PasswordChange"]>["variables"],
198+
options?: Omit<InferOptions<MUTATIONS["PasswordChange"]>, "variables">
199+
): Promise<SetPasswordChange> => {
200+
let result: {
201+
data: PasswordChange | null;
202+
} | null = null;
203+
204+
result = await this.fireQuery(MUTATIONS.PasswordChange, (data) => data!)(
205+
variables,
206+
{
207+
...options,
208+
fetchPolicy: "no-cache",
209+
}
210+
);
211+
const { data } = result;
212+
213+
return {
214+
data,
215+
error: null,
216+
};
217+
};
218+
172219
attachAuthListener = (callback: (authenticated: boolean) => void) => {
173220
const eventHandler = () => {
174221
callback(this.isLoggedIn());
@@ -226,7 +273,7 @@ export class APIProxy {
226273
}
227274

228275
const subscription = observable.subscribe(
229-
result => {
276+
(result) => {
230277
const { data, errors: apolloErrors } = result;
231278
const errorHandledData = handleDataErrors(
232279
mapFn,
@@ -246,7 +293,7 @@ export class APIProxy {
246293
}
247294
}
248295
},
249-
error => {
296+
(error) => {
250297
if (onError) {
251298
onError(error);
252299
}
@@ -281,7 +328,7 @@ export class APIProxy {
281328
);
282329

283330
// use new result for metadata and mutate existing data
284-
Object.keys(prevResultRef).forEach(key => {
331+
Object.keys(prevResultRef).forEach((key) => {
285332
prevResultRef[key] = newResultRef[key];
286333
});
287334
prevResultRef.edges = mergedEdges;

Diff for: src/@sdk/api/types.ts

+20
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import { ApolloError } from "apollo-client";
2+
import { PasswordChange } from "../mutations/gqlTypes/PasswordChange";
3+
import { SetPassword } from "../mutations/gqlTypes/SetPassword";
4+
import { TokenAuth_tokenCreate } from "../mutations/gqlTypes/TokenAuth";
5+
16
export interface ErrorResponse<T> {
27
error?: any;
38
type?: T;
@@ -15,3 +20,18 @@ export interface FunctionRunResponse<D, F> {
1520

1621
export type PromiseQueuedResponse = Promise<FunctionQueueResponse>;
1722
export type PromiseRunResponse<D, F> = Promise<FunctionRunResponse<D, F>>;
23+
24+
export type SignIn = {
25+
data: TokenAuth_tokenCreate | null;
26+
error: ApolloError | null;
27+
} | null;
28+
29+
export type SetPasswordChange = {
30+
data: PasswordChange | null;
31+
error: ApolloError | null;
32+
} | null;
33+
34+
export type SetPasswordResult = {
35+
data: SetPassword | null;
36+
error: ApolloError | null;
37+
} | null;

0 commit comments

Comments
 (0)