From 3652a4f11a347a96a71ba01c9dbb152894fc2cf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=86=E3=82=AF=E3=83=8B=E3=82=AB=E3=83=AB=E8=AB=8F?= =?UTF-8?q?=E8=A8=AA=E5=AD=90?= Date: Thu, 2 Dec 2021 01:27:34 +0900 Subject: [PATCH] =?UTF-8?q?=E9=80=A3=E7=B5=A1=E3=83=A1=E3=83=BC=E3=83=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Home/Contact.php | 147 ++++++++++++++++++ app/Mail/ContactNotifyMail.php | 23 +++ config/filesystems.php | 7 + config/mail.php | 5 + .../views/emails/notify/contact.blade.php | 10 ++ .../views/pages/site/contact-seiko.blade.php | 15 ++ resources/views/pages/site/contact.blade.php | 84 ++++++++++ routes/view/site.php | 2 + 8 files changed, 293 insertions(+) create mode 100644 app/Http/Controllers/Home/Contact.php create mode 100644 app/Mail/ContactNotifyMail.php create mode 100644 resources/views/emails/notify/contact.blade.php create mode 100644 resources/views/pages/site/contact-seiko.blade.php create mode 100644 resources/views/pages/site/contact.blade.php diff --git a/app/Http/Controllers/Home/Contact.php b/app/Http/Controllers/Home/Contact.php new file mode 100644 index 0000000..5db7e0d --- /dev/null +++ b/app/Http/Controllers/Home/Contact.php @@ -0,0 +1,147 @@ +field = [ + 'kenmei' => '', + 'adr' => '', + 'cat' => '', + 'cats' => [ + '' => '', + 'bugreport' => 'バグ報告したい', + 'chat' => 'チャットサービス(XMPP、IRC、Mumble)について聞きたい', + 'social' => 'SNSサービス(Pleroma、PeerTube)について聞きたい', + 'privfront' => '代替SNSフロントサービス(Nitter、Invidious、Librarian、Searx)について聞きたい', + 'storage' => 'ストレージサービス(Gitea、Nextcloud)について聞きたい', + 'otherserv' => '076外サービス(テク諏訪、076萌、URLoli、some.very.questionable.website、hozon.site、xmr.jp等)について聞きたい', + 'scam1' => 'DMCA報告したい', + 'scam2' => '営業したい', + 'scam3' => '法律について', + 'scam4' => '税金について', + 'scam5' => '無駄な話', + ], + 'bunsyo' => '', + 'gpg' => '', + 'ruleapply' => false, + ]; + } + + public function index (Request $r) { + if (isset($r->submit)) return $this->send($r); + return view('pages.site.contact', ['field' => $this->field, 'err' => []]); + } + + public function seiko () { + return view('pages.site.contact-seiko', ['field' => $this->field, 'suc' => ['メールを送りました!', '送信者様は連絡ルールを守ったら、24時間以内で返事します。']]); + } + + public function send (Request $r) { + $this->field['adr'] = $r->adr; + $this->field['kenmei'] = $r->kenmei; + $this->field['cat'] = $r->cat; + $this->field['gpg'] = !isset($r->gpg) || is_null($r->gpg) || $r->gpg == '' ? null : file_get_contents($r->file('gpg')); + $this->field['bunsyo'] = $r->bunsyo; + $this->field['ruleapply'] = isset($r->ruleapply); + + $err = []; + $gpg = null; + + // メールアドレス + if (!isset($this->field['adr']) || is_null($this->field['adr']) || $this->field['adr'] == '') $err[] = 'メールアドレスをご入力下さい。'; + else if (!filter_var($this->field['adr'], FILTER_VALIDATE_EMAIL)) $err[] = 'メールアドレスを正しくご入力下さい。'; + $filename = trim($this->field['adr']).'.key'; + + // 件名 + if (!isset($this->field['kenmei']) || is_null($this->field['kenmei']) || $this->field['kenmei'] == '') $err[] = '件名をご入力下さい。'; + if (str_contains($this->field['kenmei'], 'http://') || str_contains($this->field['kenmei'], 'https://')) $err[] = '件名でURLを入らないで下さい。'; + $this->field['bunsyo'] = trim($this->field['bunsyo']); + + // カテゴリ + if (!isset($this->field['cat']) || is_null($this->field['cat']) || $this->field['cat'] == '') $err[] = 'カテゴリをご選択下さい。'; + + // GPG + if (!isset($this->field['gpg']) || is_null($this->field['gpg']) || $this->field['gpg'] == '') $err[] = 'GPGをご選択下さい。'; + else { + $gpg = new \gnupg(); + $info = $gpg->import($this->field['gpg']); + $gpg->addencryptkey($info['fingerprint']); + Storage::disk('public')->put($filename, $this->field['gpg']); + $path = Storage::disk('public')->path($filename); + $verifygpg = explode("\n", $this->run('gpg --dry-run --import '.$path))[0]; + if (!str_contains($verifygpg, '処理数の合計: 1')) $err[] = $verifygpg; + } + + // 文章 + if (!isset($this->field['bunsyo']) || is_null($this->field['bunsyo']) || $this->field['bunsyo'] == '') $err[] = '文章をご入力下さい。'; + if (str_contains($this->field['bunsyo'], 'http://') || str_contains($this->field['bunsyo'], 'https://')) $err[] = '文章でURLを入らないで下さい。'; + $this->field['bunsyo'] = $gpg->encrypt(trim($this->field['bunsyo'])); + + // 連絡ルール + if (!$this->field['ruleapply']) $err[] = 'ルールを同意して下さい。'; + + if (!empty($err)) { + if (isset($this->field['gpg']) && !is_null($this->field['gpg']) && $this->field['gpg'] != '') Storage::disk('public')->delete($filename); + return view('pages.site.contact', ['field' => $this->field, 'err' => $err]); + } + + // カテゴリはDMCA報告、営業、税金、法律、又は無駄な話を選択したら、いつでも送信せず失敗します。 + if (str_contains($this->field['cat'], 'scam')) { + Storage::disk('public')->delete($filename); + return view('pages.site.contact', ['field' => $this->field, 'err' => ['送信に失敗しました。数時間後もう一回送信してみて下さい。']]); + } + + // メールを送る + try { + Mail::to(config('mail.from.address'))->send(new ContactNotifyMail($this->field, $filename)); + } catch (\Throwable $e) { + Storage::disk('public')->delete($filename); + Log::critical($e); + return view('pages.site.contact', ['field' => $this->field, 'err' => ['送信に失敗しました。数時間後もう一回送信してみて下さい。']]); + } + + Storage::disk('public')->delete($filename); + $this->field['kenmei'] = ''; + $this->field['adr'] = ''; + $this->field['cat'] = ''; + $this->field['bunsyo'] = ''; + $this->field['gpg'] = ''; + $this->field['ruleapply'] = false; + + return redirect('/contact/seiko'); + } + + function run ($bin, $command = '', $force = true) { + $stream = null; + $bin .= $force ? ' 2>&1' : ''; + + $descriptorSpec = array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w') + ); + + $process = proc_open($bin, $descriptorSpec, $pipes); + + if (is_resource($process)) { + fwrite($pipes[0], $command); + fclose($pipes[0]); + + $stream = stream_get_contents($pipes[1]); + fclose($pipes[1]); + + proc_close($process); + } + + return $stream; + } +} \ No newline at end of file diff --git a/app/Mail/ContactNotifyMail.php b/app/Mail/ContactNotifyMail.php new file mode 100644 index 0000000..2dd7de8 --- /dev/null +++ b/app/Mail/ContactNotifyMail.php @@ -0,0 +1,23 @@ +form = $form; + $this->file = $file; + } + + public function build () { + return $this->from($this->form['adr'])->subject($this->form['kenmei'])->markdown('emails.notify.contact', ['form' => $this->form])->attachFromStorage('public/'.$this->file); + } +} diff --git a/config/filesystems.php b/config/filesystems.php index 94c8112..2ea896a 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -55,6 +55,13 @@ return [ 'visibility' => 'public', ], + 'private' => [ + 'driver' => 'local', + 'root' => storage_path('app/private'), + 'url' => env('APP_URL').'/storage', + 'visibility' => 'private', + ], + 's3' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), diff --git a/config/mail.php b/config/mail.php index d67deb6..75f350e 100644 --- a/config/mail.php +++ b/config/mail.php @@ -41,6 +41,7 @@ return [ 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), + 'sendmail' => '/usr/sbin/sendmail -bs', 'timeout' => null, 'auth_mode' => null, ], @@ -87,6 +88,10 @@ return [ 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), 'name' => env('MAIL_FROM_NAME', 'Example'), ], + 'owner' => [ + 'address' => env('MAIL_OWNER_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_OWNER_NAME', 'Example'), + ], /* |-------------------------------------------------------------------------- diff --git a/resources/views/emails/notify/contact.blade.php b/resources/views/emails/notify/contact.blade.php new file mode 100644 index 0000000..ffcf7dd --- /dev/null +++ b/resources/views/emails/notify/contact.blade.php @@ -0,0 +1,10 @@ +@component('mail::message') +# {{ $form['kenmei'] }} + +{{ $form['adr'] }}
+{{ $form['cat'] }}

+ +□□□□□□□□□□□□□□□□□□□□

+ +{{ nl2br($form['bunsyo']) }} +@endcomponent diff --git a/resources/views/pages/site/contact-seiko.blade.php b/resources/views/pages/site/contact-seiko.blade.php new file mode 100644 index 0000000..df20af4 --- /dev/null +++ b/resources/views/pages/site/contact-seiko.blade.php @@ -0,0 +1,15 @@ +@extends('theme.'.env('THEME').'.site') + +@section('content') +
+
連絡フォーム
+
+ +
+
+ +@endsection diff --git a/resources/views/pages/site/contact.blade.php b/resources/views/pages/site/contact.blade.php new file mode 100644 index 0000000..ca77afc --- /dev/null +++ b/resources/views/pages/site/contact.blade.php @@ -0,0 +1,84 @@ +@extends('theme.'.env('THEME').'.site') + +@section('content') +
+
連絡フォーム
+
+ @if (!empty($err)) + + @endif + 私のGPGはこちらです→ suwako-gpg.key +
+
+ @csrf +
+
メールアドレス*
+
+ + 例)notwork@076.ne.jp +
+
+
+
件名*
+
+ + 例)アカウントの作成について +
+
+
+
カテゴリ*
+
+ + 注意)違うカテゴリを選択すると、メールアドレスをブロックされます!! +
+
+
+
GPG公開キー*
+
+
+
+
文章*
+
+
+
+
連絡ルール*
+
+

+ メールを送る前、ちゃんと下記のルールをお読み下さい。
+ ルールを守らないと、送信者様のメールアドレスをブラックリストに追加しますので、ご注意下さい。

+ + ① 件名及び文章にURLを追加できません、「http」や「https」等を消しても駄目です。
+   それの場合、送信者様のメールアドレスをブラックリストに追加します。
+ ② 正しいカテゴリを選択して下さい。
+   文章と件名とカテゴリが異なったら、送信者様のメールアドレスをブラックリストに追加します。
+ ③ 送るには、GPGパブリックキーは必須です。新規創造するには:「gpg --generate」
+ ④ 返事する時も、GPGで暗号されないと、
+   私は返事しません。私のパブリックキーはページの上で御座います。
+ ⑤ このフォームで、私のGPGパブリックキーを送ったら、返事しません。
+ ⑥ 私は返事しなければ、複数同じメールを送ると、送信者様のメールアドレスをブラックリストに追加します。
+ ⑦ 日本語でメールを送信して下さい。他の言語の場合、翻訳機で読めないと、返事しません。 +

+
+ + +
+
+
+
+
+
+
+
+
+ +@endsection diff --git a/routes/view/site.php b/routes/view/site.php index 271c480..aa3fe76 100644 --- a/routes/view/site.php +++ b/routes/view/site.php @@ -32,5 +32,7 @@ Route::group(['prefix' => 'video'], function () { Route::get('/memberlist', 'User\MemberList@index'); Route::get('/commentlist', 'Home\CommentList@index'); +Route::get('/contact/seiko', 'Home\Contact@seiko'); +Route::any('/contact', 'Home\Contact@index'); Route::get('/{slug}', 'Home\Index@page');