Passed
Push — trunk ( a19795...45f743 )
by Christian
17:17 queued 03:17
created

AppClientService.fetchHeaders   A

Complexity

Conditions 2

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 16
c 0
b 0
f 0
dl 0
loc 20
rs 9.6
1
/**
2
 * @package storefront
3
 */
4
export default class AppClientService {
5
    private readonly name: string;
6
    constructor(name: string) {
7
        this.name = name;
8
    }
9
10
    get(url: RequestInfo, options: RequestInit = {}) {
11
        options.method = 'GET';
12
13
        return this.request(url, options);
14
    }
15
16
    post(url: RequestInfo, options: RequestInit = {}) {
17
        options.method = 'POST';
18
19
        return this.request(url, options);
20
    }
21
22
    patch(url: RequestInfo, options: RequestInit = {}) {
23
        options.method = 'PATCH';
24
25
        return this.request(url, options);
26
    }
27
28
    delete(url: RequestInfo, options: RequestInit = {}) {
29
        options.method = 'DELETE';
30
31
        return this.request(url, options);
32
    }
33
34
    /**
35
     * Resets the token for the current app. This will force the next request to fetch a new token.
36
     */
37
    reset(): void {
38
        window.sessionStorage.removeItem(this.getStorageKey());
39
    }
40
41
    // @ts-ignore
42
    private getStorageKey() {
43
        return `app-system.${this.name}`;
44
    }
45
46
    private async getHeaders() {
47
        const key = this.getStorageKey();
48
        if (!window.sessionStorage.getItem(key)) {
49
            const data = await this.fetchHeaders();
50
51
            window.sessionStorage.setItem(key, JSON.stringify(data));
52
53
            return data.headers;
54
        }
55
56
        const data = JSON.parse(window.sessionStorage.getItem(key));
57
58
        if (new Date(data.expires) < new Date()) {
59
            window.sessionStorage.removeItem(key);
60
61
            return await this.getHeaders();
62
        }
63
64
        return data.headers;
65
    }
66
67
    private async fetchHeaders(): Promise<{ headers: { [key: string]: string }, expires: string }> {
68
        const url = window['router']['frontend.app-system.generate-token'].replace('Placeholder', encodeURIComponent(this.name));
69
        const response = await fetch(url, {
70
            method: 'POST',
71
        });
72
73
        if (!response.ok) {
74
            throw new Error(`Error while fetching token, got status code: ${response.status} with response ${await response.text()}`);
75
        }
76
77
        // eslint-disable-next-line no-undef
78
        const data = await response.json() as { token: string, shopId: string, expires: string };
79
80
        return {
81
            headers: {
82
                'shopware-app-token': data.token,
83
                'shopware-app-shop-id': data.shopId,
84
            },
85
            expires: data.expires,
86
        };
87
    }
88
89
    private async request(url: RequestInfo, options: RequestInit) {
90
        if (!options.headers) {
91
            options.headers = {};
92
        }
93
94
        options.headers = {...options.headers, ...await this.getHeaders()};
95
96
        return fetch(url, options)
97
    }
98
}
99