facebetter 2.0.0 → 2.0.1

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/README.md CHANGED
@@ -46,7 +46,13 @@ For direct browser usage.
46
46
  <script src="https://cdn.jsdelivr.net/npm/facebetter/dist/facebetter.js"></script>
47
47
  ```
48
48
 
49
- The UMD build loads `facebetter-core` from the **same directory** as `facebetter.js`. A single jsDelivr URL for `facebetter` is not enough: also host `facebetter-core.js` next to it (from the `facebetter-core` package `dist/`), or use npm + a bundler.
49
+ The UMD build loads `facebetter-core` from the **same directory** as `facebetter.js`. Host these next to `facebetter.js`:
50
+
51
+ - `facebetter-core.js`
52
+ - `facebetter-core.wasm`
53
+ - `resource.fbd`
54
+
55
+ A single jsDelivr URL for `facebetter` is not enough. npm + a bundler is simpler.
50
56
 
51
57
  ---
52
58
 
@@ -54,34 +60,22 @@ The UMD build loads `facebetter-core` from the **same directory** as `facebetter
54
60
 
55
61
  ### 1. Initialize the Engine
56
62
 
57
- Web 必须联网校验。`EngineConfig` **没有** `appId` / `appKey`:生产环境由你的服务器保管密钥并代理鉴权。本地调试、或你确认环境不会泄露密钥时,可以在调用处直连 Cloudflare。
63
+ Web 必须联网校验。`EngineConfig` **没有** `appId` / `appKey`:由你的服务器换 token,再传入 `licenseToken`。
58
64
 
59
65
  ```javascript
60
66
  import {
61
67
  BeautyEffectEngine,
62
68
  EngineConfig,
63
- createDirectAuthFetcher,
64
69
  } from 'facebetter';
65
70
 
66
- // 方式 A:你的后端已经拿到 v2 token(compact JWS 或 {success, token})
67
- const config = new EngineConfig({
68
- licenseToken: await fetch('/api/facebetter/auth', { method: 'POST' }).then((r) => r.text()),
69
- });
70
-
71
- // 方式 B:把 WASM 的 nonce challenge 转发到你的后端(生产推荐)
72
- const config = new EngineConfig({
73
- authProxyUrl: '/api/facebetter/auth',
74
- });
75
-
76
- // 方式 C:本地调试 / 无自己的服务器时,调用处直连 Cloudflare(密钥会出现在前端,不要用于生产)
77
- const config = new EngineConfig({
78
- fetchAuthResponse: createDirectAuthFetcher({
79
- appId: 'your-app-id',
80
- appKey: 'your-app-key',
81
- }),
71
+ const licenseToken = await fetch('/api/facebetter/auth', {
72
+ method: 'POST',
73
+ }).then((r) => {
74
+ if (!r.ok) throw new Error(`auth failed: ${r.status}`);
75
+ return r.text();
82
76
  });
83
77
 
84
- const engine = new BeautyEffectEngine(config);
78
+ const engine = new BeautyEffectEngine(new EngineConfig({ licenseToken }));
85
79
 
86
80
  try {
87
81
  await engine.init();
@@ -91,19 +85,30 @@ try {
91
85
  }
92
86
  ```
93
87
 
94
- 客户服务器代理示例(Node):
88
+ #### 服务端代理(Node
89
+
90
+ 密钥只放在服务器环境变量。签名串为 `v2|{app_id}|{timestamp}|{nonce}|web`,HMAC-SHA256(hex)后请求上游,把**响应原文**返回给前端:
95
91
 
96
92
  ```javascript
97
- import { createHmac } from 'node:crypto';
93
+ import { createHmac, randomBytes } from 'node:crypto';
94
+
95
+ const AUTH_URL = 'https://facebetter.pixpark.net/facebetter/v2/auth';
98
96
 
99
97
  app.post('/api/facebetter/auth', async (req, res) => {
100
- const { nonce, timestamp, platform, user_agent } = req.body;
101
98
  const appId = process.env.FB_APP_ID;
102
99
  const appKey = process.env.FB_APP_KEY;
100
+ if (!appId || !appKey) {
101
+ res.status(500).json({ error: 'FB_APP_ID / FB_APP_KEY not configured' });
102
+ return;
103
+ }
104
+
105
+ const nonce = randomBytes(16).toString('hex');
106
+ const timestamp = Math.floor(Date.now() / 1000);
107
+ const platform = 'web';
103
108
  const payload = `v2|${appId}|${timestamp}|${nonce}|${platform}`;
104
109
  const hmac = createHmac('sha256', appKey).update(payload).digest('hex');
105
110
 
106
- const upstream = await fetch('https://facebetter.pixpark.net/facebetter/v2/auth', {
111
+ const upstream = await fetch(AUTH_URL, {
107
112
  method: 'POST',
108
113
  headers: { 'Content-Type': 'application/json' },
109
114
  body: JSON.stringify({
@@ -112,13 +117,15 @@ app.post('/api/facebetter/auth', async (req, res) => {
112
117
  timestamp,
113
118
  nonce,
114
119
  platform,
115
- user_agent,
120
+ user_agent: req.headers['user-agent'] || '',
116
121
  }),
117
122
  });
118
123
  res.status(upstream.status).send(await upstream.text());
119
124
  });
120
125
  ```
121
126
 
127
+ 可运行参考:[Demo `api/facebetter/auth.js`](https://github.com/pixpark/facebetter-sdk/blob/main/demo/web/react/api/facebetter/auth.js)。完整说明见 [Auth & License](https://facebetter.net/docs/intro/license)。
128
+
122
129
  iOS / Android 仍可用 `appId` + `appKey` 直连在线鉴权,或使用绑定 Bundle ID / Package Name 的离线 license。Web 不支持离线 license。
123
130
 
124
131
 
@@ -201,7 +208,7 @@ processFrame();
201
208
 
202
209
  ## ⚠️ Important Notes
203
210
 
204
- 1. **Runtime package**: `import('facebetter-core')` is resolved by your bundler from `node_modules` (installed with `facebetter`). For a `<script>` tag, place `facebetter-core.js` beside `facebetter.js`.
211
+ 1. **Runtime package**: `import('facebetter-core')` is resolved by your bundler from `node_modules` (installed with `facebetter`). The SDK then downloads `facebetter-core.wasm` and `resource.fbd` from that package. For a `<script>` tag, place `facebetter-core.js`, `facebetter-core.wasm`, and `resource.fbd` beside `facebetter.js`. Pass `onProgress` to `init()` for download progress.
205
212
  2. **Secure Context**: The SDK requires a Secure Context (HTTPS or localhost) to access modern browser features.
206
213
  3. **Performance Optimization**:
207
214
  - Always call `processImage` within a `requestAnimationFrame` loop.