standard_id-google 0.3.0 → 0.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +161 -0
- data/{LICENSE.txt → LICENSE} +1 -1
- data/README.md +112 -4
- data/lib/generators/standard_id/google/install/install_generator.rb +77 -0
- data/lib/generators/standard_id/google/install/templates/initializer.rb.erb +31 -0
- data/lib/standard_id/google/providers/google.rb +128 -105
- data/lib/standard_id/google/version.rb +1 -1
- data/lib/standard_id/google.rb +6 -1
- metadata +7 -24
- data/.claude/hooks/enforce-worktree.sh +0 -84
- data/.claude/settings.json +0 -24
- data/.claude/skills/publish-gem/SKILL.md +0 -211
- data/.claude/skills/start/SKILL.md +0 -185
- data/.claude/skills/worktree/SKILL.md +0 -143
- data/.editorconfig +0 -15
- data/.rspec +0 -3
- data/.rubocop.yml +0 -8
- data/.ruby-version +0 -1
- data/AGENTS.md +0 -71
- data/CLAUDE.md +0 -26
- data/CODE_OF_CONDUCT.md +0 -132
- data/lib/standard_id/google/railtie.rb +0 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f22ca920dcb306788b3588bf99ac704b9ce5e40cbb9c423a551e064ab6b236a9
|
|
4
|
+
data.tar.gz: f8492f9d9af4dbf74af4062524e0c217e20e50ec3420605a76d363154cacc2f5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9b8d7e1bb7bdfa6302108521bf603a8727a61cd2a6893dcfd8ed230f9999697aa627f912b870528833f9b4781cbe1dbd868f761bdec013ae6cb7ff3a2f8af004
|
|
7
|
+
data.tar.gz: 53b44b47d85d30da76de8dbdf1f55953c3b3f4a31fb3808c769b8a72175210d8ac0fdbbbbbe0d52eb7e45817666d17edd5ce2947b1dfc16462d3f12d92226544
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,167 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.5.0] - 2026-09-24
|
|
11
|
+
|
|
12
|
+
Adopts the provider-plugin API of standard_id 0.42.
|
|
13
|
+
|
|
14
|
+
### Upgrade
|
|
15
|
+
|
|
16
|
+
- **Requires `standard_id` 0.42** (`~> 0.42`, was `>= 0.29, < 1.0`). Bump both
|
|
17
|
+
together.
|
|
18
|
+
- **Rename `GOOGLE_OAUTH_CLIENT_ID` / `GOOGLE_OAUTH_CLIENT_SECRET` to
|
|
19
|
+
`GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET`** when convenient. Initializers
|
|
20
|
+
from the 0.4.0 generator assign the old names explicitly and keep working
|
|
21
|
+
unchanged; the old names are also read as a deprecated ENV fallback (see
|
|
22
|
+
Deprecated). sidekick-web already uses the canonical names.
|
|
23
|
+
- **Expect a boot warning if the secret is missing.** With `google_client_id`
|
|
24
|
+
set and `google_client_secret` blank, standard_id now logs a warning at boot
|
|
25
|
+
(raises in production under `c.social.provider_misconfiguration = :raise`).
|
|
26
|
+
An app that deliberately accepts only native ID tokens and has no secret
|
|
27
|
+
should keep that setting at `:warn`.
|
|
28
|
+
- **Specs stubbing the tokeninfo call:** access-token verification now posts to
|
|
29
|
+
`TOKEN_INFO_ENDPOINT` (`https://oauth2.googleapis.com/tokeninfo`), not
|
|
30
|
+
`https://www.googleapis.com/oauth2/v3/tokeninfo`. ID-token stubs against
|
|
31
|
+
`TOKEN_INFO_ENDPOINT` (sidekick-web's `social_callback_spec.rb`) are
|
|
32
|
+
unaffected.
|
|
33
|
+
- **Anyone rescuing on message text:** several messages changed (see Changed).
|
|
34
|
+
`StandardId::Google::Railtie` no longer exists.
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
- **Required config field.** `google_client_secret` is declared
|
|
39
|
+
`required: true`, so `StandardId::Providers::Google.configuration_errors` and
|
|
40
|
+
standard_id's boot check report it whenever `google_client_id` (the enabling
|
|
41
|
+
field) is set.
|
|
42
|
+
- **ENV fallback** through standard_id 0.42: `GOOGLE_CLIENT_ID`,
|
|
43
|
+
`GOOGLE_CLIENT_SECRET`.
|
|
44
|
+
- Specs for `resolve_params`, `skip_csrf?`, `supports_mobile_callback?` /
|
|
45
|
+
`flow_for`, nonce handling (web code exchange included) and configuration,
|
|
46
|
+
plus standard_id's `"a registered StandardId provider"` shared example.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- **One tokeninfo endpoint.** ID tokens and access tokens are both verified
|
|
51
|
+
against `TOKEN_INFO_ENDPOINT`, `https://oauth2.googleapis.com/tokeninfo` —
|
|
52
|
+
the endpoint Google documents for both. Access tokens previously went to a
|
|
53
|
+
hard-coded `https://www.googleapis.com/oauth2/v3/tokeninfo`.
|
|
54
|
+
- **The id_token and access_token flows no longer need `google_client_secret`.**
|
|
55
|
+
Both verify through tokeninfo and compare the audience to the client ID; only
|
|
56
|
+
the web code exchange sends the secret. Previously every flow raised
|
|
57
|
+
`Google provider is not configured` without it.
|
|
58
|
+
- **Nonce mismatches no longer leak the nonce.** The message was
|
|
59
|
+
`ID token nonce mismatch. Expected: <nonce>, got: <nonce>`; it is now
|
|
60
|
+
standard_id's `ID token nonce mismatch`, and the comparison is constant-time.
|
|
61
|
+
The nonce is now checked after the audience and issuer.
|
|
62
|
+
- **Audience and issuer errors no longer echo values** — the old messages
|
|
63
|
+
included this app's client ID and the presented `aud`/`iss`. A token with no
|
|
64
|
+
`aud` at all is rejected explicitly.
|
|
65
|
+
- **The duplicated helpers are gone** in favour of standard_id's
|
|
66
|
+
`Providers::Base`: `rescue_to_oauth_error`, `verify_nonce!`,
|
|
67
|
+
`build_authorization_url`, `extract_tokens` (the private
|
|
68
|
+
`extract_token_payload` is removed). `lib/standard_id/google/railtie.rb` is
|
|
69
|
+
replaced by `StandardId::Providers.plugin_railtie(:google, ...)`.
|
|
70
|
+
- **Error messages**, now consistently Google-prefixed:
|
|
71
|
+
- `Either code, id_token, or access_token must be provided` → `Google sign-in requires a code, an id_token or an access_token`
|
|
72
|
+
- `Google provider is not configured` → `Google OAuth is not configured` (client ID missing) or `Google OAuth credentials are incomplete: google_client_secret not set` (code exchange only)
|
|
73
|
+
- `Missing authorization code` → `Google authorization code is missing`
|
|
74
|
+
- `Failed to exchange Google authorization code` → `...: <error>` (Google's `error`, else `HTTP <status>`)
|
|
75
|
+
- `Google response missing access token` → `Google token response is missing access_token`
|
|
76
|
+
- `Missing id_token` → `Google id_token is missing`
|
|
77
|
+
- `Invalid or expired id_token` → `Invalid Google ID token: invalid or expired`
|
|
78
|
+
- `ID token audience mismatch. Expected: ..., got: ...` → `Invalid Google ID token audience`
|
|
79
|
+
- `ID token issuer invalid. Expected Google, got: ...` → `Invalid Google ID token issuer`
|
|
80
|
+
- `Missing access token` → `Google access token is missing`
|
|
81
|
+
- `Invalid or expired access token` → `Invalid Google access token: invalid or expired`
|
|
82
|
+
- `Access token audience mismatch. Expected: ..., got: ...` → `Invalid Google access token audience`
|
|
83
|
+
- `Failed to fetch Google user info` → `...: HTTP <status>`
|
|
84
|
+
- **Spec layout mirrors `lib/`** and standard_id-apple:
|
|
85
|
+
`spec/standard_id/providers/google_spec.rb` →
|
|
86
|
+
`spec/standard_id/google/providers/google_spec.rb`, plus
|
|
87
|
+
`spec/standard_id/google/registration_spec.rb`.
|
|
88
|
+
- Install generator and README use the canonical `GOOGLE_CLIENT_ID` /
|
|
89
|
+
`GOOGLE_CLIENT_SECRET`, and document the ENV fallback, required field and
|
|
90
|
+
flows.
|
|
91
|
+
|
|
92
|
+
### Deprecated
|
|
93
|
+
|
|
94
|
+
- **`GOOGLE_OAUTH_CLIENT_ID` / `GOOGLE_OAUTH_CLIENT_SECRET`** as ENV sources.
|
|
95
|
+
Read only when the field is never assigned and the canonical variable is
|
|
96
|
+
unset, with one warning per variable per process through
|
|
97
|
+
`StandardId.deprecator`.
|
|
98
|
+
|
|
99
|
+
### Removed
|
|
100
|
+
|
|
101
|
+
- `StandardId::Google::Railtie` (replaced by the Railtie `plugin_railtie`
|
|
102
|
+
defines, `StandardId::Providers::Railties::Google`).
|
|
103
|
+
|
|
104
|
+
## [0.4.0] - 2026-07-31
|
|
105
|
+
|
|
106
|
+
### Added
|
|
107
|
+
|
|
108
|
+
- **Install generator: `bin/rails g standard_id:google:install`.** Writes
|
|
109
|
+
`config/initializers/standard_id_google.rb` with the `social.google_*` fields
|
|
110
|
+
wired to ENV, then prints the environment variables the host has to set and
|
|
111
|
+
the reminder that `/auth/callback/google` must be registered as an authorized
|
|
112
|
+
redirect URI for **every** origin served — the Google console matches the
|
|
113
|
+
redirect exactly, so staging and production each need their own. Idempotent:
|
|
114
|
+
re-running skips an existing initializer; `--force` overwrites,
|
|
115
|
+
`--skip-initializer` writes nothing.
|
|
116
|
+
|
|
117
|
+
It writes a **separate** file rather than editing `standard_id.rb`, so the
|
|
118
|
+
provider can be removed by deleting one file and `standard_id`'s own install
|
|
119
|
+
generator stays free to overwrite its initializer without clobbering these
|
|
120
|
+
credentials. Initializers load alphabetically, so the base config is applied
|
|
121
|
+
first. The generated file uses the `config.social.` form throughout — a spec
|
|
122
|
+
pins that it never emits the unqualified `config.google_*` form, which works
|
|
123
|
+
today only because the names happen to be unique across scopes.
|
|
124
|
+
|
|
125
|
+
Five of the nine `standard_*` gems shipped an install generator and this was
|
|
126
|
+
not one of them, which left both consumers assembling the block from the
|
|
127
|
+
README by hand.
|
|
128
|
+
|
|
129
|
+
### Documentation
|
|
130
|
+
|
|
131
|
+
- **Consumer list corrected in `CLAUDE.md`: this gem has two consumers, not
|
|
132
|
+
one.** It named `luminality-web` only; `sidekick-web` also consumes it. Both
|
|
133
|
+
live in sibling workspaces rather than beside this repo, which is how the
|
|
134
|
+
second one went unnoticed.
|
|
135
|
+
|
|
136
|
+
- **Corrected the Configuration section, which showed a form that raised on
|
|
137
|
+
`standard_id` <= 0.32.0.** These fields are declared by this gem, and until
|
|
138
|
+
`standard_id` 0.33.0 they were declared from this gem's Railtie
|
|
139
|
+
`after_initialize` — after `config/initializers` — so the documented plain
|
|
140
|
+
initializer raised `StandardId::ConfigurationError: Unknown field
|
|
141
|
+
'google_client_id' for scope 'social'`. The README now records the
|
|
142
|
+
`after_initialize` workaround for older `standard_id`, states that 0.33.0
|
|
143
|
+
declares provider fields before `:load_config_initializers` so the plain form
|
|
144
|
+
is correct there, and notes that the fields do not exist at all without this
|
|
145
|
+
gem in the Gemfile — on any `standard_id` version.
|
|
146
|
+
|
|
147
|
+
### Changed
|
|
148
|
+
|
|
149
|
+
- **`standard_id` dependency tightened from `~> 0.1, >= 0.1.7` to `~> 0.29.0`.**
|
|
150
|
+
The old constraint claimed compatibility with every `0.x` release while this
|
|
151
|
+
plugin reaches into `StandardId::ProviderRegistry` and
|
|
152
|
+
`StandardId::Providers::Google`, and `standard_id` is pre-1.0 with breaking
|
|
153
|
+
minors. Bundler would happily resolve against an untested minor and fail at
|
|
154
|
+
runtime instead of at resolution. Both current consumers already pin
|
|
155
|
+
`standard_id "~> 0.29.0"`, so nothing existing is affected.
|
|
156
|
+
|
|
157
|
+
### Fixed
|
|
158
|
+
|
|
159
|
+
- Gemspec no longer packages the `.claude/` directory. Published `0.3.0` shipped
|
|
160
|
+
`.claude/settings.json`, `.claude/hooks/enforce-worktree.sh`, and three skill
|
|
161
|
+
files to every consumer — this gem's `spec.files` reject-list was the only one
|
|
162
|
+
in the `standard_*` family missing the `.claude/` prefix (`standard_id-apple`
|
|
163
|
+
already had it). Packaged file count drops 21 → 16; `lib/` and `LICENSE` are
|
|
164
|
+
unaffected.
|
|
165
|
+
- Gemspec now uses an allow-list (`Dir["lib/**/*", …]`) rather than a
|
|
166
|
+
`git ls-files` reject-list, so packaging fails **closed** and this class of
|
|
167
|
+
leak cannot recur. Also drops `.editorconfig`, `.pinact.yaml`, `.rspec`,
|
|
168
|
+
`.rubocop.yml`, `.ruby-version`, `AGENTS.md`, `CLAUDE.md`, and
|
|
169
|
+
`CODE_OF_CONDUCT.md`; `lib/` is byte-identical.
|
|
170
|
+
|
|
10
171
|
## [0.3.0] - 2026-04-29
|
|
11
172
|
|
|
12
173
|
### Added
|
data/{LICENSE.txt → LICENSE}
RENAMED
data/README.md
CHANGED
|
@@ -4,6 +4,8 @@ This gem extracts the Google OAuth provider from the core [`standard_id`](https:
|
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
+
Requires `standard_id` 0.42 or later.
|
|
8
|
+
|
|
7
9
|
Add the gem next to `standard_id`:
|
|
8
10
|
|
|
9
11
|
```ruby
|
|
@@ -20,21 +22,127 @@ bundle install
|
|
|
20
22
|
|
|
21
23
|
The gem automatically registers itself with StandardId when it is required.
|
|
22
24
|
|
|
25
|
+
Then run the install generator to drop the credentials block in place:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bin/rails g standard_id:google:install
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This writes `config/initializers/standard_id_google.rb` — deliberately a
|
|
32
|
+
separate file from `config/initializers/standard_id.rb`, so the provider can be
|
|
33
|
+
removed by deleting one file and `standard_id`'s own install generator stays
|
|
34
|
+
free to overwrite its initializer without clobbering these values. Initializers
|
|
35
|
+
load alphabetically, so the base config is applied first. The generator is
|
|
36
|
+
idempotent; re-running on an existing initializer skips with a clear message
|
|
37
|
+
(pass `--force` to overwrite).
|
|
38
|
+
|
|
23
39
|
## Configuration
|
|
24
40
|
|
|
25
|
-
|
|
41
|
+
The generator writes this for you; the block is documented here for hosts
|
|
42
|
+
configuring by hand. Configure your Google credentials inside the StandardId
|
|
43
|
+
configuration block:
|
|
26
44
|
|
|
27
45
|
```ruby
|
|
46
|
+
# config/initializers/standard_id_google.rb
|
|
28
47
|
StandardId.configure do |config|
|
|
29
|
-
config.social.google_client_id = ENV.fetch("
|
|
30
|
-
config.social.google_client_secret = ENV.fetch("
|
|
48
|
+
config.social.google_client_id = ENV.fetch("GOOGLE_CLIENT_ID", nil)
|
|
49
|
+
config.social.google_client_secret = ENV.fetch("GOOGLE_CLIENT_SECRET", nil)
|
|
31
50
|
end
|
|
32
51
|
```
|
|
33
52
|
|
|
34
53
|
With those values in place, StandardId routes such as `/auth/callback/google` continue to function using this provider gem.
|
|
35
54
|
|
|
55
|
+
### ENV fallback
|
|
56
|
+
|
|
57
|
+
On `standard_id` 0.42+, a field you never assign falls back to the ENV
|
|
58
|
+
variable named after it, upper-cased:
|
|
59
|
+
|
|
60
|
+
| Field | ENV variable | Deprecated fallback |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| `google_client_id` | `GOOGLE_CLIENT_ID` | `GOOGLE_OAUTH_CLIENT_ID` |
|
|
63
|
+
| `google_client_secret` | `GOOGLE_CLIENT_SECRET` | `GOOGLE_OAUTH_CLIENT_SECRET` |
|
|
64
|
+
|
|
65
|
+
So with those variables set the block above is optional. Explicit
|
|
66
|
+
configuration, even `nil`, always wins. The `GOOGLE_OAUTH_*` names — what
|
|
67
|
+
install generators before 0.5.0 wrote — are still read when the canonical
|
|
68
|
+
variable is unset and the field is never assigned, with a deprecation warning;
|
|
69
|
+
rename them. (An initializer that assigns `ENV.fetch("GOOGLE_OAUTH_CLIENT_ID")`
|
|
70
|
+
explicitly keeps working as-is.)
|
|
71
|
+
|
|
72
|
+
### Required fields and the boot check
|
|
73
|
+
|
|
74
|
+
`google_client_id` switches the provider on — it is what
|
|
75
|
+
`StandardId.social_provider_enabled?(:google)` and the `google_enabled` Inertia
|
|
76
|
+
prop report. While it is set, `google_client_secret` is required: the web
|
|
77
|
+
sign-in's code exchange needs it, so without it the user authenticates with
|
|
78
|
+
Google and only then does the callback fail. StandardId checks this once every
|
|
79
|
+
plugin has registered:
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
StandardId::Providers::Google.configuration_errors
|
|
83
|
+
# => ["google_client_secret is required when google_client_id is set"]
|
|
84
|
+
|
|
85
|
+
config.social.provider_misconfiguration = :raise # fail a production boot instead of warning
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Flows
|
|
89
|
+
|
|
90
|
+
| Flow | Needs `google_client_secret` |
|
|
91
|
+
|---|---|
|
|
92
|
+
| Web (`/auth/callback/google`, authorization code) | yes |
|
|
93
|
+
| Native `id_token` (`/api/oauth/callback/google`) | no |
|
|
94
|
+
| Native `access_token` | no |
|
|
95
|
+
|
|
96
|
+
ID tokens and access tokens are both checked against Google's tokeninfo
|
|
97
|
+
endpoint (`https://oauth2.googleapis.com/tokeninfo`), then against this app's
|
|
98
|
+
client ID. An app that only accepts native ID tokens can run without a client
|
|
99
|
+
secret; it will get the boot warning above, because an enabled provider shows
|
|
100
|
+
the web sign-in button — leave `provider_misconfiguration` at `:warn` there.
|
|
101
|
+
|
|
102
|
+
### Boot ordering (standard_id <= 0.32.0)
|
|
103
|
+
|
|
104
|
+
These fields are declared by *this gem*, not by `standard_id`, and until
|
|
105
|
+
`standard_id` 0.33.0 they were declared from this gem's Railtie
|
|
106
|
+
`after_initialize` — which runs *after* `config/initializers`. On `standard_id`
|
|
107
|
+
**0.32.0 and earlier** the block above therefore raised:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
StandardId::ConfigurationError: Unknown field 'google_client_id' for scope 'social'
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The workaround was to wrap the writes:
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
# Only needed on standard_id <= 0.32.0
|
|
117
|
+
Rails.application.config.after_initialize do
|
|
118
|
+
StandardId.configure do |config|
|
|
119
|
+
config.social.google_client_id = ENV.fetch("GOOGLE_CLIENT_ID", nil)
|
|
120
|
+
config.social.google_client_secret = ENV.fetch("GOOGLE_CLIENT_SECRET", nil)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`standard_id` **>= 0.33.0** declares every loaded provider's fields before
|
|
126
|
+
`:load_config_initializers`, so a plain initializer is correct. The wrapper is no
|
|
127
|
+
longer needed and existing ones keep working unchanged.
|
|
128
|
+
|
|
129
|
+
Note this is about *ordering*, not just versions: **the fields do not exist
|
|
130
|
+
without this gem in your Gemfile**, on any `standard_id` version. Configuring
|
|
131
|
+
`social.google_*` with the plugin absent raises the same error, correctly.
|
|
132
|
+
|
|
36
133
|
## Testing
|
|
37
134
|
|
|
135
|
+
In a host app, pin the plugin's registration with standard_id's shared
|
|
136
|
+
example:
|
|
137
|
+
|
|
138
|
+
```ruby
|
|
139
|
+
require "standard_id/testing"
|
|
140
|
+
|
|
141
|
+
RSpec.describe "StandardId social providers" do
|
|
142
|
+
it_behaves_like "a registered StandardId provider", :google
|
|
143
|
+
end
|
|
144
|
+
```
|
|
145
|
+
|
|
38
146
|
Run the provider test suite with:
|
|
39
147
|
|
|
40
148
|
```bash
|
|
@@ -53,4 +161,4 @@ To release a new version:
|
|
|
53
161
|
|
|
54
162
|
## License
|
|
55
163
|
|
|
56
|
-
The gem is available as open source under the terms of the [MIT License](LICENSE
|
|
164
|
+
The gem is available as open source under the terms of the [MIT License](LICENSE).
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
|
|
5
|
+
module StandardId
|
|
6
|
+
module Google
|
|
7
|
+
module Generators
|
|
8
|
+
# Installs the Google provider's credentials block in a host Rails app.
|
|
9
|
+
#
|
|
10
|
+
# Writes `config/initializers/standard_id_google.rb` — a separate file
|
|
11
|
+
# from `config/initializers/standard_id.rb` on purpose. The provider is
|
|
12
|
+
# opt-in per app, so its credentials should be removable by deleting one
|
|
13
|
+
# file, and `standard_id`'s own install generator must stay free to
|
|
14
|
+
# overwrite its initializer without clobbering these values.
|
|
15
|
+
#
|
|
16
|
+
# Initializers load alphabetically, so `standard_id.rb` runs before
|
|
17
|
+
# `standard_id_google.rb` — the base configuration is already applied by
|
|
18
|
+
# the time this file sets the `social.google_*` fields.
|
|
19
|
+
#
|
|
20
|
+
# Idempotent: re-running skips an initializer that is already there.
|
|
21
|
+
# `--skip-initializer` opts out; `--force` overwrites.
|
|
22
|
+
class InstallGenerator < Rails::Generators::Base
|
|
23
|
+
source_root File.expand_path("templates", __dir__)
|
|
24
|
+
|
|
25
|
+
INITIALIZER_PATH = "config/initializers/standard_id_google.rb"
|
|
26
|
+
|
|
27
|
+
desc <<~DESC
|
|
28
|
+
Installs StandardId Google. This writes #{INITIALIZER_PATH} with the
|
|
29
|
+
social.google_* fields wired to ENV, and prints the env vars the host
|
|
30
|
+
needs to set.
|
|
31
|
+
|
|
32
|
+
The generator is idempotent — an existing initializer is skipped with
|
|
33
|
+
a clear message. Pass --force to overwrite.
|
|
34
|
+
DESC
|
|
35
|
+
|
|
36
|
+
class_option :skip_initializer, type: :boolean, default: false,
|
|
37
|
+
desc: "Do not write #{INITIALIZER_PATH}"
|
|
38
|
+
class_option :force, type: :boolean, default: false,
|
|
39
|
+
desc: "Overwrite #{INITIALIZER_PATH} if it already exists"
|
|
40
|
+
|
|
41
|
+
def copy_initializer
|
|
42
|
+
if options[:skip_initializer]
|
|
43
|
+
say_status("skip", "#{INITIALIZER_PATH} (--skip-initializer)", :yellow)
|
|
44
|
+
return
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
if File.exist?(File.join(destination_root, INITIALIZER_PATH)) && !options[:force]
|
|
48
|
+
say_status("identical", "#{INITIALIZER_PATH} (already exists; pass --force to overwrite)", :blue)
|
|
49
|
+
return
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
template "initializer.rb.erb", INITIALIZER_PATH, force: options[:force]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def print_env_hint
|
|
56
|
+
return if options[:skip_initializer]
|
|
57
|
+
|
|
58
|
+
say ""
|
|
59
|
+
say "=" * 79
|
|
60
|
+
say "StandardId Google installed."
|
|
61
|
+
say ""
|
|
62
|
+
say "Set these in the host's environment (1Password / DO app spec / .env):"
|
|
63
|
+
say ""
|
|
64
|
+
say " GOOGLE_CLIENT_ID the OAuth 2.0 Web application client ID"
|
|
65
|
+
say " GOOGLE_CLIENT_SECRET its client secret — required whenever GOOGLE_CLIENT_ID"
|
|
66
|
+
say " is set; StandardId checks for it at boot"
|
|
67
|
+
say ""
|
|
68
|
+
say "Register /auth/callback/google as an authorized redirect URI in the"
|
|
69
|
+
say "Google Cloud console for EVERY origin you serve — the console matches"
|
|
70
|
+
say "the redirect exactly, so staging and production each need their own."
|
|
71
|
+
say "=" * 79
|
|
72
|
+
say ""
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Google Sign In credentials for StandardId.
|
|
4
|
+
#
|
|
5
|
+
# These two fields are declared by the standard_id-google gem, NOT by
|
|
6
|
+
# standard_id — they do not exist unless this gem is in the Gemfile, on any
|
|
7
|
+
# standard_id version. Removing the gem and leaving this file behind raises
|
|
8
|
+
# `StandardId::ConfigurationError: Unknown field 'google_client_id' for scope
|
|
9
|
+
# 'social'`, which is correct behaviour, not a bug.
|
|
10
|
+
#
|
|
11
|
+
# Set them in the `social` scope, as below. The unqualified form
|
|
12
|
+
# (`config.google_client_id = ...`) happens to work today because StandardId
|
|
13
|
+
# routes a unique unqualified name to its owning scope, but it stops working
|
|
14
|
+
# the day another scope declares a colliding name. Use `config.social.`.
|
|
15
|
+
#
|
|
16
|
+
# ENV: on standard_id >= 0.42 a field this file does not assign falls back to
|
|
17
|
+
# the ENV variable named after it, upper-cased — GOOGLE_CLIENT_ID and
|
|
18
|
+
# GOOGLE_CLIENT_SECRET — which are the names used below. The assignments are
|
|
19
|
+
# kept so the wiring is visible; delete them to leave it to the fallback, or
|
|
20
|
+
# point them at another source (e.g. Rails credentials). Installs before
|
|
21
|
+
# standard_id-google 0.5.0 used GOOGLE_OAUTH_CLIENT_ID / _SECRET.
|
|
22
|
+
#
|
|
23
|
+
# google_client_id switches the provider on. While it is set, StandardId's boot
|
|
24
|
+
# check requires google_client_secret, which the web sign-in's code exchange
|
|
25
|
+
# needs (warns by default; `config.social.provider_misconfiguration = :raise`
|
|
26
|
+
# fails a production boot instead). Native id_token / access_token sign-in
|
|
27
|
+
# needs only the client ID.
|
|
28
|
+
StandardId.configure do |config|
|
|
29
|
+
config.social.google_client_id = ENV.fetch("GOOGLE_CLIENT_ID", nil)
|
|
30
|
+
config.social.google_client_secret = ENV.fetch("GOOGLE_CLIENT_SECRET", nil)
|
|
31
|
+
end
|