BikeControl (SwiftControl)
使用 Zwift Click、Zwift Play、Shimano Di2 或任何藍牙控制器,搭配 MyWhoosh、Rouvy、Zwift 等。iOS、Android、Windows、macOS 均可免費試用。
AI 翻译
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Web based tracker for Yorkshire Golf
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Web based tracker for Yorkshire Golf
For consistent naming of pages/sections and guidance for the scripts Course Audit tool, see .github/copilot-instructions.md.
Managed as resouces:
courses.csv contains the list of yorkshire coursescourse-records.csv contains the list of played courses. fk into the courses listRequires:
./mvnw clean package
./mvnw versions:set -DremoveSnapshot=true -DprocessAllModules=true -DgenerateBackupPoms=false
./mvnw clean package
./mvnw docker:push
Build the Docker image:
deploy4j deploy --version=0.0.15
./mvnw versions:set -DnextSnapshot=true -DprocessAllModules=true -DgenerateBackupPoms=false
Go to https://www.yorkshiregolf.life
Run from repo root:
jbang scripts/CourseAudit.java
By default, closed courses are hidden.
To include closed courses for editing:
jbang scripts/CourseAudit.java --show-closed
https://www.chartjs.org/docs/latest/samples/other-charts/multi-series-pie.html https://stackoverflow.com/questions/20966817/how-to-add-text-inside-the-doughnut-chart-using-chart-js
The application is a single Maven module using Java 21, Spring Boot 4.0.3 and Spring Security 7.0.3. Spring MVC controllers render j2html views. JDBC repositories use a file-backed H2 database; Liquibase applies additive YAML changelogs at startup. There is no separate identity service.
Existing accounts have a numeric golf_user.id, unique email, BCrypt password,
generated public tracker_id, role and lockout counters. There is no separate
public username to collect. Rounds reference the numeric user ID; public Challenge
Tracker URLs use the tracker ID. Registration, form login, POST logout and
hashed, expiring password-reset tokens remain available. Successful login returns
to /challenge. Browser actions use Spring Security CSRF protection.
External identities are separate from local accounts: only the provider and its opaque, case-sensitive subject identify a provider login. Matching emails never merge accounts. To use a provider with an existing account, sign in to that account first and explicitly link the provider. Existing IDs, tracker URLs and round ownership must not change. Provider-only accounts do not need an email or password.
Local login continues to identify existing accounts by email; federated sessions instead carry the local numeric user ID, not provider claims. The identity table stores no names, emails, pictures or provider tokens. OAuth authorized clients are not retained for API access or refresh. Provider buttons use locally served artwork, not third-party scripts or remote logo requests. Asset attribution and licensing accompany the artwork.
All providers default to disabled and can be enabled independently. Supply the following environment variables through the existing deployment environment:
| Provider | Enable flag | Client ID | Client secret |
|---|---|---|---|
AUTH_GOOGLE_ENABLED=true | AUTH_GOOGLE_CLIENT_ID | AUTH_GOOGLE_CLIENT_SECRET | |
| Apple | AUTH_APPLE_ENABLED=true | AUTH_APPLE_CLIENT_ID | AUTH_APPLE_CLIENT_SECRET |
AUTH_FACEBOOK_ENABLED=true | AUTH_FACEBOOK_CLIENT_ID | AUTH_FACEBOOK_CLIENT_SECRET | |
| X | AUTH_X_ENABLED=true | AUTH_X_CLIENT_ID | AUTH_X_CLIENT_SECRET |
Facebook and Apple sign-in are currently disabled in the production deployment. Facebook is not enabled because Yorkshire Golf Life does not have a registered business, and Apple is not enabled because Apple Developer Program membership costs £80 per year. X sign-in is enabled in the production deployment; configure the corresponding GitHub Actions secrets so the release workflow can inject its OAuth credentials.
Apple's secret is the signed JWT described below, not the downloaded private key.
An enabled provider requires both credentials; malformed configuration fails
startup without printing secret values. The underlying Spring properties are
golf.auth.<provider>.enabled, .client-id and .client-secret.
APP_BASE_URL supplies the trusted public origin used for callbacks: HTTPS in
production, or HTTP loopback for local Google/Facebook development where accepted
by the provider. Restart after changing credentials or enable flags.
Email/password registration is disabled by default and is not available on the
live site. To create a local test account for linking-provider tests, set
AUTH_LOCAL_REGISTRATION_ENABLED=true in the same local shell as
APP_BASE_URL=http://localhost:8080, then restart the app. The app rejects
enabling this option for non-loopback origins. Turn it off after testing.
Visit /account while signed in to manage sign-in methods. Local accounts confirm
changes using their current password. Accounts without a password first confirm
through a new authorization with an already-linked provider. Apple can reuse its
own SSO session; this is proof of control, not a guarantee of a new password prompt.
Linking starts a new provider authorization
flow; it does not replace another link or match accounts by email. Removing the
last usable sign-in method is rejected, including when other linked providers
are disabled. Sensitive operations are rate-limited.
Users can permanently delete their account and all recorded rounds from
Sign-in methods after confirming with their password or a linked provider.
Deletion removes the account data from the live database; backup copies, if any,
may remain under infrastructure retention processes.
Prefer separate applications and credentials for development/staging and production where the provider supports them. Register the exact callback URL, including scheme, host and path:
https://yorkshiregolf.life/login/oauth2/code/googlehttps://yorkshiregolf.life/login/oauth2/code/applehttps://yorkshiregolf.life/login/oauth2/code/facebookhttps://yorkshiregolf.life/login/oauth2/code/xIf using www or a staging hostname, register that exact hostname instead and
set APP_BASE_URL consistently. Do not use wildcard callbacks or derive public
callbacks from an untrusted Host header.
Google: In Google Auth Platform,
configure the consent screen, audience/test users and a Web application OAuth
client. Add the callback as an authorized redirect URI. Authentication needs only
the openid and email scopes, not Gmail, Contacts or other Google APIs. The
verified email claim is checked transiently to prevent a first-time Google sign-in
from creating a second account when that email already belongs to an existing
account; it is not stored from the Google profile. The member must sign in using
their existing method and link Google from Sign-in methods.
Apple: Follow Apple's
web configuration guide.
Enable Sign in with Apple for a primary App ID, associate a Services ID with it,
and configure the website domain and exact return URL. The Services ID is the
client ID. Create a Sign in with Apple key and use it to generate an ES256-signed
client-secret JWT with the Team ID, Key ID, Services ID and Apple audience,
following Apple's
token documentation.
Keep the signing key outside the repository. Client secrets expire after at most
six months; schedule rotation before expiry and replace the deployed secret.
Apple requires an eligible Apple Developer Program account, which can entail a
membership fee; this implementation does not remove that provider prerequisite.
Web return URLs require a real HTTPS domain, not localhost or an IP address.
Only openid is requested, avoiding name/email scopes. Apple uses a cross-site
form_post callback. Its exact POST callback is exempt from the application's
CSRF-token check, but must pass Spring Security's session-bound OAuth state and
OIDC nonce validation. Other browser POST actions retain CSRF protection.
When Apple is enabled, session cookies require SameSite=None; Secure so the
callback can recover its original session; otherwise cookies use SameSite=Lax.
Facebook: Create a suitable application in
Meta for Developers, enable Facebook
Login for the web, configure the site domain and production Valid OAuth Redirect
URI, and obtain the App ID and App Secret. Use the AUTH_FACEBOOK_* environment
variables for local testing and production secrets; never commit the credentials.
The same Meta app can serve local testing and production. In Development mode,
Meta automatically allows the localhost callback; the app uses
http://localhost:8080/login/oauth2/code/facebook locally.
Request public_profile and email. The Facebook email, when supplied, is
checked transiently to prevent accidental duplicate accounts; it is not stored
and never links accounts automatically. Only the application-scoped Facebook
user ID is stored. No name or profile photo is requested or stored. The public
privacy and data-deletion URLs are
https://yorkshiregolf.life/privacy and
https://yorkshiregolf.life/data-deletion. Keep Meta's app in Development mode
while testing. Before public login, make sure the deployed site is accessible to
reviewers, complete Meta's App Review requirements for public users, and switch
the app to Live only after approval.
X: In the X Developer Portal,
enable OAuth 2.0 for a Web App, configure the exact callback URL above, and set
the Client ID and Client Secret. The app requests tweet.read and users.read
for X's authenticated-user lookup; authorization uses PKCE and the profile
lookup stores only the X account ID.
Never place credentials, authorization codes, access/ID tokens, raw provider responses or provider email addresses into logs, screenshots, support tickets or source control. Disable HTTP wire/TRACE debugging in deployed environments and avoid recording callback query strings in proxy/access logs.
Real-provider smoke tests require operator-supplied, non-production credentials and provider-console configuration. Deterministic automated tests do not replace these checks, provider approval or a review of current branding requirements.
With Java 21 selected, run the focused authentication tests, then the full suite:
./mvnw test -Dtest=FederatedProvidersTest,FederatedSecurityTest,OidcProtocolTest,AccountActionGuardTest,ExternalIdentityServiceTest,UserRepositoryTest
./mvnw test
Protocol tests use a local mock provider and signed test ID tokens, not live credentials. They exercise the real Spring Security callback processing, including invalid token claims, nonce/state rejection and session rotation.
env.secret in its deployment
configuration; add only the enabled providers' variable names there and supply
their values through the existing secret mechanism.websecure and HTTP redirected to
HTTPS. Set APP_BASE_URL=https://yorkshiregolf.life; ensure the backend is not
publicly reachable around the trusted proxy. Check external callback URLs and
Secure, HttpOnly and SameSite session-cookie attributes in a browser.Provider-only accounts have no email-based recovery unless a separate local login method is deliberately added. Link another usable provider before losing access to the only one. Recovery redesign, password retirement and deletion of existing personal data are outside Phase 1.