-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
viewer-cid-api.js
118 lines (107 loc) · 3.3 KB
/
viewer-cid-api.js
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
* Copyright 2017 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Services} from '../services';
import {dict} from '../utils/object';
import {user} from '../log';
const GOOGLE_CLIENT_ID_API_META_NAME = 'amp-google-client-id-api';
const CID_API_SCOPE_WHITELIST = {
'googleanalytics': 'AMP_ECID_GOOGLE',
};
const API_KEYS = {
'googleanalytics': 'AIzaSyA65lEHUEizIsNtlbNo-l2K18dT680nsaM',
};
const TAG = 'ViewerCidApi';
/**
* Exposes CID API if provided by the Viewer.
*/
export class ViewerCidApi {
constructor(ampdoc) {
/** @private {!./ampdoc-impl.AmpDoc} */
this.ampdoc_ = ampdoc;
/** @private {!./viewer-impl.Viewer} */
this.viewer_ = Services.viewerForDoc(this.ampdoc_);
/** @private {?Object<string, string>} */
this.apiKeyMap_ = null;
}
/**
* Resolves to true if Viewer is trusted and supports CID API.
* @returns {!Promise<boolean>}
*/
isSupported() {
if (!this.viewer_.hasCapability('cid')) {
return Promise.resolve(false);
}
return this.viewer_.isTrustedViewer();
}
/**
* Returns scoped CID retrieved from the Viewer.
* @param {!string} scope
* @return {!Promise<?JsonObject|string|undefined>}
*/
getScopedCid(scope) {
const apiKey = this.isScopeOptedIn(scope);
const payload = dict({
'scope': scope,
'clientIdApi': !!apiKey,
});
if (apiKey) {
payload['apiKey'] = apiKey;
}
return this.viewer_.sendMessageAwaitResponse('cid', payload);
}
/**
* Checks if the page has opted in CID API for the given scope.
* Returns the API key that should be used, or null if page hasn't opted in.
*
* @param {string} scope
* @return {string|undefined}
*/
isScopeOptedIn(scope) {
if (!this.apiKeyMap_) {
this.apiKeyMap_ = this.getOptedInScopes_();
}
return this.apiKeyMap_[scope];
}
/**
* @return {!Object<string, string>}
*/
getOptedInScopes_() {
const apiKeyMap = {};
const optInMeta = this.ampdoc_.win.document.head./*OK*/querySelector(
`meta[name=${GOOGLE_CLIENT_ID_API_META_NAME}]`);
if (optInMeta && optInMeta.hasAttribute('content')) {
const list = optInMeta.getAttribute('content').split(',');
list.forEach(item => {
item = item.trim();
if (item.indexOf('=') > 0) {
const pair = item.split('=');
const scope = pair[0].trim();
apiKeyMap[scope] = pair[1].trim();
} else {
const clientName = item;
const scope = CID_API_SCOPE_WHITELIST[clientName];
if (scope) {
apiKeyMap[scope] = API_KEYS[clientName];
} else {
user().error(TAG,
`Unsupported client for Google CID API: ${clientName}`);
}
}
});
}
return apiKeyMap;
}
}