@kieransimkin/dancemoves 3.1.21 → 3.1.23
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 +16 -1
- package/docs/api/surface.json +10 -0
- package/docs/api/wordpress.md +68 -22
- package/docs/wordpress-org.md +6 -0
- package/lib/build-manifest.json +5 -5
- package/lib/dancemoves.min.js +1 -1
- package/lib/index.cjs +1 -1
- package/lib/index.mjs +1 -1
- package/lib/wordpress.js +1 -1
- package/package.json +1 -1
- package/readme.txt +16 -3
package/README.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# DanceMoves
|
|
2
2
|
|
|
3
|
+
**3.1.23** secures WordPress motion-capture writes with authenticated
|
|
4
|
+
`manage_options` authorization. The private capture administration UI uses the
|
|
5
|
+
same capability. Published tokens no longer authorize uploads; cookie clients
|
|
6
|
+
send a fresh WordPress REST nonce and same-origin credentials, and administrators
|
|
7
|
+
have separate bounded upload quotas. Local recording/download stays available
|
|
8
|
+
without upload authorization. See the [capture contract](docs/api/wordpress.md#motion-capture-rest-api).
|
|
9
|
+
The real WordPress integration test reports its executed assertion count;
|
|
10
|
+
CI rejects a missing or zero-count summary as well as any failed check.
|
|
11
|
+
|
|
12
|
+
**3.1.22** fixes WordPress.org submission metadata: the Author URI points to
|
|
13
|
+
[Kieran's website](https://kieransimkin.co.uk/), separately from the plugin
|
|
14
|
+
homepage. The release checker rejects duplicate plugin/author URLs before
|
|
15
|
+
packaging. The plugin name remains **DanceMoves**.
|
|
16
|
+
|
|
3
17
|
**3.1.20** adds a shared playback transport for explicitly verified native and
|
|
4
18
|
YouTube players. Full-master players drive the existing musical effects; Shorts
|
|
5
19
|
map their offset and duration onto the master clock. See
|
|
@@ -597,7 +611,8 @@ const example = {schema:'ks-epk-motion-recording/v1', samples:[{t:0,beta:10,gamm
|
|
|
597
611
|
inspect(example);
|
|
598
612
|
// The local simulator uses /examples/wordpress/api/capture, never /wp-json/… .
|
|
599
613
|
// For actual captures, follow docs/api/wordpress.md and the private sensor harness.
|
|
600
|
-
//
|
|
614
|
+
// Uploads require administrator authorization and a fresh WordPress REST nonce.
|
|
615
|
+
// Keep real session nonces out of static examples and source control.
|
|
601
616
|
```
|
|
602
617
|
|
|
603
618
|
[Run the example](examples/wordpress/capture.html) · [Read its complete source](examples/wordpress/demos/capture.mjs).
|
package/docs/api/surface.json
CHANGED
|
@@ -7,6 +7,16 @@
|
|
|
7
7
|
"effects_version": "3.1.13",
|
|
8
8
|
"effects_reviewed_on": "2026-10-08",
|
|
9
9
|
"inventory_method": "Manual comparison with the pinned source exports and PHP declarations; symbol-presence validation is not runtime coverage.",
|
|
10
|
+
"wordpress_capture_security": {
|
|
11
|
+
"version": "3.1.23",
|
|
12
|
+
"reviewed_on": "2026-10-15",
|
|
13
|
+
"scope": "Current capture contract supersedes the historical 2.8.0 capture authorization, quota and post-type capability description; pinned baseline symbols and source hashes below remain historical evidence.",
|
|
14
|
+
"authorization": "WordPress-authenticated current_user_can('manage_options'); cookie REST nonces are checked by WordPress core",
|
|
15
|
+
"removed_constants": ["KS_EPK_MOTION_CAPTURE_TOKEN"],
|
|
16
|
+
"quota": "ks_motion_user_<authenticated user ID>, eight accepted checks per ten-minute expiry",
|
|
17
|
+
"private_capture_capability": "manage_options",
|
|
18
|
+
"reference": "wordpress.md#motion-capture-rest-api"
|
|
19
|
+
},
|
|
10
20
|
"source_blobs": {
|
|
11
21
|
"kieran-epk-device-orientation.php": "b374690a0c141aa1f870bf1084a0a0b34c25abe5",
|
|
12
22
|
"assets/dance-moves-core.js": "3d975c7a3b380f9c99a62f7deade14df4b746929",
|
package/docs/api/wordpress.md
CHANGED
|
@@ -15,7 +15,7 @@ registration, rendering or save callbacks manually.
|
|
|
15
15
|
| --- | --- |
|
|
16
16
|
| `DANCE_MOVES_VERSION` | `2.8.0` |
|
|
17
17
|
| `KS_EPK_ORIENTATION_VERSION` | Alias of `DANCE_MOVES_VERSION`. |
|
|
18
|
-
| `KS_EPK_MOTION_CAPTURE_TOKEN` |
|
|
18
|
+
| `KS_EPK_MOTION_CAPTURE_TOKEN` | Removed in 3.1.23. No fixed/published token authorizes capture writes. See the current capture security section. |
|
|
19
19
|
| `DANCE_MOVES_META_BPM` | `_dance_moves_bpm` |
|
|
20
20
|
| `DANCE_MOVES_META_LYRIC_TIMING` | `_dance_moves_lyric_timing_id` |
|
|
21
21
|
| `DANCE_MOVES_META_CUE_TIMING` | `_dance_moves_cue_timing_id` |
|
|
@@ -172,7 +172,7 @@ The full validator runs when the Page editor saves the selected attachment.
|
|
|
172
172
|
```text
|
|
173
173
|
POST <WordPress REST root>/ks-epk-motion/v1/capture
|
|
174
174
|
Content-Type: application/json
|
|
175
|
-
X-
|
|
175
|
+
X-WP-Nonce: <fresh wp_rest nonce for the signed-in administrator session>
|
|
176
176
|
```
|
|
177
177
|
|
|
178
178
|
Implemented by `ks_epk_motion_register_rest_route()` using
|
|
@@ -180,23 +180,48 @@ Implemented by `ks_epk_motion_register_rest_route()` using
|
|
|
180
180
|
`ks_epk_motion_capture_permission(WP_REST_Request $request)` and handler
|
|
181
181
|
`ks_epk_motion_store_capture(WP_REST_Request $request)`.
|
|
182
182
|
|
|
183
|
-
|
|
183
|
+
In 3.1.23, permission processing is:
|
|
184
|
+
|
|
185
|
+
1. WordPress authenticates the request before the permission callback. Cookie
|
|
186
|
+
clients send same-origin credentials and a fresh `wp_rest` nonce in
|
|
187
|
+
`X-WP-Nonce`; WordPress validates that nonce. Missing/expired cookie nonces
|
|
188
|
+
cannot establish administrator authorization. Standard WordPress Application
|
|
189
|
+
Password authentication over HTTPS may also establish the current user;
|
|
190
|
+
this plugin does not create or store those credentials.
|
|
191
|
+
2. Require `current_user_can('manage_options')`. Anonymous requests return 401;
|
|
192
|
+
authenticated callers lacking that capability return 403. The former
|
|
193
|
+
`X-KS-Motion-Token` header is ignored and its public constant is removed.
|
|
194
|
+
3. When `get_http_origin()` supplies an origin, require it to equal `home_url()`
|
|
195
|
+
after trailing-slash removal. A missing Origin is allowed only after genuine
|
|
196
|
+
WordPress authentication/authorization, for example an authorized API client.
|
|
197
|
+
4. Rate-limit by authenticated user ID, using `ks_motion_user_<id>`. Eight
|
|
198
|
+
accepted permission checks are allowed before 429. Each allowed check writes
|
|
199
|
+
a ten-minute expiry; a later-invalid payload still consumes a check. Denied
|
|
200
|
+
callers and other administrators cannot exhaust an administrator's quota.
|
|
201
|
+
|
|
202
|
+
The development lab's static HTML carries no real nonce. Populate its
|
|
203
|
+
`ksMotionCaptureConfig.restNonce` from the current administrator session, not a
|
|
204
|
+
committed value. A registered harness on an authenticated WordPress admin screen
|
|
205
|
+
can use the normal script configuration route:
|
|
184
206
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
207
|
+
```php
|
|
208
|
+
if (current_user_can('manage_options')) {
|
|
209
|
+
// Run after registering/enqueuing your own capture harness script.
|
|
210
|
+
wp_localize_script('your-capture-harness', 'ksMotionCaptureConfig', array(
|
|
211
|
+
'endpoint' => esc_url_raw(rest_url('ks-epk-motion/v1/capture')),
|
|
212
|
+
'restNonce' => wp_create_nonce('wp_rest'),
|
|
213
|
+
));
|
|
214
|
+
}
|
|
215
|
+
```
|
|
192
216
|
|
|
193
|
-
|
|
194
|
-
endpoint
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
217
|
+
The capture client sends `credentials: 'same-origin'` and rejects a different
|
|
218
|
+
endpoint origin before transmitting a nonce or recording. A missing nonce leaves
|
|
219
|
+
local recording/download available and displays an accurate upload hold. After
|
|
220
|
+
a session/nonce expires, reload the authorized configuration before retrying.
|
|
221
|
+
Sensor consent and the explicit upload button remain separate requirements.
|
|
222
|
+
See WordPress's [REST authentication](https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/)
|
|
223
|
+
and [permission callback](https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/#permissions-callback)
|
|
224
|
+
documentation. No custom authentication mechanism is added.
|
|
200
225
|
|
|
201
226
|
### Request shape
|
|
202
227
|
|
|
@@ -275,9 +300,9 @@ Success returns a normal REST response (no explicit 201 status is set):
|
|
|
275
300
|
|
|
276
301
|
| HTTP status | Error code | Meaning |
|
|
277
302
|
| --- | --- | --- |
|
|
278
|
-
| 403 | `ks_motion_forbidden` |
|
|
303
|
+
| 401 / 403 | `ks_motion_forbidden` | WordPress caller is anonymous / lacks `manage_options`. |
|
|
279
304
|
| 403 | `ks_motion_origin` | Supplied origin does not match the site. |
|
|
280
|
-
| 429 | `ks_motion_rate` |
|
|
305
|
+
| 429 | `ks_motion_rate` | This administrator's permission-check quota exhausted. |
|
|
281
306
|
| 400 | `ks_motion_schema` | Missing/wrong schema or nonarray JSON payload. |
|
|
282
307
|
| 400 | `ks_motion_samples` | Missing/nonarray samples or input count outside 1–500. |
|
|
283
308
|
| 400 | `ks_motion_invalid_samples` | At least one required sample field is invalid. |
|
|
@@ -292,9 +317,12 @@ A successful record is a `private` post of type `ks_motion_capture`, titled
|
|
|
292
317
|
`Phone motion capture <site-local date/time>`, with the cleaned JSON in
|
|
293
318
|
`post_content`. Extra metadata: `_ks_motion_passed` (`'1'`/`'0'`),
|
|
294
319
|
`_ks_motion_sample_count`, and `_ks_motion_sha256` (hash of stored encoded JSON).
|
|
295
|
-
The post
|
|
296
|
-
`
|
|
297
|
-
|
|
320
|
+
The post author is the authenticated administrator ID. The post type has a
|
|
321
|
+
Tools-menu UI, title/editor support, `public: false`, and `show_in_rest: false`.
|
|
322
|
+
In 3.1.23 its read, create, edit and delete capabilities all require
|
|
323
|
+
`manage_options`, with generic post meta-capability mapping disabled. Ordinary
|
|
324
|
+
editors/authors cannot acquire access to private sensor captures through their
|
|
325
|
+
normal post-editing capabilities. Retention remains an explicit operator duty.
|
|
298
326
|
|
|
299
327
|
There is **no plugin GET/list/delete capture REST route, retention job, automatic
|
|
300
328
|
capture upload, or cryptographic proof of native sensor provenance**. Private
|
|
@@ -323,6 +351,24 @@ available. Do not assume a root exists merely because the shared script loaded.
|
|
|
323
351
|
|
|
324
352
|
## Registered hooks and callback reference
|
|
325
353
|
|
|
354
|
+
### Project prefixes and compatibility
|
|
355
|
+
|
|
356
|
+
Production PHP declarations use `dance_moves_` / `ks_epk_` functions and
|
|
357
|
+
`DANCE_MOVES_` / `KS_EPK_` constants. Plugin-owned metadata, transients, post
|
|
358
|
+
types, REST namespaces and asset handles use the existing `dance_moves`,
|
|
359
|
+
`dance-moves`, `ks_motion`, `ks-epk-motion` or `ks-epk-device-orientation`
|
|
360
|
+
prefixes. Localized JavaScript configuration uses the named `danceMoves*` and
|
|
361
|
+
`ksEpkOrientationConfig` objects. WordPress core hook names in the table below
|
|
362
|
+
are consumed hooks; they must retain their core names.
|
|
363
|
+
|
|
364
|
+
These names remain for installed-site compatibility. In 3.1.23 the obsolete
|
|
365
|
+
public token constant is removed and the authenticated quota uses the prefixed
|
|
366
|
+
`ks_motion_user_<id>` transient. The declaration-prefix regression and capture
|
|
367
|
+
authorization/client tests run in the existing legacy test gate. Hosted CI also
|
|
368
|
+
exercises real WordPress core nonce validation, roles, REST dispatch, database
|
|
369
|
+
storage and capability mapping on a disposable site. It does not use a live
|
|
370
|
+
installation or claim physical phone acceptance.
|
|
371
|
+
|
|
326
372
|
These are WordPress hooks **consumed** by the plugin, not plugin-defined extension
|
|
327
373
|
hooks. Default priority is 10 unless shown. No `apply_filters('dance_moves_...')`
|
|
328
374
|
or `do_action('dance_moves_...')` extension contract is exposed in this baseline.
|
package/docs/wordpress-org.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# WordPress.org publication
|
|
2
2
|
|
|
3
|
+
The plugin and author URI headers must identify different pages. The author
|
|
4
|
+
header uses https://kieransimkin.co.uk/; the plugin retains its published My Songs
|
|
5
|
+
homepage. `npm run check:release` rejects duplicate URLs (including a trailing
|
|
6
|
+
slash variation), matching the directory upload validation. Keep the public
|
|
7
|
+
plugin name **DanceMoves** and its existing compatibility identifiers.
|
|
8
|
+
|
|
3
9
|
Run the official Plugin Check against the exact production ZIP with the intended directory slug. Do not scan tests as installed runtime code, ignore an entire category or treat a passing static scan as a security audit. Review all warnings and document each contextual finding. Keep the readme stable tag, main PHP version and GitHub release aligned. After directory approval, publish the same verified source through the assigned SVN repository; verify the downloaded directory ZIP independently. No directory password belongs in source.
|
|
4
10
|
|
|
5
11
|
## Potential problems
|
package/lib/build-manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "dancemoves-library-build/v1",
|
|
3
3
|
"name": "@kieransimkin/dancemoves",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.23",
|
|
5
5
|
"homepage": "https://kieransimkin.co.uk/my-songs/",
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
{
|
|
33
33
|
"path": "dancemoves.min.js",
|
|
34
34
|
"bytes": 212321,
|
|
35
|
-
"sha256": "
|
|
35
|
+
"sha256": "2d7a7ec476e32d695fd88277967009b3e10a2ef889e0ecafa59ac4eaf6e15f2a"
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
"path": "index.cjs",
|
|
39
39
|
"bytes": 361185,
|
|
40
|
-
"sha256": "
|
|
40
|
+
"sha256": "cf41f6c466acbb9f170ca37258fdf15ef7695457543e3bc29dc8b38ff38fed54"
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
"path": "index.d.ts",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
{
|
|
48
48
|
"path": "index.mjs",
|
|
49
49
|
"bytes": 360040,
|
|
50
|
-
"sha256": "
|
|
50
|
+
"sha256": "abd302d298b2c808d83507eed49235602a4c7530dd3771083e4dfe16d84997ba"
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
53
|
"path": "react.cjs",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
{
|
|
108
108
|
"path": "wordpress.js",
|
|
109
109
|
"bytes": 211126,
|
|
110
|
-
"sha256": "
|
|
110
|
+
"sha256": "dfb55567a063115518847ab70485924fed0bd4d64e790f9d659be97e1f0f08f5"
|
|
111
111
|
}
|
|
112
112
|
]
|
|
113
113
|
}
|