-
Notifications
You must be signed in to change notification settings - Fork 7
Add F3 Me profile manager app #163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
taterhead247
wants to merge
44
commits into
dev
Choose a base branch
from
feat/me
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
3433d51
f3 me initial
taterhead247 1c0951c
it's alive!
taterhead247 9ca8017
mostly working local
taterhead247 0d90e53
branding
taterhead247 d6fb848
fixing ci checks
taterhead247 1b80430
fix build by downgrading react to 18
taterhead247 deba197
fixed orange change bar
taterhead247 2e1dc1e
remove gif as allowable type
taterhead247 5a142fd
Fix bugs in roles API, avatar state, toast a11y, meta serialization, …
Copilot 45e1458
saving seed file
taterhead247 3e87bd2
converted from firebase to cloud run
taterhead247 8e4f87d
more
taterhead247 909f4bf
2 artifact registries instead of 1
taterhead247 72bec82
docker fixes for deploy
taterhead247 a2324bf
still fixing docker - adding turbo
taterhead247 c99c84e
docker fix. moving env variable
taterhead247 cc76bbe
docker - removed node_env
taterhead247 e27ceb9
docker fixes. dependencies
taterhead247 58b6d66
fixed a few console errors
taterhead247 2ab375a
minor html complaint
taterhead247 d034174
Fix input validation, type safety, and missing config files in apps/m…
Copilot 6e438fa
removed firebase residue and cleanup
taterhead247 0560373
matching versions and removing gifs
taterhead247 47cd123
open-redirect vector
taterhead247 02a21a0
useful auth fail responses
taterhead247 057ae68
consolidate references
taterhead247 ca3eef5
html fix
taterhead247 c6dd468
toast timers
taterhead247 60e8b60
add server-only package and improve environment variable handling
taterhead247 9e61ad4
handling server side security changes
taterhead247 00d9643
type validation
taterhead247 81a3097
meta validaton
taterhead247 f8cccd7
wasn't saved yet
taterhead247 a92b791
new api
taterhead247 abb60e4
missed some
taterhead247 df04672
a ton of changes on user reckoning
taterhead247 87bdccf
stopping to take a look at api security
taterhead247 3b0ca35
vitest fix
taterhead247 f1ece7e
lint cleanup
taterhead247 3da429d
that last one was dev, now it's to make lefthook happy
taterhead247 c8549c0
Refactor me app to use @acme/sso SDK and fix sign-out flow
taterhead247 85e5894
fix(me): Security fixes, hook extraction, dead code removal (#235)
pstaylor-patrick 00a90bd
Add me app to env generation pipeline and update dev setup docs
pstaylor-patrick 24ba58a
Merge branch 'dev' into feat/me
taterhead247 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,7 +45,7 @@ After install, re-verify. If still missing, print the manual install instruction | |
|
|
||
| --- | ||
|
|
||
| ## Step 3 — Check GCP Authentication | ||
| ## Step 3 — Check GCP Authentication and Project Context | ||
|
|
||
| ```bash | ||
| gcloud auth print-identity-token 2>/dev/null | ||
|
|
@@ -62,19 +62,64 @@ GCP authentication needed. Run these commands in your terminal: | |
|
|
||
| Wait for the user to confirm, then re-check. | ||
|
|
||
| **Quota project check:** | ||
|
|
||
| The ADC quota project must be set correctly for the Cloud SQL proxy and secret access to work. This is critical when switching between workspaces (e.g., f3-nation vs joinfold). | ||
|
|
||
| ```bash | ||
| QUOTA_PROJECT=$(cat ~/.config/gcloud/application_default_credentials.json 2>/dev/null | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));console.log(d.quota_project_id||'')" 2>/dev/null) | ||
| ``` | ||
|
|
||
| If `QUOTA_PROJECT` is not `f3-authentication-staging`, fix it: | ||
|
|
||
| ```bash | ||
| gcloud auth application-default set-quota-project f3-authentication-staging | ||
| ``` | ||
|
|
||
| After changing the quota project, restart the Cloud SQL proxy (kill existing process; launchd or systemd will restart it automatically): | ||
|
|
||
| ```bash | ||
| kill $(lsof -ti :5433) 2>/dev/null | ||
| # Wait for launchd/systemd to restart it | ||
| sleep 2 | ||
| lsof -i :5433 # verify new process is listening | ||
| ``` | ||
|
|
||
| **GCP project access verification:** | ||
|
|
||
| The monorepo uses two GCP projects for secrets: | ||
|
|
||
| | Project | Apps | Secrets | | ||
| | --------------------------- | -------------- | ----------------------------------------------------------------- | | ||
| | `f3-authentication-staging` | api, map, auth | DB creds, API keys, auth JWT, GCS logo bucket, SendGrid | | ||
| | `f3-me-app-staging` | me | OAuth client secret, session secret, F3 API key, GCS avatar creds | | ||
|
|
||
| Verify access to both: | ||
|
|
||
| ```bash | ||
| gcloud secrets list --project=f3-authentication-staging --limit=1 2>/dev/null | ||
| gcloud secrets list --project=f3-me-app-staging --limit=1 2>/dev/null | ||
| ``` | ||
|
|
||
| If the second fails, warn: "No access to f3-me-app-staging secrets. The me app .env.local won't be auto-generated. Ask a project owner (tackle@f3nation.com) for Secret Manager Secret Accessor role." | ||
|
|
||
| --- | ||
|
|
||
| ## Step 4 — Generate Environment | ||
|
|
||
| Check if `.env` exists at the repo root: | ||
| Check if `.env` and me app env exist: | ||
|
|
||
| ```bash | ||
| test -f .env && echo "EXISTS" || echo "MISSING" | ||
| test -f .env && echo ".env EXISTS" || echo ".env MISSING" | ||
| test -f apps/me/.env.local && echo "me .env.local EXISTS" || echo "me .env.local MISSING" | ||
| ``` | ||
|
|
||
| **If missing or `reset` mode:** Run `pnpm env:generate` to pull staging secrets from GCP and create `.env` with symlinks. | ||
| **If either is missing or `reset` mode:** Run `pnpm env:generate` to pull staging secrets from GCP. This will: | ||
|
|
||
| **If exists:** Validate it has the required variables by cross-referencing with `packages/env/src/index.ts`. Report any missing vars. | ||
| - Create root `.env` from `f3-authentication-staging` secrets (shared by api, map, auth via symlinks) | ||
| - Create `apps/me/.env.local` from `f3-me-app-staging` secrets (me app has its own OAuth client, session, and GCS config) | ||
|
|
||
| **If both exist:** Validate required variables. The root `.env` should have: `DATABASE_URL`, `API_KEY`, `AUTH_SECRET`, `AUTH_JWT_PRIVATE_KEY`. The me `.env.local` should have: `OAUTH_CLIENT_ID`, `OAUTH_CLIENT_SECRET`, `SESSION_SECRET`, `F3_API_KEY`, `F3_API_BASE_URL`. | ||
|
|
||
| --- | ||
|
|
||
|
|
@@ -154,10 +199,16 @@ Prerequisites: | |
| GCP Auth: | ||
| Identity: ✓ (user@example.com) | ||
| App Default: ✓ | ||
| ADC Quota Project: f3-authentication-staging ✓ | ||
|
|
||
| GCP Projects: | ||
| f3-authentication-staging: ✓ (secrets accessible) | ||
| f3-me-app-staging: ✓ (secrets accessible) | ||
|
|
||
| Environment: | ||
| .env: ✓ (generated 2026-04-09) | ||
| Symlinks: api ✓ map ✓ auth ✓ | ||
| me .env.local: ✓ (generated 2026-04-09, from f3-me-app-staging) | ||
|
|
||
| Database: | ||
| Proxy: ✓ running on :5433 (background daemon) | ||
|
|
@@ -179,18 +230,23 @@ When called with `fix`, diagnose and auto-fix issues: | |
|
|
||
| 1. Missing prerequisites → install them | ||
| 2. GCP auth expired → prompt re-auth | ||
| 3. `.env` missing or incomplete → regenerate | ||
| 4. Proxy not running → start it (or install daemon) | ||
| 5. Port conflicts → identify and offer to kill conflicting processes | ||
| 6. Stale symlinks → recreate | ||
| 3. ADC quota project wrong → `gcloud auth application-default set-quota-project f3-authentication-staging` + restart proxy | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is ADC? Sorry if I'm missing something |
||
| 4. `.env` missing or incomplete → regenerate via `pnpm env:generate` | ||
| 5. `apps/me/.env.local` missing → regenerate (requires `f3-me-app-staging` access) | ||
| 6. Proxy not running → start it (or install daemon) | ||
| 7. Port conflicts → identify and offer to kill conflicting processes | ||
| 8. Stale symlinks → recreate | ||
|
|
||
| --- | ||
|
|
||
| ## Error Handling | ||
|
|
||
| | Condition | Action | | ||
| | -------------------- | ---------------------------------------------------------- | | ||
| | No GCP access | Print instructions to request access from team lead | | ||
| | Proxy port conflict | Identify process, offer to kill or suggest alternate port | | ||
| | DB connection failed | Check proxy → check credentials → check DATABASE_URL | | ||
| | App won't start | Check port conflicts, missing env vars, pending migrations | | ||
| | Condition | Action | | ||
| | --------------------------- | --------------------------------------------------------------------------------------------------- | | ||
| | No GCP access | Print instructions to request access from team lead | | ||
| | Wrong ADC quota project | Run `gcloud auth application-default set-quota-project f3-authentication-staging` and restart proxy | | ||
| | Proxy port conflict | Identify process, offer to kill or suggest alternate port | | ||
| | DB connection reset | Likely wrong ADC quota project — fix and restart proxy | | ||
| | DB connection failed | Check proxy → check credentials → check DATABASE_URL | | ||
| | No f3-me-app-staging access | Warn, skip me .env.local generation, suggest requesting access from tackle@f3nation.com | | ||
| | App won't start | Check port conflicts, missing env vars, pending migrations | | ||
|
taterhead247 marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| name: Deploy f3-me | ||
|
|
||
| on: | ||
| push: | ||
| tags: | ||
| - "me@*" | ||
|
|
||
| # Prevent concurrent deploys of the same tag | ||
| concurrency: | ||
| group: deploy-me-${{ github.ref_name }} | ||
| cancel-in-progress: false | ||
|
|
||
| env: | ||
| IMAGE_NAME: f3-me | ||
| STAGING_PROJECT: f3-me-app-staging | ||
| PROD_PROJECT: f3-me-app | ||
| REGION: us-east1 | ||
| SERVICE_NAME: f3-me | ||
| AR_REPO: cloud-run-builds | ||
|
|
||
| jobs: | ||
| # ── Gate: wait for CI to pass on this commit ── | ||
| ci-check: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Wait for CI to pass | ||
| uses: lewagon/wait-on-check-action@v1.3.4 | ||
| with: | ||
| ref: ${{ github.sha }} | ||
| repo-token: ${{ secrets.GITHUB_TOKEN }} | ||
| check-name: "test-coverage" | ||
| wait-interval: 15 | ||
| allowed-conclusions: success | ||
|
|
||
| # ── Build container image (once) ── | ||
| build: | ||
| needs: ci-check | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| id-token: write | ||
| outputs: | ||
| image: ${{ steps.meta.outputs.image }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Authenticate to GCP (staging project for AR) | ||
| uses: google-github-actions/auth@v2 | ||
| with: | ||
| workload_identity_provider: ${{ secrets.ME_WIF_PROVIDER }} | ||
| service_account: ${{ secrets.ME_WIF_SA_STAGING }} | ||
|
|
||
| - name: Set up Cloud SDK | ||
| uses: google-github-actions/setup-gcloud@v2 | ||
|
|
||
| - name: Authorize Docker to Artifact Registry | ||
| run: gcloud auth configure-docker ${{ env.REGION }}-docker.pkg.dev --quiet | ||
|
|
||
| - name: Extract tag version | ||
| id: meta | ||
| run: | | ||
| TAG="${GITHUB_REF_NAME}" # e.g. me@1.2.3 | ||
| VERSION="${TAG#me@}" # e.g. 1.2.3 | ||
| IMAGE="${REGION}-docker.pkg.dev/${STAGING_PROJECT}/${AR_REPO}/${IMAGE_NAME}:${VERSION}" | ||
| echo "image=${IMAGE}" >> "$GITHUB_OUTPUT" | ||
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Build and push Docker image | ||
| run: | | ||
| docker build \ | ||
| --file apps/me/Dockerfile \ | ||
| --tag "${{ steps.meta.outputs.image }}" \ | ||
| . | ||
| docker push "${{ steps.meta.outputs.image }}" | ||
|
|
||
| # ── Deploy to staging ── | ||
| deploy-staging: | ||
| needs: build | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| id-token: write | ||
| environment: | ||
| name: me-staging | ||
| url: https://staging.me.f3nation.com | ||
| steps: | ||
| - name: Authenticate to GCP (staging) | ||
| uses: google-github-actions/auth@v2 | ||
| with: | ||
| workload_identity_provider: ${{ secrets.ME_WIF_PROVIDER }} | ||
| service_account: ${{ secrets.ME_WIF_SA_STAGING }} | ||
|
|
||
| - name: Deploy to Cloud Run (staging) | ||
| uses: google-github-actions/deploy-cloudrun@v2 | ||
| with: | ||
| service: ${{ env.SERVICE_NAME }} | ||
| image: ${{ needs.build.outputs.image }} | ||
| region: ${{ env.REGION }} | ||
| project_id: ${{ env.STAGING_PROJECT }} | ||
| # Env vars are set via Cloud Run secrets / env config (see scripts/cloud-run-env.sh) | ||
|
|
||
| # ── Deploy to production (requires approval) ── | ||
| deploy-prod: | ||
| needs: [build, deploy-staging] | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| id-token: write | ||
| environment: | ||
| name: me-production | ||
| url: https://me.f3nation.com | ||
| steps: | ||
| - name: Authenticate to GCP (prod) | ||
| uses: google-github-actions/auth@v2 | ||
| with: | ||
| workload_identity_provider: ${{ secrets.ME_WIF_PROVIDER }} | ||
| service_account: ${{ secrets.ME_WIF_SA_PROD }} | ||
|
|
||
| - name: Set up Cloud SDK | ||
| uses: google-github-actions/setup-gcloud@v2 | ||
|
|
||
| - name: Authorize Docker to Artifact Registry | ||
| run: gcloud auth configure-docker ${{ env.REGION }}-docker.pkg.dev --quiet | ||
|
|
||
| - name: Promote image to prod Artifact Registry | ||
| run: | | ||
| STAGING_IMAGE="${{ needs.build.outputs.image }}" | ||
| PROD_IMAGE="${REGION}-docker.pkg.dev/${PROD_PROJECT}/${AR_REPO}/${IMAGE_NAME}:${STAGING_IMAGE##*:}" | ||
| docker pull "${STAGING_IMAGE}" | ||
| docker tag "${STAGING_IMAGE}" "${PROD_IMAGE}" | ||
| docker push "${PROD_IMAGE}" | ||
| echo "prod_image=${PROD_IMAGE}" >> "$GITHUB_ENV" | ||
|
|
||
| - name: Deploy to Cloud Run (prod) | ||
| uses: google-github-actions/deploy-cloudrun@v2 | ||
| with: | ||
| service: ${{ env.SERVICE_NAME }} | ||
| image: ${{ env.prod_image }} | ||
| region: ${{ env.REGION }} | ||
| project_id: ${{ env.PROD_PROJECT }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # Cloud Run deployment secrets — populate and run scripts/cloud-run-env.sh | ||
| # Copy to .env.cloud-run.prod or .env.cloud-run.staging and fill in values. | ||
|
|
||
| OAUTH_CLIENT_ID= | ||
| OAUTH_CLIENT_SECRET= | ||
| OAUTH_REDIRECT_URI= | ||
| SESSION_SECRET= | ||
| F3_API_KEY= | ||
| F3_API_BASE_URL= | ||
| GCS_BUCKET= | ||
| GCS_CREDENTIALS= | ||
| NEXT_PUBLIC_SITE_URL= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # ============================================================================= | ||
| # F3 Me — Local Development Environment (example) | ||
| # ============================================================================= | ||
| # Don't edit this file directly. Run `pnpm env:generate` to auto-generate | ||
| # apps/me/.env.local from GCP Secret Manager (project: f3-me-app-staging). | ||
| # | ||
| # If you need manual setup, copy this file to .env.local and fill in values. | ||
|
|
||
| # Auth (F3 SSO — points to local auth server on :3004) | ||
| OAUTH_CLIENT_ID=f3-me-local | ||
| OAUTH_CLIENT_SECRET=<from-gcp: f3-me-app-staging/oauth-client-secret> | ||
| OAUTH_REDIRECT_URI=http://localhost:3003/api/auth/callback | ||
| AUTH_PROVIDER_URL=http://localhost:3004 | ||
|
|
||
| # Session | ||
| SESSION_SECRET=<from-gcp: f3-me-app-staging/session-secret> | ||
|
|
||
| # F3 Nation API (local API on :3001) | ||
| F3_API_KEY=<from-gcp: f3-me-app-staging/f3-api-key> | ||
| F3_API_BASE_URL=http://localhost:3001/v1 | ||
|
|
||
| # Google Cloud Storage (avatar uploads) | ||
| GCS_BUCKET=f3-public-images-staging | ||
| GCS_CREDENTIALS=<from-gcp: f3-me-app-staging/gcs-credentials> | ||
|
|
||
| # App | ||
| NEXT_PUBLIC_SITE_URL=http://localhost:3003 | ||
| NODE_ENV=development |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is joinfold?