Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copy to .env and fill in real values for local development. .env is gitignored --
# never commit real values here or in .env itself.

# Google OAuth client id used by the login/signup and password-reset OAuth flows
# (see the comment on google_client_id in _config.yml for why this isn't just
# hardcoded there). Ask a maintainer for the real value -- it's the same one
# production uses, stored as a GitHub Actions repository secret for CI.
GOOGLE_CLIENT_ID=
10 changes: 10 additions & 0 deletions .github/workflows/jekyll-gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ jobs:

echo "baseurl: \"$BASEURL\"" > _config.override.yml

# google_client_id must never be committed to the repo (see the comment on
# it in _config.yml) -- injected here from a repository secret instead,
# into the same gitignored override file used for baseurl above. Requires
# a repo admin to add the GOOGLE_CLIENT_ID secret in Settings > Secrets and
# variables > Actions; the site builds fine without it, the Google sign-in
# button just won't render until it's set.
if [ -n "${{ secrets.GOOGLE_CLIENT_ID }}" ]; then
echo "google_client_id: \"${{ secrets.GOOGLE_CLIENT_ID }}\"" >> _config.override.yml
fi

- name: Generate dynamic SASS imports
run: |
source venv/bin/activate
Expand Down
6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -480,11 +480,13 @@ bundle-install:
fi

# Start Jekyll server (no auto-watch, we control rebuilds manually)
# Supports optional _config.local.yml override for local settings (e.g. baseurl)
# Supports optional _config.local.yml override for local settings (e.g. baseurl,
# google_client_id -- see scripts/generate_local_config_override.sh and .env.example)
jekyll-serve: bundle-install
@touch /tmp/.notebook_watch_marker
@rm -f /tmp/.jekyll_rebuild_trigger
bundle exec jekyll serve -H $(HOST) -P $(PORT) --no-watch > $(LOG_FILE) 2>&1 &
@./scripts/generate_local_config_override.sh
bundle exec jekyll serve -H $(HOST) -P $(PORT) --no-watch --config _config.yml,_config.local.yml > $(LOG_FILE) 2>&1 &
@make wait-for-server

# Common server wait logic
Expand Down
11 changes: 10 additions & 1 deletion _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,17 @@ description: "Class of 2026"
owner_name: Open Coding Society
github_username: open-coding-society
github_repo: "pages"
baseurl: ""
baseurl: ""
future: true
# google_client_id is intentionally NOT set here -- per John Mortensen's review on
# PR #1371, it must not be committed to the public repo. It's injected at build time
# into a gitignored override config instead: locally into _config.local.yml via
# scripts/generate_local_config_override.sh reading .env (see .env.example), in CI
# into _config.override.yml via the "Compute and apply baseurl" step in
# .github/workflows/jekyll-gh-pages.yml (which already generates that file for
# baseurl) reading a repository secret. Either way, assets/js/api/config.js's
# GOOGLE_CLIENT_ID and login.md's #g_id_onload data-client_id pull the same
# google_client_id key via Liquid -- one source of truth, just never a committed one.

# Exclude from Jekyll watch - these are processed by our conversion scripts
# This prevents double-regeneration when saving notebooks/docx files
Expand Down
31 changes: 3 additions & 28 deletions _layouts/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,8 @@ <h2 class="text-xl font-semibold mb-6">Personal Information</h2>

<!-- Password Change -->
<div>
<label for="password" class="block text-sm font-medium text-gray-300 mb-1">New
Password</label>
<input type="password" id="password" name="password"
class="w-full px-4 py-2 rounded-lg border border-gray-600 bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-indigo-500"
placeholder="Enter new password" onchange="checkForChanges()" autocomplete="new-password">
<label class="block text-sm font-medium text-gray-300 mb-1">Password</label>
<a href="{{ site.baseurl }}/support?topic=reset" class="text-sm text-indigo-400 hover:text-indigo-300 inline-block">Forgot your password?</a>
</div>
</div>
</div>
Expand Down Expand Up @@ -1317,7 +1314,6 @@ <h4 class="text-red-400 font-semibold mb-1">Selection Failed</h4>
const uidInput = document.getElementById("uidChangeInput");
const emailInput = document.getElementById("emailChangeInput");
const sidInput = document.getElementById("sidChangeInput");
const passwordInput = document.getElementById("password");
const kasmInput = document.getElementById("kasmChangeInput");
const schoolInput = document.getElementById("schoolChangeInput");

Expand All @@ -1326,7 +1322,6 @@ <h4 class="text-red-400 font-semibold mb-1">Selection Failed</h4>
const uid = uidInput.value.trim();
const email = emailInput.value.trim();
const sid = sidInput.value.trim();
const password = passwordInput.value.trim();
const kasmServerNeeded = kasmInput ? kasmInput.checked : undefined;
const school = schoolInput.value;

Expand Down Expand Up @@ -1422,26 +1417,6 @@ <h4 class="text-red-400 font-semibold mb-1">Selection Failed</h4>
}
}

// save password (both backends, logs out)
if (password) {
try {
await Promise.all([
putUpdate({
URL: pythonURI + "/api/user",
body: { password },
message: 'password-message'
}),
postUpdate({
URL: javaURI + "/api/person/update",
body: { password }
})
]);
needsLogout = true;
} catch (e) {
console.error("error saving password:", e.message);
}
}

// save kasm server status (both backends)
if (
typeof kasmServerNeeded !== "undefined" &&
Expand Down Expand Up @@ -1511,7 +1486,7 @@ <h4 class="text-red-400 font-semibold mb-1">Selection Failed</h4>

// handle reload or logout if needed
if (needsLogout) {
alert("you updated your github id or password, so you will be logged out. remember your new credentials!");
alert("you updated your github id, so you will be logged out. remember your new credentials!");
window.location.href = '{{site.baseurl}}';
} else if (needsReload) {
window.location.reload();
Expand Down
5 changes: 5 additions & 0 deletions _sass/open-coding/elements/forms/passwordvalidation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ $validation-focus-color: #6366f1 !default;
box-shadow: 0 0 0 1px $validation-error-color !important;
}

.password-length {
border-color: $validation-error-color !important;
box-shadow: 0 0 0 1px $validation-error-color !important;
}

// Validation message styling
.validation-message {
font-size: 0.8rem;
Expand Down
4 changes: 4 additions & 0 deletions assets/js/api/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
javaURI = "https://spring.opencodingsociety.com";
}

// Shared across the signup, login, and password-reset OAuth flows (login.md,
// support.md) so the client_id only needs updating in one place.
export const GOOGLE_CLIENT_ID = "{{ site.google_client_id }}";

export var javaWebSocketURI;
if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
javaWebSocketURI = "http://localhost:8589";
Expand Down
8 changes: 5 additions & 3 deletions navigation/authentication/login.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ show_reading_time: false
<button type="submit" class="large primary submit-button">Login</button>
</p>
<p id="message" style="color: red;"></p>
<p style="text-align: center;">
<a href="{{site.baseurl}}/support?topic=reset">Forgot your password?</a>
</p>
</form>
</div>
<div class="signup-card">
Expand All @@ -38,7 +41,7 @@ show_reading_time: false
<br><strong>You must use an email ending in @stu.powayusd.com or @powayusd.com</strong>
</p>
<div id="g_id_onload"
data-client_id="65827797404-ccjleg7jg4g2an8ddpmhnlca4ii2gk8q.apps.googleusercontent.com"
data-client_id="{{ site.google_client_id }}"
data-callback="handleGoogleSignIn"
data-auto_prompt="false">
</div>
Expand Down Expand Up @@ -120,12 +123,11 @@ show_reading_time: false
</div>

<script type="module">
import { login, pythonURI, javaURI, fetchOptions } from '{{site.baseurl}}/assets/js/api/config.js';
import { login, pythonURI, javaURI, fetchOptions, GOOGLE_CLIENT_ID } from '{{site.baseurl}}/assets/js/api/config.js';

let signupFormData = {};
let verifiedSchoolEmail = null;
let validationTimeout = null;
const GOOGLE_CLIENT_ID = "65827797404-ccjleg7jg4g2an8ddpmhnlca4ii2gk8q.apps.googleusercontent.com";

// Password validation with debouncing (1.5 second delay)
function validatePasswordsDebounced() {
Expand Down
Loading