-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathSaleorExternalAuth.ts
78 lines (63 loc) · 2.07 KB
/
SaleorExternalAuth.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
import { TypedDocumentString } from "./graphql";
import { ExternalAuthenticationURL, ExternalObtainAccessTokens } from "./mutations";
import { ExternalProvider } from "./types";
import { getRequestData } from "./utils";
interface RedirectData {
code: string;
state: string;
}
interface GraphQLErrorResponse {
errors: readonly {
message: string;
}[];
}
type GraphQLResponse<T> = { data: T } | GraphQLErrorResponse;
export class GraphQLError extends Error {
constructor(public errorResponse: GraphQLErrorResponse) {
const message = errorResponse.errors.map((error) => error.message).join("\n");
super(message);
this.name = this.constructor.name;
Object.setPrototypeOf(this, new.target.prototype);
}
}
export class SaleorExternalAuth {
constructor(
private saleorURL: string,
private provider: ExternalProvider,
) {}
async makePOSTRequest<TResult, TVariables>(
query: TypedDocumentString<TResult, TVariables>,
variables: TVariables,
) {
const response = await fetch(this.saleorURL, getRequestData(query, variables));
const result = (await response.json()) as GraphQLResponse<TResult>;
if ("errors" in result) {
console.error(result.errors);
throw new GraphQLError(result);
}
return result.data;
}
async initiate({ redirectURL }: { redirectURL: string }) {
const {
externalAuthenticationUrl: { authenticationData: data, errors },
} = await this.makePOSTRequest(ExternalAuthenticationURL, {
pluginId: this.provider,
input: JSON.stringify({ redirectUri: redirectURL }),
});
if (errors.length > 0) {
console.error({ errors });
throw new GraphQLError({ errors });
}
const { authorizationUrl } = JSON.parse(data) as {
authorizationUrl: string;
};
return authorizationUrl;
}
async obtainAccessToken({ code, state }: RedirectData) {
const { externalObtainAccessTokens: data } = await this.makePOSTRequest(ExternalObtainAccessTokens, {
pluginId: this.provider,
input: JSON.stringify({ code, state }),
});
return data;
}
}