@0xchain/token 1.1.0-beta.61 → 1.1.0-beta.62

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,12 @@
1
+ /**
2
+ * 计算写 cookie 时的 secure 属性。
3
+ *
4
+ * 关键点:客户端(浏览器)以当前页面协议为准——https 页面就必须写 secure cookie,
5
+ * 否则会与服务端写入的 secure 同名 cookie 冲突,导航/刷新后客户端读不到。
6
+ * 这能让本地通过 https 代理调试时与线上行为一致。
7
+ *
8
+ * 服务端(无 window)无法感知页面协议,沿用 NODE_ENV==='production' 判断,
9
+ * 与既有线上行为保持一致。
10
+ */
11
+ export declare function resolveCookieSecure(): boolean;
12
+ //# sourceMappingURL=cookieSecure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookieSecure.d.ts","sourceRoot":"","sources":["../src/cookieSecure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAU7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAC;AA+C9D;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GAAI,KAAK,qBAAqB,EAAE,WAAW,YAAY,GAAG,IAAI,KAAG,YAAY,GAAG,IAyCpG,CAAA;AAED,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,WAEpC,CAAA;AAED,sCAAsC;AACtC,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,OAAO,GACX,qBAAqB,GAAG,IAAI,CAc9B;AAED,eAAO,MAAM,cAAc,YAM1B,CAAA;AAID,eAAO,MAAM,cAAc,wBA2C1B,CAAA;AACD,QAAA,MAAM,YAAY,EAAE,aAMnB,CAAA;AAED,eAAe,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAC;AA2E9D;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GAAI,KAAK,qBAAqB,EAAE,WAAW,YAAY,GAAG,IAAI,KAAG,YAAY,GAAG,IA0CpG,CAAA;AAED,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,WAEpC,CAAA;AAED,sCAAsC;AACtC,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,OAAO,GACX,qBAAqB,GAAG,IAAI,CAc9B;AAED,eAAO,MAAM,cAAc,YAM1B,CAAA;AAID,eAAO,MAAM,cAAc,wBAgD1B,CAAA;AACD,QAAA,MAAM,YAAY,EAAE,aAMnB,CAAA;AAED,eAAe,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -1,41 +1,71 @@
1
1
  import Cookies from "js-cookie";
2
+ function resolveCookieSecure() {
3
+ if (typeof window !== "undefined" && window.location) {
4
+ return window.location.protocol === "https:";
5
+ }
6
+ const authUrl = process.env.NEXT_PUBLIC_AUTH_URL || "";
7
+ const appUrl = process.env.NEXT_PUBLIC_APP_URL || "";
8
+ if (authUrl.startsWith("https://") || appUrl.startsWith("https://")) {
9
+ return true;
10
+ }
11
+ return process.env.NODE_ENV === "production";
12
+ }
2
13
  const COOKIE_DOMAIN = ".ichatgo.ai";
3
14
  const COOKIE_PATH = "/";
4
15
  const COOKIE_SAME_SITE = "lax";
5
- const COOKIE_SECURE = process.env.NODE_ENV === "production";
6
16
  const REFRESH_TOKEN_COOKIE_DAYS = 7;
7
17
  function expiresFromSeconds(seconds) {
8
18
  return new Date(Date.now() + Math.max(seconds, 0) * 1e3);
9
19
  }
20
+ function decodeJwtExpiryMs(token) {
21
+ if (!token) return void 0;
22
+ const parts = token.split(".");
23
+ if (parts.length < 2) return void 0;
24
+ const base64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
25
+ try {
26
+ const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, "=");
27
+ const raw = typeof atob === "function" ? atob(padded) : Buffer.from(padded, "base64").toString("binary");
28
+ const utf8 = decodeURIComponent(
29
+ raw.split("").map((c) => `%${c.charCodeAt(0).toString(16).padStart(2, "0")}`).join("")
30
+ );
31
+ const payload = JSON.parse(utf8);
32
+ if (typeof payload.exp === "number") {
33
+ return payload.exp * 1e3;
34
+ }
35
+ } catch {
36
+ }
37
+ return void 0;
38
+ }
10
39
  const cookieSetToken = (data) => {
11
40
  const expiresIn = data?.expires_in ?? 3600;
12
41
  const accessExpires = expiresFromSeconds(expiresIn);
42
+ const secure = resolveCookieSecure();
13
43
  Cookies.set("access_token", data?.access_token, {
14
44
  expires: accessExpires,
15
45
  domain: COOKIE_DOMAIN,
16
46
  sameSite: COOKIE_SAME_SITE,
17
- secure: COOKIE_SECURE,
47
+ secure,
18
48
  path: COOKIE_PATH
19
49
  });
20
50
  Cookies.set("refresh_token", data?.refresh_token, {
21
51
  expires: REFRESH_TOKEN_COOKIE_DAYS,
22
52
  domain: COOKIE_DOMAIN,
23
53
  sameSite: COOKIE_SAME_SITE,
24
- secure: COOKIE_SECURE,
54
+ secure,
25
55
  path: COOKIE_PATH
26
56
  });
27
57
  Cookies.set("id_token", data?.id_token, {
28
58
  expires: accessExpires,
29
59
  domain: COOKIE_DOMAIN,
30
60
  sameSite: COOKIE_SAME_SITE,
31
- secure: COOKIE_SECURE,
61
+ secure,
32
62
  path: COOKIE_PATH
33
63
  });
34
64
  Cookies.set("token_expire", (Date.now() + expiresIn * 1e3).toString(), {
35
65
  expires: accessExpires,
36
66
  domain: COOKIE_DOMAIN,
37
67
  sameSite: COOKIE_SAME_SITE,
38
- secure: COOKIE_SECURE,
68
+ secure,
39
69
  path: COOKIE_PATH
40
70
  });
41
71
  };
@@ -44,12 +74,13 @@ const setToken = (res, response) => {
44
74
  cookieSetToken(res);
45
75
  return null;
46
76
  } else {
77
+ const secure = resolveCookieSecure();
47
78
  response.cookies.set("access_token", res?.access_token, {
48
79
  httpOnly: false,
49
80
  maxAge: res?.expires_in,
50
81
  domain: COOKIE_DOMAIN,
51
82
  sameSite: COOKIE_SAME_SITE,
52
- secure: COOKIE_SECURE,
83
+ secure,
53
84
  path: COOKIE_PATH
54
85
  });
55
86
  response.cookies.set("refresh_token", res?.refresh_token, {
@@ -57,7 +88,7 @@ const setToken = (res, response) => {
57
88
  maxAge: 60 * 60 * 24 * 7,
58
89
  domain: COOKIE_DOMAIN,
59
90
  sameSite: COOKIE_SAME_SITE,
60
- secure: COOKIE_SECURE,
91
+ secure,
61
92
  path: COOKIE_PATH
62
93
  });
63
94
  response.cookies.set("id_token", res?.id_token, {
@@ -65,7 +96,7 @@ const setToken = (res, response) => {
65
96
  maxAge: res?.expires_in,
66
97
  domain: COOKIE_DOMAIN,
67
98
  sameSite: COOKIE_SAME_SITE,
68
- secure: COOKIE_SECURE,
99
+ secure,
69
100
  path: COOKIE_PATH
70
101
  });
71
102
  response.cookies.set("token_expire", (Date.now() + res?.expires_in * 1e3).toString(), {
@@ -73,7 +104,7 @@ const setToken = (res, response) => {
73
104
  maxAge: res?.expires_in,
74
105
  domain: COOKIE_DOMAIN,
75
106
  sameSite: COOKIE_SAME_SITE,
76
- secure: COOKIE_SECURE,
107
+ secure,
77
108
  path: COOKIE_PATH
78
109
  });
79
110
  }
@@ -130,10 +161,14 @@ const isTokenExpired = async () => {
130
161
  }
131
162
  const nearExpiry = (expireAt) => expireAt - Date.now() < 5 * 60 * 1e3;
132
163
  if (accessToken) {
164
+ const jwtExpiry = decodeJwtExpiryMs(accessToken);
165
+ if (jwtExpiry) {
166
+ return nearExpiry(jwtExpiry);
167
+ }
133
168
  if (t && !Number.isNaN(t)) {
134
169
  return nearExpiry(t);
135
170
  }
136
- return false;
171
+ return Boolean(refreshToken);
137
172
  }
138
173
  if (refreshToken) {
139
174
  return true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xchain/token",
3
- "version": "1.1.0-beta.61",
3
+ "version": "1.1.0-beta.62",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",