wd ();
use Convos::Core;
use Convos::Util;
use File::HomeDir ();
use Mojo::File 'path';
use Mojo::JSON qw(false true);
use Mojo::Util;
$ENV{CONVOS_PLUGINS} //= 'Convos::Plugin::Paste';
our $VERSION
atic->file('convos-api.json');
die "Could not find convos-api.json in static=@{$self->static->paths}, home=@{[$self->home]})"
unless $file;
return Mojo::JSON::decode_json($file->slurp);
};
ha
fig = $self->config;
if (my $path = $ENV{MOJO_CONFIG}) {
$config = $path =~ /\.json$/ ? $self->plugin('JSONConfig') : $self->plugin('Config');
}
$config->{backend} ||= $ENV{CONVOS_BACKEND}
Fcntl ':flock';
use File::ReadBackwards;
use Mojo::File;
use Mojo::IOLoop::ForkCall ();
use Mojo::JSON;
use Mojo::Util;
use Symbol;
use Time::Piece;
use Time::Seconds;
use constant FLAG_OFFSET =>
nection.json');
next unless -e $settings;
push @connections, Mojo::JSON::decode_json($settings->slurp);
delete $connections[-1]{state}; # should not be stored in connection.json
}
= {};
my $err = '';
if (-e $storage_file) {
eval { $data = Mojo::JSON::decode_json($storage_file->slurp); };
$err = $@ || 'Unknown error' unless $data;
}
return nex
sub TO_JSON {
my ($self, $persist) = @_;
my %json = map { ($_, $self->$_) } qw(frozen is_private name last_active last_read topic);
$json{connection_id} = $self->connection->id;
$json{dialog_
id} = $self->id;
$json{password} = $self->password if $persist;
$json{stash} = $self->stash;
$json{unread} = $self->{unread} || 0;
return \%json;
}
1;
=encoding utf8
il');
return $c->app->core->get_user({email => $email});
}
sub _unauthorized {
shift->render(json => E('Need to log in first.'), status => 401);
}
1;
=encoding utf8
=head1 NAME
Convos::Plugin
ge Convos::Plugin::ShareDialog;
use Mojo::Base 'Convos::Plugin';
use Convos::Util 'E';
use Mojo::JSON qw(false true);
use Mojo::Util qw(sha1_sum steady_time);
sub register {
my ($self, $app, $conf
->share_dialog->load() and $app->share_dialog->save()
# for loading/saving data using $self->TO_JSON()
$self->add_backend_helpers($app);
$app->helper('share_dialog.shared' => sub { $self->{share
es => $messages, end => @$messages < $query{limit} ? true : false);
$c->respond_to(
json => \%res,
any => sub { shift->render('plugin/share_dialog/messages', %res) }
);
package Convos::Plugin::Auth;
use Mojo::Base 'Mojolicious::Plugin';
use Mojo::JSON qw(false true);
use Mojo::Util;
sub register {
my ($self, $app, $config) = @_;
$self->{invite_code} = $config-
sage => $message // ''});
return $self;
}
sub uri { Mojo::Path->new(sprintf '%s/%s/connection.json', $_[0]->user->email, $_[0]->id) }
sub wanted_state {
my ($self, $state, $cb) = @_;
return $
}
sub TO_JSON {
my ($self, $persist) = @_;
my $url = $self->url;
my %json = map { ($_, $self->$_) } qw(name protocol wanted_state);
$json{connection_id} = $self->id;
$json{on_connec
n_connect_commands;
$json{url} = $url->to_unsafe_string;
if (!$persist and $url->query->param('forced')) {
my $password = $url->password // '';
$json{url} =~ s!:$password\
Mojo::Path->new(sprintf '%s.json', Mojo::Util::decamelize($1));
};
sub add_backend_helpers {
my ($self, $app) = @_;
my $prefix = $self->uri->[0];
$prefix =~ s!\.json$!!;
$app->log->debug("Ad
ection);
return $connection;
};
sub get {
my ($self, $args, $cb) = @_;
my $res = $self->TO_JSON;
Mojo::IOLoop->delay(
sub {
my ($delay) = @_;
return $delay->pass unless $args
$_[0]->{password} = $_[0]->_bcrypt($_[1]);
$_[0];
}
sub uri { Mojo::Path->new(sprintf '%s/user.json', $_[0]->email) }
sub validate_password {
my ($self, $plain) = @_;
return 0 unless $self->p
sub TO_JSON {
my ($self, $persist) = @_;
$self->{registered} ||= Mojo::Date->new->to_datetime;
my $json = {map { ($_, $self->{$_} // '') } qw(email password registered)};
delete $json->{passw
s::Controller::Dialog;
use Mojo::Base 'Mojolicious::Controller';
use Convos::Util 'E';
use Mojo::JSON qw(false true);
sub last_read {
my $self = shift->openapi->valid_input or return;
my $d
nection';
no warnings 'utf8';
use Convos::Util qw(next_tick DEBUG);
use Mojo::IRC::UA;
use Mojo::JSON;
use Parse::IRC ();
use Time::HiRes 'time';
use constant MAX_BULK_MESSAGE_SIZE => $ENV{CONVOS_MA
$self->_irc->server) if DEBUG;
$self->emit(state => frozen => $_->frozen('Not connected.')->TO_JSON)
for grep { !$_->frozen } @{$self->dialogs};
$self->{steal_nick_tid} //= $self->_steal_nick
ost = $self->url->host;
my $store = $self->_room_cache->{$host} ||= {rooms => {}, end => Mojo::JSON->false};
my ($generate, @rooms, @by_topic);
if ($match) {
$generate = sub {
$match
');
if (!$self->backend->user) {
return $self->stash(status => 401)
->respond_to(json => {json => {errors => []}}, any => {text => ''});
}
if (my $link = $self->app->_link_cache->get(
$self->res->headers->header('X-Cached' => 1); # for testing
return $self->respond_to(json => {json => $link}, any => {text => $link->html});
}
$self->delay(
sub { $self->linkembedder
;
$self->res->headers->cache_control('max-age=600');
}
$self->respond_to(json => {json => $link}, any => {text => $link->html});
},
);
}
1;
=encoding utf8
=head1 NAME
Co
}
sub TO_JSON {
my ($self, $private) = @_;
my $json = {content => $self->content, created_at => $self->created_at};
$json->{author} = $self->user->email if $private;
return $json;
}
1;
=
rized;
my $json = $self->req->json;
my $url = $self->_validate_url($json->{url})
or return $self->render(openapi => E('Missing "host" in URL'), status => 400);
my $name = $json->{name} || $
onnection = $user->connection({
name => $name,
on_connect_commands => $json->{on_connect_commands} || [],
protocol => $url->scheme,
});
$connection-
my $user = $self->backend->user or return $self->unauthorized;
my $json = $self->req->json;
my $state = $json->{wanted_state} || '';
my $connection;
eval {
$connection = $user->g
:Events;
use Mojo::Base 'Mojolicious::Controller';
use Convos::Util qw(DEBUG E);
use Mojo::JSON 'encode_json';
use Mojo::Util;
use constant INACTIVE_TIMEOUT => $ENV{CONVOS_INACTIVE_TIMEOUT} || 30;
me)->to_datetime;
warn "[Convos::Controller::Events] >>> @{[encode_json $data]}\n" if DEBUG == 2;
$self->send({json => {%$data, ts => $ts, event => $event}});
}
);
$self->inactivi
sh\n" if DEBUG == 2;
$backend->unsubscribe("user:$uid" => $cb);
}
);
$self->on(
json => sub {
my ($self, $data) = @_;
my $method = sprintf '_event_%s', $data->{method} ||
shift->openapi->valid_input or return;
$self->delay(
sub { $self->auth->login($self->req->json, shift->begin) },
sub {
my ($delay, $err, $user) = @_;
return $self->render(opena
ift->openapi->valid_input or return;
$self->delay(
sub { $self->auth->register($self->req->json, shift->begin) },
sub {
my ($delay, $err, $user) = @_;
return $self->render(opena
id_input or return;
my $json = $self->req->json;
my $user = $self->backend->user or return $self->unauthorized;
# TODO: Add support for changing email
unless (%$json) {
return $self->ren
package Convos::Util;
use Mojo::Base 'Exporter';
use JSON::Validator::Error;
use Mojo::File;
use Mojo::Util 'monkey_patch';
use constant DEBUG => $ENV{CONVOS_DEBUG} || 0;
our @EXPORT_OK = qw(DEBUG E
E {
my ($msg, $path) = @_;
$msg =~ s! at \S+.*!!s;
$msg =~ s!:.*!.!s;
return {errors => [JSON::Validator::Error->new($path, $msg)]};
}
sub has_many {
my $class = caller;
my ($accessor, $