glitch-javascript-sdk 1.8.1 → 1.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,69 @@
1
+ import Route from "./interface";
2
+ import HTTP_METHODS from "../constants/HttpMethods";
3
+
4
+ class WebsiteAnalyticsRoute {
5
+ public static routes: { [key: string]: Route } = {
6
+ listSessions: {
7
+ url: '/analytics/sessions',
8
+ method: HTTP_METHODS.GET
9
+ },
10
+ listPageviews: {
11
+ url: '/analytics/pageviews',
12
+ method: HTTP_METHODS.GET
13
+ },
14
+ listEvents: {
15
+ url: '/analytics/events',
16
+ method: HTTP_METHODS.GET
17
+ },
18
+ overview: {
19
+ url: '/analytics/overview',
20
+ method: HTTP_METHODS.GET
21
+ },
22
+ collect: {
23
+ url: '/analytics/collect',
24
+ method: HTTP_METHODS.POST
25
+ },
26
+ sessionsAverage: {
27
+ url: '/analytics/sessions/average',
28
+ method: HTTP_METHODS.GET
29
+ },
30
+ sessionsHistogram: {
31
+ url: '/analytics/sessions/histogram',
32
+ method: HTTP_METHODS.GET
33
+ },
34
+ pageviewsOverTime: {
35
+ url: '/analytics/pageviews/over-time',
36
+ method: HTTP_METHODS.GET
37
+ },
38
+ topPages: {
39
+ url: '/analytics/pageviews/top-pages',
40
+ method: HTTP_METHODS.GET
41
+ },
42
+ eventsSummary: {
43
+ url: '/analytics/events/summary',
44
+ method: HTTP_METHODS.GET
45
+ },
46
+ popularEvents: {
47
+ url: '/analytics/events/popular',
48
+ method: HTTP_METHODS.GET
49
+ },
50
+ geoDistribution: {
51
+ url: '/analytics/geo-distribution',
52
+ method: HTTP_METHODS.GET
53
+ },
54
+ deviceBreakdown: {
55
+ url: '/analytics/device-breakdown',
56
+ method: HTTP_METHODS.GET
57
+ },
58
+ referrers: {
59
+ url: '/analytics/referrers',
60
+ method: HTTP_METHODS.GET
61
+ },
62
+ utmPerformance: {
63
+ url: '/analytics/utm-performance',
64
+ method: HTTP_METHODS.GET
65
+ }
66
+ };
67
+ }
68
+
69
+ export default WebsiteAnalyticsRoute;
@@ -1,8 +1,91 @@
1
1
  import { Config } from "../config";
2
2
  import Storage from "./Storage";
3
3
 
4
- class Session {
4
+ // Type declarations for crypto functionality
5
+ interface HmacInterface {
6
+ update(data: string): HmacInterface;
7
+ digest(encoding: 'hex'): string;
8
+ }
9
+
10
+ interface CryptoInterface {
11
+ createHmac(algorithm: string, secret: string): HmacInterface;
12
+ }
13
+
14
+ // Browser implementation using crypto-js
15
+ class BrowserCrypto implements CryptoInterface {
16
+ private CryptoJS: any;
17
+
18
+ constructor() {
19
+ this.CryptoJS = require('crypto-js');
20
+ }
21
+
22
+ createHmac(algorithm: string, secret: string): HmacInterface {
23
+ let data = '';
24
+
25
+ const hmac: HmacInterface = {
26
+ update: (updateData: string): HmacInterface => {
27
+ data = updateData;
28
+ return hmac;
29
+ },
30
+ digest: (encoding: 'hex'): string => {
31
+ if (encoding !== 'hex') {
32
+ throw new Error('Only hex encoding is supported in browser implementation');
33
+ }
34
+ return this.CryptoJS.HmacSHA256(data, secret).toString(this.CryptoJS.enc.Hex);
35
+ }
36
+ };
37
+
38
+ return hmac;
39
+ }
40
+ }
41
+
42
+ // Node.js implementation that maintains sync interface
43
+ class NodeCrypto implements CryptoInterface {
44
+ private crypto?: typeof import('crypto');
45
+
46
+ constructor() {
47
+ // Use dynamic import but handle it synchronously for interface compliance
48
+ try {
49
+ // This will throw in browser environments
50
+ this.crypto = require('crypto');
51
+ } catch (e) {
52
+ this.crypto = undefined;
53
+ }
54
+ }
55
+
56
+ createHmac(algorithm: string, secret: string): HmacInterface {
57
+ if (!this.crypto) {
58
+ throw new Error('Node.js crypto module not available');
59
+ }
60
+ return this.crypto.createHmac(algorithm, secret);
61
+ }
62
+ }
63
+
64
+ // Determine which crypto implementation to use
65
+ const getCrypto = (): CryptoInterface => {
66
+ try {
67
+ // Check if we're in Node.js environment and crypto is available
68
+ if (typeof process !== 'undefined' && process.versions?.node) {
69
+ const nodeCrypto = new NodeCrypto();
70
+ // Verify crypto was actually loaded
71
+ try {
72
+ nodeCrypto.createHmac('sha256', 'test');
73
+ return nodeCrypto;
74
+ } catch (e) {
75
+ console.warn('Node.js crypto not available, falling back to browser implementation');
76
+ }
77
+ }
78
+ } catch (e) {
79
+ console.warn('Node.js environment detection failed, falling back to browser implementation');
80
+ }
81
+ // Fall back to browser implementation
82
+ return new BrowserCrypto();
83
+ };
5
84
 
85
+ // Singleton crypto instance
86
+ const cryptoInstance: CryptoInterface = getCrypto();
87
+
88
+ class Session {
6
89
  private static _id_key = 'user_id';
7
90
  private static _first_name_key = 'user_first_name';
8
91
  private static _last_name_key = 'user_last_name';
@@ -34,14 +117,9 @@ class Session {
34
117
  return Storage.get(Session._email_key);
35
118
  }
36
119
 
37
- public static hasJoinedCommunity() {
120
+ public static hasJoinedCommunity(): boolean {
38
121
  const community = Storage.get('community');
39
-
40
- if(!community) {
41
- return false;
42
- }
43
-
44
- return (community?.me) ? true : false;
122
+ return !!community?.me;
45
123
  }
46
124
 
47
125
  public static end(): void {
@@ -53,7 +131,14 @@ class Session {
53
131
  Storage.set(Session._username_key, null);
54
132
  }
55
133
 
56
- public static processAuthentication(data: { token: { access_token: string }, id: string, first_name: string, last_name: string, email: string, username: string }): void {
134
+ public static processAuthentication(data: {
135
+ token: { access_token: string },
136
+ id: string,
137
+ first_name: string,
138
+ last_name: string,
139
+ email: string,
140
+ username: string
141
+ }): void {
57
142
  Storage.setAuthToken(data.token.access_token);
58
143
  Storage.set(Session._id_key, data.id);
59
144
  Storage.set(Session._first_name_key, data.first_name);
@@ -63,6 +148,32 @@ class Session {
63
148
 
64
149
  Config.setAuthToken(data.token.access_token);
65
150
  }
151
+
152
+ /**
153
+ * Generate a tracking token for analytics collection
154
+ * @param titleId The title ID to generate token for
155
+ * @param secret The secret key (should match server config)
156
+ * @returns HMAC-SHA256 token
157
+ * @throws Error if crypto operations fail
158
+ */
159
+ public static generateTrackingToken(titleId: string, secret: string): string {
160
+ try {
161
+ if (!titleId) {
162
+ throw new Error('titleId is required');
163
+ }
164
+ if (!secret) {
165
+ throw new Error('secret is required');
166
+ }
167
+
168
+ return cryptoInstance
169
+ .createHmac('sha256', secret)
170
+ .update(titleId)
171
+ .digest('hex');
172
+ } catch (error) {
173
+ console.error('Failed to generate tracking token:', error);
174
+ throw new Error('Failed to generate tracking token');
175
+ }
176
+ }
66
177
  }
67
178
 
68
- export default Session;
179
+ export default Session;