@followgate/js 0.2.0 → 0.4.0
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.
- package/dist/index.d.mts +26 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +123 -3
- package/dist/index.mjs +121 -2
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -15,6 +15,14 @@ interface FollowGateConfig {
|
|
|
15
15
|
apiUrl?: string;
|
|
16
16
|
debug?: boolean;
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* SDK Error class with helpful messages
|
|
20
|
+
*/
|
|
21
|
+
declare class FollowGateError extends Error {
|
|
22
|
+
code: string;
|
|
23
|
+
hint?: string | undefined;
|
|
24
|
+
constructor(message: string, code: string, hint?: string | undefined);
|
|
25
|
+
}
|
|
18
26
|
/**
|
|
19
27
|
* Open action options
|
|
20
28
|
*/
|
|
@@ -44,6 +52,13 @@ interface AuthenticatedUser {
|
|
|
44
52
|
username: string;
|
|
45
53
|
platform: Platform;
|
|
46
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Auth state when username input is needed
|
|
57
|
+
*/
|
|
58
|
+
interface PendingUsernameState {
|
|
59
|
+
needsUsername: true;
|
|
60
|
+
token: string;
|
|
61
|
+
}
|
|
47
62
|
/**
|
|
48
63
|
* Authentication options
|
|
49
64
|
*/
|
|
@@ -61,8 +76,10 @@ declare class FollowGateClient {
|
|
|
61
76
|
private listeners;
|
|
62
77
|
private currentUser;
|
|
63
78
|
private authToken;
|
|
79
|
+
private pendingUsername;
|
|
64
80
|
/**
|
|
65
81
|
* Initialize the SDK
|
|
82
|
+
* @throws {FollowGateError} If configuration is invalid
|
|
66
83
|
*/
|
|
67
84
|
init(config: FollowGateConfig): void;
|
|
68
85
|
/**
|
|
@@ -82,6 +99,14 @@ declare class FollowGateClient {
|
|
|
82
99
|
* Logout - clear stored session
|
|
83
100
|
*/
|
|
84
101
|
logout(): void;
|
|
102
|
+
/**
|
|
103
|
+
* Check if username input is needed (Twitter Free Tier limitation)
|
|
104
|
+
*/
|
|
105
|
+
needsUsernameInput(): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Set username manually (when needsUsernameInput() returns true)
|
|
108
|
+
*/
|
|
109
|
+
setUsername(username: string): void;
|
|
85
110
|
/**
|
|
86
111
|
* Handle auth callback from URL params
|
|
87
112
|
*/
|
|
@@ -121,4 +146,4 @@ declare class FollowGateClient {
|
|
|
121
146
|
}
|
|
122
147
|
declare const FollowGate: FollowGateClient;
|
|
123
148
|
|
|
124
|
-
export { type AuthOptions, type AuthenticatedUser, type EventCallback, type EventType, FollowGate, FollowGateClient, type FollowGateConfig, type LinkedInTargetType, type OpenOptions, type Platform, type SocialAction };
|
|
149
|
+
export { type AuthOptions, type AuthenticatedUser, type EventCallback, type EventType, FollowGate, FollowGateClient, type FollowGateConfig, FollowGateError, type LinkedInTargetType, type OpenOptions, type PendingUsernameState, type Platform, type SocialAction };
|
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,14 @@ interface FollowGateConfig {
|
|
|
15
15
|
apiUrl?: string;
|
|
16
16
|
debug?: boolean;
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* SDK Error class with helpful messages
|
|
20
|
+
*/
|
|
21
|
+
declare class FollowGateError extends Error {
|
|
22
|
+
code: string;
|
|
23
|
+
hint?: string | undefined;
|
|
24
|
+
constructor(message: string, code: string, hint?: string | undefined);
|
|
25
|
+
}
|
|
18
26
|
/**
|
|
19
27
|
* Open action options
|
|
20
28
|
*/
|
|
@@ -44,6 +52,13 @@ interface AuthenticatedUser {
|
|
|
44
52
|
username: string;
|
|
45
53
|
platform: Platform;
|
|
46
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Auth state when username input is needed
|
|
57
|
+
*/
|
|
58
|
+
interface PendingUsernameState {
|
|
59
|
+
needsUsername: true;
|
|
60
|
+
token: string;
|
|
61
|
+
}
|
|
47
62
|
/**
|
|
48
63
|
* Authentication options
|
|
49
64
|
*/
|
|
@@ -61,8 +76,10 @@ declare class FollowGateClient {
|
|
|
61
76
|
private listeners;
|
|
62
77
|
private currentUser;
|
|
63
78
|
private authToken;
|
|
79
|
+
private pendingUsername;
|
|
64
80
|
/**
|
|
65
81
|
* Initialize the SDK
|
|
82
|
+
* @throws {FollowGateError} If configuration is invalid
|
|
66
83
|
*/
|
|
67
84
|
init(config: FollowGateConfig): void;
|
|
68
85
|
/**
|
|
@@ -82,6 +99,14 @@ declare class FollowGateClient {
|
|
|
82
99
|
* Logout - clear stored session
|
|
83
100
|
*/
|
|
84
101
|
logout(): void;
|
|
102
|
+
/**
|
|
103
|
+
* Check if username input is needed (Twitter Free Tier limitation)
|
|
104
|
+
*/
|
|
105
|
+
needsUsernameInput(): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Set username manually (when needsUsernameInput() returns true)
|
|
108
|
+
*/
|
|
109
|
+
setUsername(username: string): void;
|
|
85
110
|
/**
|
|
86
111
|
* Handle auth callback from URL params
|
|
87
112
|
*/
|
|
@@ -121,4 +146,4 @@ declare class FollowGateClient {
|
|
|
121
146
|
}
|
|
122
147
|
declare const FollowGate: FollowGateClient;
|
|
123
148
|
|
|
124
|
-
export { type AuthOptions, type AuthenticatedUser, type EventCallback, type EventType, FollowGate, FollowGateClient, type FollowGateConfig, type LinkedInTargetType, type OpenOptions, type Platform, type SocialAction };
|
|
149
|
+
export { type AuthOptions, type AuthenticatedUser, type EventCallback, type EventType, FollowGate, FollowGateClient, type FollowGateConfig, FollowGateError, type LinkedInTargetType, type OpenOptions, type PendingUsernameState, type Platform, type SocialAction };
|
package/dist/index.js
CHANGED
|
@@ -21,19 +21,68 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
FollowGate: () => FollowGate,
|
|
24
|
-
FollowGateClient: () => FollowGateClient
|
|
24
|
+
FollowGateClient: () => FollowGateClient,
|
|
25
|
+
FollowGateError: () => FollowGateError
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(index_exports);
|
|
27
28
|
var DEFAULT_API_URL = "https://api.followgate.app";
|
|
29
|
+
var FollowGateError = class extends Error {
|
|
30
|
+
constructor(message, code, hint) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.code = code;
|
|
33
|
+
this.hint = hint;
|
|
34
|
+
this.name = "FollowGateError";
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
function isValidApiKeyFormat(apiKey) {
|
|
38
|
+
return /^fg_(live|test)_[a-zA-Z0-9_-]+$/.test(apiKey);
|
|
39
|
+
}
|
|
28
40
|
var FollowGateClient = class {
|
|
29
41
|
config = null;
|
|
30
42
|
listeners = /* @__PURE__ */ new Map();
|
|
31
43
|
currentUser = null;
|
|
32
44
|
authToken = null;
|
|
45
|
+
pendingUsername = null;
|
|
33
46
|
/**
|
|
34
47
|
* Initialize the SDK
|
|
48
|
+
* @throws {FollowGateError} If configuration is invalid
|
|
35
49
|
*/
|
|
36
50
|
init(config) {
|
|
51
|
+
if (!config.appId || typeof config.appId !== "string") {
|
|
52
|
+
throw new FollowGateError(
|
|
53
|
+
"[FollowGate] Missing or invalid appId",
|
|
54
|
+
"INVALID_APP_ID",
|
|
55
|
+
"Get your App ID from https://followgate.app/dashboard. Make sure NEXT_PUBLIC_FOLLOWGATE_APP_ID is set in your environment."
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
if (config.appId.trim() === "" || config.appId === "undefined") {
|
|
59
|
+
throw new FollowGateError(
|
|
60
|
+
"[FollowGate] appId is empty or undefined",
|
|
61
|
+
"EMPTY_APP_ID",
|
|
62
|
+
"Your appId appears to be empty. This often happens when environment variables are not properly configured. Check that NEXT_PUBLIC_FOLLOWGATE_APP_ID is set and rebuild your application."
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
if (!config.apiKey || typeof config.apiKey !== "string") {
|
|
66
|
+
throw new FollowGateError(
|
|
67
|
+
"[FollowGate] Missing or invalid apiKey",
|
|
68
|
+
"INVALID_API_KEY",
|
|
69
|
+
"Get your API Key from https://followgate.app/dashboard. Make sure NEXT_PUBLIC_FOLLOWGATE_API_KEY is set in your environment."
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
if (config.apiKey.trim() === "" || config.apiKey === "undefined") {
|
|
73
|
+
throw new FollowGateError(
|
|
74
|
+
"[FollowGate] apiKey is empty or undefined",
|
|
75
|
+
"EMPTY_API_KEY",
|
|
76
|
+
"Your apiKey appears to be empty. This often happens when environment variables are not properly configured at BUILD TIME (not runtime). Set NEXT_PUBLIC_FOLLOWGATE_API_KEY and REBUILD your application."
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
if (!isValidApiKeyFormat(config.apiKey)) {
|
|
80
|
+
throw new FollowGateError(
|
|
81
|
+
`[FollowGate] Invalid API key format: "${config.apiKey.substring(0, 10)}..."`,
|
|
82
|
+
"INVALID_API_KEY_FORMAT",
|
|
83
|
+
'API keys should start with "fg_live_" (production) or "fg_test_" (development). Get a valid key from https://followgate.app/dashboard'
|
|
84
|
+
);
|
|
85
|
+
}
|
|
37
86
|
this.config = {
|
|
38
87
|
...config,
|
|
39
88
|
apiUrl: config.apiUrl || DEFAULT_API_URL
|
|
@@ -42,6 +91,10 @@ var FollowGateClient = class {
|
|
|
42
91
|
this.restoreSession();
|
|
43
92
|
if (config.debug) {
|
|
44
93
|
console.log("[FollowGate] Initialized with appId:", config.appId);
|
|
94
|
+
console.log(
|
|
95
|
+
"[FollowGate] API Key:",
|
|
96
|
+
config.apiKey.substring(0, 12) + "..."
|
|
97
|
+
);
|
|
45
98
|
if (this.currentUser) {
|
|
46
99
|
console.log("[FollowGate] Restored user:", this.currentUser.username);
|
|
47
100
|
}
|
|
@@ -91,14 +144,49 @@ var FollowGateClient = class {
|
|
|
91
144
|
logout() {
|
|
92
145
|
this.currentUser = null;
|
|
93
146
|
this.authToken = null;
|
|
147
|
+
this.pendingUsername = null;
|
|
94
148
|
if (typeof localStorage !== "undefined") {
|
|
95
149
|
localStorage.removeItem("followgate_token");
|
|
96
150
|
localStorage.removeItem("followgate_user");
|
|
151
|
+
localStorage.removeItem("followgate_pending_username");
|
|
97
152
|
}
|
|
98
153
|
if (this.config?.debug) {
|
|
99
154
|
console.log("[FollowGate] User logged out");
|
|
100
155
|
}
|
|
101
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if username input is needed (Twitter Free Tier limitation)
|
|
159
|
+
*/
|
|
160
|
+
needsUsernameInput() {
|
|
161
|
+
return this.pendingUsername !== null;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Set username manually (when needsUsernameInput() returns true)
|
|
165
|
+
*/
|
|
166
|
+
setUsername(username) {
|
|
167
|
+
if (!this.pendingUsername) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
"[FollowGate] No pending username state. User is either not authenticated or username is already set."
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
const normalizedUsername = username.startsWith("@") ? username.slice(1) : username;
|
|
173
|
+
this.currentUser = {
|
|
174
|
+
userId: "user_input",
|
|
175
|
+
username: normalizedUsername,
|
|
176
|
+
platform: "twitter"
|
|
177
|
+
};
|
|
178
|
+
this.authToken = this.pendingUsername.token;
|
|
179
|
+
if (typeof localStorage !== "undefined") {
|
|
180
|
+
localStorage.setItem("followgate_token", this.authToken);
|
|
181
|
+
localStorage.setItem("followgate_user", JSON.stringify(this.currentUser));
|
|
182
|
+
localStorage.removeItem("followgate_pending_username");
|
|
183
|
+
}
|
|
184
|
+
this.pendingUsername = null;
|
|
185
|
+
this.emit("authenticated", this.currentUser);
|
|
186
|
+
if (this.config?.debug) {
|
|
187
|
+
console.log("[FollowGate] Username set manually:", normalizedUsername);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
102
190
|
/**
|
|
103
191
|
* Handle auth callback from URL params
|
|
104
192
|
*/
|
|
@@ -107,7 +195,26 @@ var FollowGateClient = class {
|
|
|
107
195
|
const params = new URLSearchParams(window.location.search);
|
|
108
196
|
const token = params.get("followgate_token");
|
|
109
197
|
const username = params.get("followgate_user");
|
|
110
|
-
|
|
198
|
+
const needsUsername = params.get("followgate_needs_username") === "true";
|
|
199
|
+
if (token && needsUsername) {
|
|
200
|
+
this.pendingUsername = {
|
|
201
|
+
needsUsername: true,
|
|
202
|
+
token
|
|
203
|
+
};
|
|
204
|
+
if (typeof localStorage !== "undefined") {
|
|
205
|
+
localStorage.setItem(
|
|
206
|
+
"followgate_pending_username",
|
|
207
|
+
JSON.stringify(this.pendingUsername)
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
const url = new URL(window.location.href);
|
|
211
|
+
url.searchParams.delete("followgate_token");
|
|
212
|
+
url.searchParams.delete("followgate_needs_username");
|
|
213
|
+
window.history.replaceState({}, "", url.toString());
|
|
214
|
+
if (this.config?.debug) {
|
|
215
|
+
console.log("[FollowGate] OAuth successful, username input needed");
|
|
216
|
+
}
|
|
217
|
+
} else if (token && username) {
|
|
111
218
|
this.authToken = token;
|
|
112
219
|
this.currentUser = {
|
|
113
220
|
userId: "",
|
|
@@ -137,6 +244,18 @@ var FollowGateClient = class {
|
|
|
137
244
|
*/
|
|
138
245
|
restoreSession() {
|
|
139
246
|
if (typeof localStorage === "undefined") return;
|
|
247
|
+
const pendingJson = localStorage.getItem("followgate_pending_username");
|
|
248
|
+
if (pendingJson) {
|
|
249
|
+
try {
|
|
250
|
+
this.pendingUsername = JSON.parse(pendingJson);
|
|
251
|
+
if (this.config?.debug) {
|
|
252
|
+
console.log("[FollowGate] Restored pending username state");
|
|
253
|
+
}
|
|
254
|
+
return;
|
|
255
|
+
} catch {
|
|
256
|
+
localStorage.removeItem("followgate_pending_username");
|
|
257
|
+
}
|
|
258
|
+
}
|
|
140
259
|
const token = localStorage.getItem("followgate_token");
|
|
141
260
|
const userJson = localStorage.getItem("followgate_user");
|
|
142
261
|
if (token && userJson) {
|
|
@@ -313,5 +432,6 @@ var FollowGate = new FollowGateClient();
|
|
|
313
432
|
// Annotate the CommonJS export names for ESM import in node:
|
|
314
433
|
0 && (module.exports = {
|
|
315
434
|
FollowGate,
|
|
316
|
-
FollowGateClient
|
|
435
|
+
FollowGateClient,
|
|
436
|
+
FollowGateError
|
|
317
437
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,62 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
var DEFAULT_API_URL = "https://api.followgate.app";
|
|
3
|
+
var FollowGateError = class extends Error {
|
|
4
|
+
constructor(message, code, hint) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.hint = hint;
|
|
8
|
+
this.name = "FollowGateError";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
function isValidApiKeyFormat(apiKey) {
|
|
12
|
+
return /^fg_(live|test)_[a-zA-Z0-9_-]+$/.test(apiKey);
|
|
13
|
+
}
|
|
3
14
|
var FollowGateClient = class {
|
|
4
15
|
config = null;
|
|
5
16
|
listeners = /* @__PURE__ */ new Map();
|
|
6
17
|
currentUser = null;
|
|
7
18
|
authToken = null;
|
|
19
|
+
pendingUsername = null;
|
|
8
20
|
/**
|
|
9
21
|
* Initialize the SDK
|
|
22
|
+
* @throws {FollowGateError} If configuration is invalid
|
|
10
23
|
*/
|
|
11
24
|
init(config) {
|
|
25
|
+
if (!config.appId || typeof config.appId !== "string") {
|
|
26
|
+
throw new FollowGateError(
|
|
27
|
+
"[FollowGate] Missing or invalid appId",
|
|
28
|
+
"INVALID_APP_ID",
|
|
29
|
+
"Get your App ID from https://followgate.app/dashboard. Make sure NEXT_PUBLIC_FOLLOWGATE_APP_ID is set in your environment."
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
if (config.appId.trim() === "" || config.appId === "undefined") {
|
|
33
|
+
throw new FollowGateError(
|
|
34
|
+
"[FollowGate] appId is empty or undefined",
|
|
35
|
+
"EMPTY_APP_ID",
|
|
36
|
+
"Your appId appears to be empty. This often happens when environment variables are not properly configured. Check that NEXT_PUBLIC_FOLLOWGATE_APP_ID is set and rebuild your application."
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
if (!config.apiKey || typeof config.apiKey !== "string") {
|
|
40
|
+
throw new FollowGateError(
|
|
41
|
+
"[FollowGate] Missing or invalid apiKey",
|
|
42
|
+
"INVALID_API_KEY",
|
|
43
|
+
"Get your API Key from https://followgate.app/dashboard. Make sure NEXT_PUBLIC_FOLLOWGATE_API_KEY is set in your environment."
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (config.apiKey.trim() === "" || config.apiKey === "undefined") {
|
|
47
|
+
throw new FollowGateError(
|
|
48
|
+
"[FollowGate] apiKey is empty or undefined",
|
|
49
|
+
"EMPTY_API_KEY",
|
|
50
|
+
"Your apiKey appears to be empty. This often happens when environment variables are not properly configured at BUILD TIME (not runtime). Set NEXT_PUBLIC_FOLLOWGATE_API_KEY and REBUILD your application."
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
if (!isValidApiKeyFormat(config.apiKey)) {
|
|
54
|
+
throw new FollowGateError(
|
|
55
|
+
`[FollowGate] Invalid API key format: "${config.apiKey.substring(0, 10)}..."`,
|
|
56
|
+
"INVALID_API_KEY_FORMAT",
|
|
57
|
+
'API keys should start with "fg_live_" (production) or "fg_test_" (development). Get a valid key from https://followgate.app/dashboard'
|
|
58
|
+
);
|
|
59
|
+
}
|
|
12
60
|
this.config = {
|
|
13
61
|
...config,
|
|
14
62
|
apiUrl: config.apiUrl || DEFAULT_API_URL
|
|
@@ -17,6 +65,10 @@ var FollowGateClient = class {
|
|
|
17
65
|
this.restoreSession();
|
|
18
66
|
if (config.debug) {
|
|
19
67
|
console.log("[FollowGate] Initialized with appId:", config.appId);
|
|
68
|
+
console.log(
|
|
69
|
+
"[FollowGate] API Key:",
|
|
70
|
+
config.apiKey.substring(0, 12) + "..."
|
|
71
|
+
);
|
|
20
72
|
if (this.currentUser) {
|
|
21
73
|
console.log("[FollowGate] Restored user:", this.currentUser.username);
|
|
22
74
|
}
|
|
@@ -66,14 +118,49 @@ var FollowGateClient = class {
|
|
|
66
118
|
logout() {
|
|
67
119
|
this.currentUser = null;
|
|
68
120
|
this.authToken = null;
|
|
121
|
+
this.pendingUsername = null;
|
|
69
122
|
if (typeof localStorage !== "undefined") {
|
|
70
123
|
localStorage.removeItem("followgate_token");
|
|
71
124
|
localStorage.removeItem("followgate_user");
|
|
125
|
+
localStorage.removeItem("followgate_pending_username");
|
|
72
126
|
}
|
|
73
127
|
if (this.config?.debug) {
|
|
74
128
|
console.log("[FollowGate] User logged out");
|
|
75
129
|
}
|
|
76
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Check if username input is needed (Twitter Free Tier limitation)
|
|
133
|
+
*/
|
|
134
|
+
needsUsernameInput() {
|
|
135
|
+
return this.pendingUsername !== null;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Set username manually (when needsUsernameInput() returns true)
|
|
139
|
+
*/
|
|
140
|
+
setUsername(username) {
|
|
141
|
+
if (!this.pendingUsername) {
|
|
142
|
+
throw new Error(
|
|
143
|
+
"[FollowGate] No pending username state. User is either not authenticated or username is already set."
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
const normalizedUsername = username.startsWith("@") ? username.slice(1) : username;
|
|
147
|
+
this.currentUser = {
|
|
148
|
+
userId: "user_input",
|
|
149
|
+
username: normalizedUsername,
|
|
150
|
+
platform: "twitter"
|
|
151
|
+
};
|
|
152
|
+
this.authToken = this.pendingUsername.token;
|
|
153
|
+
if (typeof localStorage !== "undefined") {
|
|
154
|
+
localStorage.setItem("followgate_token", this.authToken);
|
|
155
|
+
localStorage.setItem("followgate_user", JSON.stringify(this.currentUser));
|
|
156
|
+
localStorage.removeItem("followgate_pending_username");
|
|
157
|
+
}
|
|
158
|
+
this.pendingUsername = null;
|
|
159
|
+
this.emit("authenticated", this.currentUser);
|
|
160
|
+
if (this.config?.debug) {
|
|
161
|
+
console.log("[FollowGate] Username set manually:", normalizedUsername);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
77
164
|
/**
|
|
78
165
|
* Handle auth callback from URL params
|
|
79
166
|
*/
|
|
@@ -82,7 +169,26 @@ var FollowGateClient = class {
|
|
|
82
169
|
const params = new URLSearchParams(window.location.search);
|
|
83
170
|
const token = params.get("followgate_token");
|
|
84
171
|
const username = params.get("followgate_user");
|
|
85
|
-
|
|
172
|
+
const needsUsername = params.get("followgate_needs_username") === "true";
|
|
173
|
+
if (token && needsUsername) {
|
|
174
|
+
this.pendingUsername = {
|
|
175
|
+
needsUsername: true,
|
|
176
|
+
token
|
|
177
|
+
};
|
|
178
|
+
if (typeof localStorage !== "undefined") {
|
|
179
|
+
localStorage.setItem(
|
|
180
|
+
"followgate_pending_username",
|
|
181
|
+
JSON.stringify(this.pendingUsername)
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
const url = new URL(window.location.href);
|
|
185
|
+
url.searchParams.delete("followgate_token");
|
|
186
|
+
url.searchParams.delete("followgate_needs_username");
|
|
187
|
+
window.history.replaceState({}, "", url.toString());
|
|
188
|
+
if (this.config?.debug) {
|
|
189
|
+
console.log("[FollowGate] OAuth successful, username input needed");
|
|
190
|
+
}
|
|
191
|
+
} else if (token && username) {
|
|
86
192
|
this.authToken = token;
|
|
87
193
|
this.currentUser = {
|
|
88
194
|
userId: "",
|
|
@@ -112,6 +218,18 @@ var FollowGateClient = class {
|
|
|
112
218
|
*/
|
|
113
219
|
restoreSession() {
|
|
114
220
|
if (typeof localStorage === "undefined") return;
|
|
221
|
+
const pendingJson = localStorage.getItem("followgate_pending_username");
|
|
222
|
+
if (pendingJson) {
|
|
223
|
+
try {
|
|
224
|
+
this.pendingUsername = JSON.parse(pendingJson);
|
|
225
|
+
if (this.config?.debug) {
|
|
226
|
+
console.log("[FollowGate] Restored pending username state");
|
|
227
|
+
}
|
|
228
|
+
return;
|
|
229
|
+
} catch {
|
|
230
|
+
localStorage.removeItem("followgate_pending_username");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
115
233
|
const token = localStorage.getItem("followgate_token");
|
|
116
234
|
const userJson = localStorage.getItem("followgate_user");
|
|
117
235
|
if (token && userJson) {
|
|
@@ -287,5 +405,6 @@ var FollowGateClient = class {
|
|
|
287
405
|
var FollowGate = new FollowGateClient();
|
|
288
406
|
export {
|
|
289
407
|
FollowGate,
|
|
290
|
-
FollowGateClient
|
|
408
|
+
FollowGateClient,
|
|
409
|
+
FollowGateError
|
|
291
410
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@followgate/js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "FollowGate SDK - Grow your audience with every download. Require social actions (follow, repost) before users can access your app.",
|
|
5
5
|
"author": "FollowGate <hello@followgate.app>",
|
|
6
6
|
"homepage": "https://followgate.app",
|