diff --git a/src/backend/src/services/auth/OIDCService.js b/src/backend/src/services/auth/OIDCService.js index 86e6ef98b..2a4daff03 100644 --- a/src/backend/src/services/auth/OIDCService.js +++ b/src/backend/src/services/auth/OIDCService.js @@ -20,8 +20,10 @@ import jwt from 'jsonwebtoken'; import { username_exists } from '../../helpers.js'; import { generate_identifier } from '../../util/identifier.js'; +import { OutcomeObject } from '../../util/outcomeutil.js'; import BaseService from '../BaseService.js'; import { DB_WRITE } from '../database/consts.js'; +import { CreatedUserOutcome } from './SignupService.js'; const GOOGLE_DISCOVERY_URL = 'https://accounts.google.com/.well-known/openid-configuration'; const GOOGLE_SCOPES = 'openid email profile'; @@ -215,17 +217,24 @@ export class OIDCService extends BaseService { * Create a new Puter user from OIDC claims and link the provider. Delegates to signup_create_new_user. */ async createUserFromOIDC (providerId, claims) { + if ( claims.email_verified === false ) { + // This should never happen; Google always sends verified emails. + const outcome = new OutcomeObject(new CreatedUserOutcome()); + return outcome.fail( + 'Provider did not verify this email address.', + 'oidc.email_not_verified', + ); + } const svc_signup = this.services.get('signup'); const outcome = await svc_signup.create_new_user({ username: await generate_random_username(), email: claims?.email ?? null, password: null, oidc_only: true, + assume_email_ownership: true, }); const { user_id } = outcome.infoObject; - console.log('user_id?', user_id); - if ( outcome.success ) - { + if ( outcome.success ) { await this.linkProviderToUser(user_id, providerId, claims.sub, null); } return outcome; diff --git a/src/backend/src/services/auth/SignupService.js b/src/backend/src/services/auth/SignupService.js index 53e5766c4..224a15068 100644 --- a/src/backend/src/services/auth/SignupService.js +++ b/src/backend/src/services/auth/SignupService.js @@ -23,6 +23,7 @@ export class SignupService extends BaseService { * @param {boolean} [params.temporary] - Whether the user is a temporary user. * @param {boolean} [params.oidc_only] - Whether the user created with OIDC * @param {boolean} [params.send_confirmation_code] - Whether to send a confirmation code instead of a token by email + * @param {boolean} [params.assume_email_ownership] - If true, set email_confirmed=1 without sending verification (e.g. OIDC provider already verified). * @param {string|null} params.username - The username of the user. * @param {string|null} params.email - The email of the user. * @param {string|null} params.password - The password of the user. @@ -33,6 +34,7 @@ export class SignupService extends BaseService { temporary = false, oidc_only = false, send_confirmation_code = false, + assume_email_ownership = false, username = null, email = null, password = null, @@ -171,12 +173,12 @@ export class SignupService extends BaseService { const insert_res = await db.write(`INSERT INTO user ( username, email, clean_email, password, uuid, referrer, - email_confirm_code, email_confirm_token, free_storage, + email_confirm_code, email_confirm_token, email_confirmed, free_storage, referred_by, audit_metadata, signup_ip, signup_ip_forwarded, signup_user_agent, signup_origin, signup_server ) VALUES - (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [ // username username, @@ -194,6 +196,8 @@ export class SignupService extends BaseService { email_confirm_code, // email_confirm_token email_confirm_token, + // email_confirmed (1 when assume_email_ownership, else 0) + assume_email_ownership ? 1 : 0, // free_storage this.global_config.storage_capacity, // referred_by @@ -244,10 +248,12 @@ export class SignupService extends BaseService { // }); } - if ( send_confirmation_code ) { - send_email_verification_code(email_confirm_code, email); - } else { - send_email_verification_token(email_confirm_token, email, user_uuid); + if ( ! assume_email_ownership ) { + if ( send_confirmation_code ) { + send_email_verification_code(email_confirm_code, email); + } else { + send_email_verification_token(email_confirm_token, email, user_uuid); + } } // TODO: This is where sending the referral code would