Skip to content

Technical Marketplace Login

Daniel Neto edited this page Nov 11, 2026 · 1 revision

Technical: Marketplace login and session isolation

This page describes the PHP Marketplace in the separate youphptube.com repository, not the independently configured AVideo LoginFacebook and LoginGoogle plugins.

Provider configuration

The Marketplace reads the Facebook, Google and optional GitHub IDs and secrets from its deployment's marketplace/configuration.php. Keep secrets out of commits, reports, browser screenshots and command-line arguments. Change the ID and its matching secret together. Preserve independently configured environments and unrelated providers.

Each environment needs an exact registered callback, including the query string:

https://your-domain/marketplace/objects/login.json.php?type=Facebook
https://your-domain/marketplace/objects/login.json.php?type=Google
https://your-domain/marketplace/objects/login.json.php?type=GitHub

Include an installation subdirectory and non-default port when used. OAuth starts on the configured canonical origin because its state belongs to that origin's PHP session. A Google redirect registration change can take time to propagate.

For Facebook, configure the Facebook Login use case with email and public_profile, client and web OAuth enabled, HTTPS and strict redirect matching. Set the website, app domains, privacy policy, data-deletion instructions, category and an approved icon. Check the actual publishing requirements in Meta, including the connected business's verification and data-handling questions. Development mode tests by an app administrator do not prove that public users can sign in.

The Marketplace's vendored Facebook adapter uses Graph API v26.0, requests only the profile fields needed for login, and adds appsecret_proof when requesting the profile after the token exchange. Preserve those changes during library updates. Production must run the same authentication fixes as the tested checkout.

For GitHub, use the YPT-ME organization-owned apps AVideo Marketplace for production and AVideo Marketplace (Local) for development, with read:user user:email. Register the exact callback for each environment, including installation path and query string. Although multiple callbacks are supported, the 2026-11-03 cancellation test used the first registered callback instead of the requested local one; separate apps avoid crossing environments. Disable Device Flow and wildcard matching; leave token expiration enabled. Set production login.GitHub.id/key defaults before the existing local branch and override them in the branch that sets vlu.me:444. The button appears only when both values are present. An extra local URI remains registered in the production app from the initial setup; development uses its dedicated app.

The vendored GitHub adapter always reads /user/emails, even when /user contains a public address. It prefers primary verified then another verified address; unavailable or unverified email never proves ownership. Its API headers include User-Agent: AVideo-Marketplace and Accept: application/vnd.github+json. These edits are marked Marketplace patch: and do not upgrade Hybridauth.

Session bootstrap

marketplace/objects/User.php loads MarketplaceSession.php and configures the session before the deployment configuration calls session_start().

  • Cookie name: AVIDEO_MARKETPLACE_SESSION.
  • Path: the path of the canonical Marketplace URL, with a trailing slash.
  • Domain: host-only, without a parent-domain attribute.
  • HttpOnly enabled, SameSite=Lax, and Secure for canonical HTTPS URLs.
  • Cookie-only session IDs and PHP strict session mode enabled.

For /marketplace/, the cookie path is /marketplace/. An installation at /youphptube.com/marketplace/ uses that complete path. CDN, account and wallet pages inside the Marketplace share this session. Already active sessions are left intact when another Marketplace component loads the class again.

Using the generic root-path PHPSESSID can collide with another application's host-only or parent-domain cookie. The OAuth callback can save a logged-in session while the landing request reads a different empty session. The symptom is a successful provider login and account-resolution log followed by Sign in on the landing page. The dedicated cookie removes that ambiguity without deleting other applications' cookies or session files. Existing Marketplace sessions need one new sign-in after this update.

Account resolution

UserObj::resolveExternalLogin() first preserves an account's existing provider identifier. Otherwise, only a provider-verified email may link to an existing account. Unverified email matches are refused; new unverified accounts are flagged. Do not rewrite existing identifiers, tutorials IDs or purchases to repair a session problem, and do not merge legacy duplicate accounts as a login fix.

New GitHub identifiers and usernames are prefixed with GitHub_ to avoid colliding with Facebook's numeric ids. Google and Facebook keep their existing identifiers. GitHub's full name is split into first word and remaining surname, falling back to its login if the name is empty.

Verification

Run PHP syntax checks and python tests/test_marketplace_sessions.py /path/to/php. The isolated test starts a loopback PHP fixture server with a temporary session store, sends conflicting legacy cookies, checks fixation rejection, carries OAuth state through session regeneration and verifies the logged-in landing request. It covers both deployment paths without a database or real credentials.

Run php tests/test_marketplace_github.php for isolated verified-email selection, public/unverified addresses, email endpoint failures, request headers, login-name fallback and provider visibility/order. In Chrome, compare Google and GitHub account numbers for the same verified email, test cancellation and inspect the modal at desktop and 390px widths. Existing legacy duplicate rows can retain different numbers; report that condition without merging accounts.

Then test Facebook in Chrome, verify Sign out / Account #..., reload, sign out, and repeat with Google. Check cookie metadata without printing cookie values. Correlate the test times with Marketplace Facebook login, Marketplace Google login and Marketplace login log entries. A linked-account log or an HTTP 200 alone is insufficient evidence of a persistent browser login.

Validation on 2026-11-03: the isolated regression passed locally and on the Marketplace server. Facebook and Google sign-ins were exercised in Chrome on the local installation and streamphp.com, including reload and sign-out between providers. Existing account identifiers were preserved. Authentication fixes were deployed in commit 337baf6; the approved app icon was added in cacf54b.

GitHub was subsequently validated in the local checkout on the same date: desktop and 390px modal layouts passed, the Local app returned a persistent account #1 session, and cancelling reopened the friendly error modal. Google returned account #2. A read-only comparison confirmed both old rows already had the same email, which GitHub marks primary and verified; the existing identifier and oldest-verified-email rules were preserved. No runtime PHP diagnostics were found in the changed login files. These changes were subsequently committed in ab706b4 and deployed to production on 2026-11-03. Production Google, GitHub and Facebook sign-ins returned persistent accounts #2, #1 and #1, respectively; legacy duplicate account resolution was preserved. No new runtime PHP errors or OAuth failures were found after recovering the permissions incident below.

The shared url_get_contents() diagnostic no longer logs the requested URL or an exception message that may repeat it: tutorials sign-in URLs can contain credentials. This change does not remove old log entries. When extracting logs, select only the required login events and redact credentials before displaying.

Updating a deployment with a tracked configuration

This repository still tracks marketplace/configuration.php; adding that path to .gitignore does not protect it from a pull. Compare the live file, its HEAD base and the incoming version privately, and preserve deployment-specific values. Keep configuration backups outside the document root in a root-only directory; never display a configuration diff containing credentials.

For the 2026-11-03 update to ab706b4, the server-only Facebook settings already matched the incoming version. The reviewed configuration added GitHub defaults and its local override and preserved every other byte. It exactly matched the incoming Git blob. It was installed with an atomic rename preserving ownership and permissions, staged as that reviewed blob, then pulled with fast-forward only. A second ordinary pull returned Already up to date; tracked files were clean. This staging procedure depends on the reviewed file matching the incoming blob and must not discard different production settings.

Keep the restrictive backup umask separate from Git checkout operations. During this deployment, a backup umask of 077 was mistakenly inherited by Git. New files became 0600/0700, causing HTTP 500 responses because Apache could not read them. Previous file modes were restored (new ordinary files use 0644), and HTTP 200 recovered at approximately 14:07:48 America/Sao_Paulo, after the first observed 500 at 14:06:32. Apache was not restarted. Git operations now run with umask 022; validate web-server readability as well as PHP syntax before considering a deployment healthy.

The server currently runs PHP 8.5. Its unchanged legacy Hybridauth adapter has implicit-nullable parameter deprecations. The GitHub fixture's strict handler turns class-loading deprecations into exceptions. Preloading the adapter before installing that handler allowed the seven runtime fixtures to pass without changing the library:

php -r 'error_reporting(E_ALL & ~E_DEPRECATED); require "marketplace/hybridauth/autoload.php"; class_exists("Hybridauth\\Provider\\GitHub"); require "tests/test_marketplace_github.php";'

The isolated session regression also passed on the server. These fixtures do not exercise payments or replace browser sign-in and session-persistence tests.

Clone this wiki locally