blob: 5b36c7a2a19af7996022adc78443f47b651f2a82 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import '@chopsui/prpc-client/prpc-client.js';
6
7/**
8 * @fileoverview pRPC-related helper functions.
9 */
10export default class AutoRefreshPrpcClient {
11 constructor(token, tokenExpiresSec) {
12 this.token = token;
13 this.tokenExpiresSec = tokenExpiresSec;
14 this.prpcClient = new window.chops.rpc.PrpcClient({
15 insecure: Boolean(location.hostname === 'localhost'),
16 fetchImpl: (url, options) => {
17 options.credentials = 'same-origin';
18 return fetch(url, options);
19 },
20 });
21 }
22
23 /**
24 * Refresh the XSRF token if necessary.
25 * TODO(ehmaldonado): Figure out how to handle failures to refresh tokens.
26 * Maybe fire an event that a root page handler could use to show a message.
27 * @async
28 */
29 async ensureTokenIsValid() {
30 if (AutoRefreshPrpcClient.isTokenExpired(this.tokenExpiresSec)) {
31 const headers = {'X-Xsrf-Token': this.token};
32 const message = {
33 token: this.token,
34 tokenPath: 'xhr',
35 };
36 const freshToken = await this.prpcClient.call(
37 'monorail.Sitewide', 'RefreshToken', message, headers);
38 this.token = freshToken.token;
39 this.tokenExpiresSec = freshToken.tokenExpiresSec;
40 }
41 }
42
43 /**
44 * Sends a pRPC request. Adds this.token to the request message after making
45 * sure it is fresh.
46 * @param {string} service Full service name, including package name.
47 * @param {string} method Service method name.
48 * @param {Object} message The protobuf message to send.
49 * @return {Object} The pRPC API response.
50 */
51 call(service, method, message) {
52 return this.ensureTokenIsValid().then(() => {
53 const headers = {'X-Xsrf-Token': this.token};
54 return this.prpcClient.call(service, method, message, headers);
55 });
56 }
57
58 /**
59 * Check if the token is expired.
60 * @param {number} tokenExpiresSec: the expiration time of the token.
61 * @return {boolean} Whether the token is expired.
62 */
63 static isTokenExpired(tokenExpiresSec) {
64 const tokenExpiresDate = new Date(tokenExpiresSec * 1000);
65 return tokenExpiresDate < new Date();
66 }
67}