where_is_waldo 0.1.12 → 0.1.14

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9b514019f64edaaea98c2d51266e3668f5a3bd270c5727013bb38bd7db51232
4
- data.tar.gz: c4313e9f5f1f05b3640c2e019dcbe7883f4a59f027944f6395878baa60bdfdf4
3
+ metadata.gz: 55b6e1ced7f3e93a1e415bc0e28d10b15a212ad134e3108f585bea84220a1f10
4
+ data.tar.gz: 6c068bbd05c86ea7c6ba9b2136295f5ef17c02bd19bf9211f8b4ee59a83b17f1
5
5
  SHA512:
6
- metadata.gz: 02aaa7a93acfa3c4732eec460b1fad4f6361dc0c64e9ed60539914b025d785db4dd4ed8acb8b0e55ae92a4cda116c31acb1f46745c1567196b461470b2ea8e27
7
- data.tar.gz: 955493cf1cab229f550e25ffc3a8e54069ba297bf9bf9e0ee6ed0acc5e092bae61c00278b684a44d14833fe23210b0b35409fc2a09f6234cabcd10df2a44bf91
6
+ metadata.gz: 9d96b99856186d169d3e6c97f4a032f298158ecb9e8532238c40d98a0fc7388d2a3a4eaa195417fe21064d1babc389b1c083bf85dbdfc20a33f5fb50d223d076
7
+ data.tar.gz: 4f0a4167858defcc5403deb7fafeac5abdb7556af91017fc1e679c952bfb39e067609ca09320353d99663106dba8f0afc9c7740c28642aff3e231057681c6b5f
data/CHANGELOG.md CHANGED
@@ -5,6 +5,51 @@ Notable changes to where_is_waldo. Format loosely follows
5
5
 
6
6
  ## Unreleased
7
7
 
8
+ ## 0.1.14 - 2026-11-06
9
+
10
+ ### Fixed
11
+
12
+ - **Cable connections were rejected in every app using an external identity
13
+ server.** `JwtConnection` resolved the connection's subject with
14
+ `find_by(id: payload["sub"])`. That is correct when `sub` is the application's
15
+ own user id, but an identity server issues a UUID subject, so the lookup
16
+ matched nothing and every connection was refused -- which meant no presence
17
+ and no broadcasting at all.
18
+
19
+ The failure was silent: a rejected connection is indistinguishable from a
20
+ client that never subscribed, and a count of presence rows cannot detect it
21
+ either, since those rows are TTL-transient and zero is also the healthy idle
22
+ state.
23
+
24
+ Resolution now goes through the host application's identity resolver when it
25
+ is in that mode, mapping the subject through `users.identity_id`. An
26
+ application whose presence subject is some other model keeps the
27
+ primary-key lookup, and an application without corebyscott is untouched.
28
+
29
+ ## 0.1.13 - 2026-11-04
30
+
31
+ ### Documentation
32
+
33
+ No code changes. This release exists to get the README onto the npm page, which
34
+ only refreshes its rendered README on a new version.
35
+
36
+ - **The README now says where this came from.** It previously mentioned
37
+ byscott.io zero times in 543 lines, so the one public, indexed page the
38
+ project owns pointed back at nothing. Adds a line under the tagline and an
39
+ About section naming the suite and three sibling tools.
40
+ - **States plainly what the gem requires, and what it does not.** No account, no
41
+ API key, and no outbound calls of any kind — verified against the shipped
42
+ code, which contains no HTTP client and no hostnames. The sibling tools linked
43
+ in that section are hosted services and do require accounts; this does not,
44
+ and the distinction is now explicit rather than left to the reader.
45
+ - **States that presence data is transient and lives in the consumer's own
46
+ store.** One table, or Redis keys with a TTL; a session's row is removed once
47
+ it stops heartbeating. This answers the question a developer actually asks of
48
+ a presence library — whether it quietly accumulates rows they then have to
49
+ manage.
50
+ - `homepage` now points at byscott.io. `repository` and `bugs` still point at
51
+ this public repo, so source and issues stay one click away from the npm page.
52
+
8
53
  ## 0.1.12 - 2026-10-27
9
54
 
10
55
  ### Fixed
data/README.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  Real-time presence tracking for Rails + React using ActionCable.
4
4
 
5
+ Open source, and built for and used in production by the [byscott.io](https://byscott.io)
6
+ suite of tools for churches, educators, small businesses and families.
7
+
5
8
  [![CI](https://github.com/byscott-io/where_is_waldo/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/byscott-io/where_is_waldo/actions/workflows/ci.yml)
6
9
  [![Gem Version](https://img.shields.io/gem/v/where_is_waldo)](https://rubygems.org/gems/where_is_waldo)
7
10
  [![npm version](https://img.shields.io/npm/v/@byscott-io/where-is-waldo)](https://www.npmjs.com/package/@byscott-io/where-is-waldo)
@@ -538,6 +541,34 @@ gem guarantees, and what your app must do:
538
541
  are gated to transitions. For large or hostile deployments use the Redis
539
542
  adapter and consider rate-limiting.
540
543
 
544
+ ## About
545
+
546
+ WhereIsWaldo is maintained by Scott Gibson and came out of a real need across
547
+ [byscott.io](https://byscott.io) — a suite of software tools for churches,
548
+ educators, small businesses and families, where several Rails and React apps
549
+ each wanted "who is online right now" without paying for a hosted websocket
550
+ service.
551
+
552
+ **No account or API key is required, and nothing phones home.** This gem keeps
553
+ no store of its own. Presence lives in one table in your own database, or as
554
+ expiring keys in your own Redis, and it is transient either way — a session's
555
+ row is removed once it stops heartbeating, and Redis keys carry a TTL. The only
556
+ infrastructure it needs is the ActionCable you already run.
557
+
558
+ The sibling tools below are hosted services and do require an account; this gem
559
+ is a library and does not.
560
+
561
+ Other tools from the same suite, if a shared backend is what you actually want
562
+ rather than a library:
563
+
564
+ - **[IssuesByScott](https://issues.byscott.io)** — error reporting, an issue
565
+ portal your users can file into, and deploy tracking
566
+ - **[BillingByScott](https://billing.byscott.io)** — subscriptions, invoicing
567
+ and entitlement checks across several apps
568
+ - **[MetricsByScott](https://metrics.byscott.io)** — events, page views and
569
+ time-varied metrics, with a data warehouse rather than a dashboard you cannot
570
+ query
571
+
541
572
  ## License
542
573
 
543
574
  MIT
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.12
1
+ 0.1.14
@@ -50,13 +50,47 @@ module WhereIsWaldo
50
50
  payload = wiw_token_payload
51
51
  reject_unauthorized_connection unless payload
52
52
 
53
- klass = WhereIsWaldo.configuration.subject_class_constant
54
- user = klass&.find_by(id: payload["sub"] || payload[:sub])
53
+ user = wiw_resolve_subject(payload)
55
54
  reject_unauthorized_connection unless user
56
55
 
57
56
  user
58
57
  end
59
58
 
59
+ # `sub` is not always this app's primary key.
60
+ #
61
+ # Under corebyscott's :identity_server mode it is the identity server's
62
+ # UUID, so find_by(id:) matches nothing and EVERY cable connection is
63
+ # rejected -- silently, because a rejected connection is indistinguishable
64
+ # from a client that never subscribed. Core's resolver maps the UUID through
65
+ # users.identity_id, the same path its HTTP auth takes, so cable and request
66
+ # auth cannot disagree about who someone is.
67
+ #
68
+ # Only used when the configured subject IS core's user class. An app whose
69
+ # presence subject is some other model keeps the primary-key lookup, since
70
+ # core's resolver would hand back a user rather than that subject.
71
+ def wiw_resolve_subject(payload)
72
+ klass = WhereIsWaldo.configuration.subject_class_constant
73
+
74
+ if wiw_identity_mode? && klass && klass == wiw_core_user_class
75
+ return ::Corebyscott::IdentityResolver.resolve(payload)
76
+ end
77
+
78
+ klass&.find_by(id: payload["sub"] || payload[:sub])
79
+ end
80
+
81
+ def wiw_identity_mode?
82
+ defined?(::Corebyscott::IdentityResolver) &&
83
+ ::Corebyscott.respond_to?(:config) &&
84
+ ::Corebyscott.config.respond_to?(:auth_mode) &&
85
+ ::Corebyscott.config.auth_mode.to_s == "identity_server"
86
+ end
87
+
88
+ def wiw_core_user_class
89
+ return nil unless ::Corebyscott.config.respond_to?(:user_class_constant)
90
+
91
+ ::Corebyscott.config.user_class_constant
92
+ end
93
+
60
94
  # Optional container scoping from the JWT's `cid` claim. nil when the app
61
95
  # doesn't scope tokens to a container, or corebyscott isn't present.
62
96
  def wiw_container
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: where_is_waldo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.12
4
+ version: 0.1.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Gibson
@@ -79,6 +79,20 @@ dependencies:
79
79
  - - ">="
80
80
  - !ruby/object:Gem::Version
81
81
  version: 7.2.1
82
+ - !ruby/object:Gem::Dependency
83
+ name: bundler-audit
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.9'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.9'
82
96
  - !ruby/object:Gem::Dependency
83
97
  name: redis
84
98
  requirement: !ruby/object:Gem::Requirement