Concierge

 view release on metacpan or  search on metacpan

lib/Concierge/Desk/User.pm  view on Meta::CPAN


# =============================================================================
# IDENTITY & METADATA - Direct scalar returns
# =============================================================================

sub user_id ($self) {
    return $self->{user_id};
}

sub user_key ($self) {
    return $self->{user_key};
}

sub session_id ($self) {
    return $self->{session_id};  # undef if visitor/no session
}

# =============================================================================
# STATUS METHODS - Direct boolean returns
# =============================================================================

sub is_visitor ($self) {
    return $self->{is_visitor} ? 1 : 0;
}

sub is_guest ($self) {
    return $self->{is_guest} ? 1 : 0;
}

sub is_logged_in ($self) {
    return $self->{is_logged_in} ? 1 : 0;
}

# =============================================================================
# SESSION ACCESS - Returns session object
# =============================================================================

sub session ($self) {
    return $self->{session};  # undef if no session (visitor)
}

# Internal: is this object's session still live on the backend right now?
# Deliberately a fresh backend check via the _session_valid closure, not a
# check of cached in-memory state -- a *different* Concierge::Desk::User
# instance for the same identity (e.g. from a second restore_user() call)
# can still hold a populated (but now stale) session field after this
# object's own logout() ran, and cached session status wouldn't catch that.
sub _session_ok ($self) {
    return 0 unless $self->{_session_valid};
    my $result = $self->{_session_valid}->();
    return $result->{success} ? 1 : 0;
}

sub get_session_data ($self) {
    return undef unless $self->{session};
    return undef unless $self->_session_ok;
    my $result = $self->{session}->get_data();
    return $result->{value} // {};
}

sub update_session_data ($self, $updates) {
    return undef unless $self->{session};
    return undef unless $self->_session_ok;

    my $result = $self->{session}->get_data();
    my $current = $result->{value} // {};

    # Merge updates into current data
    for my $key (keys %$updates) {
        $current->{$key} = $updates->{$key};
    }

    $self->{session}->set_data($current);
    $self->{session}->save();

    return 1;
}

# =============================================================================
# USER DATA - Quick access from memory snapshot
# =============================================================================

sub moniker ($self) {
    return $self->{user_data}{moniker};
}

sub email ($self) {
    return $self->{user_data}{email};
}

sub user_status ($self) {
    return $self->{user_data}{user_status};
}

sub access_level ($self) {
    return $self->{user_data}{access_level};
}

sub get_user_field ($self, $field) {
    return $self->{user_data}{$field};
}

# =============================================================================
# USER DATA - Backend operations via closures
# =============================================================================

sub refresh_user_data ($self) {
    # Fetch fresh data from backend, update memory snapshot
    return undef unless $self->{_get_user_data};
    return undef unless $self->_session_ok;

    my $result = $self->{_get_user_data}->();
    return undef unless $result->{success};

    $self->{user_data} = $result->{user};
    return 1;
}

sub update_user_data ($self, $updates) {
    # Update backend AND memory snapshot
    return undef unless $self->{_update_user_data};
    return undef unless $self->_session_ok;

    my $result = $self->{_update_user_data}->($updates);
    return undef unless $result->{success};

    # Update memory snapshot with new values
    for my $field (keys %$updates) {
        $self->{user_data}{$field} = $updates->{$field};
    }

    return 1;
}

# =============================================================================
# PASSWORD & LOGOUT - Mirror operations via closures
# =============================================================================

sub verify_password ($self, $password) {
    return undef unless $self->{_verify_password};
    return undef unless $self->_session_ok;

    my $result = $self->{_verify_password}->($password);
    return $result->{success} ? 1 : 0;
}

sub reset_password ($self, $new_password) {
    return undef unless $self->{_reset_password};
    return undef unless $self->_session_ok;

    my $result = $self->{_reset_password}->($new_password);
    return $result->{success} ? 1 : undef;
}

sub logout ($self) {
    return undef unless $self->{_logout};

    my $result = $self->{_logout}->();
    return undef unless $result->{success};

    # Concierge has already done the real work (session deleted, user_key
    # mapping removed). Clean up this object in place so any reference to
    # it the application is still holding degrades to visitor-equivalent
    # status rather than silently retaining backend-write capability or
    # reporting stale identity/session state. user_id and user_key are
    # left intact -- they're inert identity strings, not capabilities.
    delete $self->{$_} for qw(
        _get_user_data _update_user_data
        _verify_password _reset_password _logout _session_valid
        session session_id user_data
    );
    $self->{is_logged_in} = 0;
    $self->{is_guest}     = 0;
    $self->{is_visitor}   = 1;

    return 1;
}

1;



( run in 0.703 second using v1.01-cache-2.11-cpan-364913b4093 )