410 lines
16 KiB
PHP
410 lines
16 KiB
PHP
<!DOCTYPE html>
|
||
<html lang="en">
|
||
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||
|
||
<title>{{config('app.name')}}</title>
|
||
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
|
||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet">
|
||
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet" />
|
||
|
||
<style>
|
||
.page-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.main-content {
|
||
flex-grow: 1;
|
||
}
|
||
|
||
.footer {
|
||
flex-shrink: 0;
|
||
bottom: 0;
|
||
width: 100%;
|
||
text-align: center;
|
||
padding: 10px;
|
||
background-color: #f8f9fa;
|
||
}
|
||
|
||
.select2-container .select2-selection--single {
|
||
height: calc(1.5em + .75rem + 2px);
|
||
}
|
||
|
||
.select2-container--default .select2-selection--single .select2-selection__rendered {
|
||
line-height: calc(1.5em + .75rem);
|
||
}
|
||
|
||
.select2-container--default .select2-selection--single .select2-selection__arrow {
|
||
height: calc(1.5em + .75rem + 2px);
|
||
}
|
||
|
||
.input-group-text {
|
||
border-right: 0;
|
||
}
|
||
|
||
.select2-container {
|
||
border-left: 0;
|
||
}
|
||
|
||
.btn-save {
|
||
display: none;
|
||
}
|
||
|
||
#modalIframe {
|
||
width: 100%;
|
||
height: auto;
|
||
border: 1px solid #ced4da;
|
||
border-radius: .2rem;
|
||
padding: .375rem .75rem;
|
||
font-size: 1rem;
|
||
font-weight: 400;
|
||
line-height: 1.5;
|
||
color: #495057;
|
||
background-color: #fff;
|
||
background-clip: padding-box;
|
||
transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
|
||
}
|
||
|
||
#modalIframe:focus {
|
||
color: #495057;
|
||
background-color: #fff;
|
||
border-color: #80bdff;
|
||
outline: 0;
|
||
box-shadow: 0 0 0 .2rem rgba(0, 123, 255, .25);
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
<div class="page-container">
|
||
<div class="main-content">
|
||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||
<a class="navbar-brand" href="/">{{config('app.name')}}</a>
|
||
<div class="collapse navbar-collapse" id="navbarNav">
|
||
<ul class="navbar-nav mr-auto">
|
||
<li class="nav-item active">
|
||
<a class="nav-link" href="/">首页 <span class="sr-only">(current)</span></a>
|
||
</li>
|
||
<li class="nav-item">
|
||
<a class="nav-link" href="{{route('custom')}}">自定义域名</a>
|
||
</li>
|
||
</ul>
|
||
|
||
</div>
|
||
</nav>
|
||
|
||
<div class="container mt-3">
|
||
<div class="row">
|
||
|
||
<div class="col-5">
|
||
<div class="input-group mb-3">
|
||
<input type="text" class="form-control" id="inputText" value="{{$rand_prefix}}"
|
||
placeholder="Enter text">
|
||
<div class="input-group-append">
|
||
<span class="input-group-text">@</span>
|
||
</div>
|
||
<select class="form-control select2" id="selectOption" style="width: auto;">
|
||
@foreach($domain_list as $domain)
|
||
<option value="{{$domain}}">{{$domain}}</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
|
||
</div>
|
||
<div class="col-3">
|
||
<div class="input-group mb-3">
|
||
|
||
<button id="saveBtn" class="btn btn-primary btn-save" style="margin-right: 5px;"
|
||
type="button">修改邮箱</button>
|
||
<input type="hidden" value="" id="mailToCopy">
|
||
|
||
<button id="copyBtn" class="btn btn-info copy-btn" data-clipboard-target="#mailToCopy"
|
||
type="button">复制邮箱</button>
|
||
</div>
|
||
</div>
|
||
<div class="col-4">
|
||
<div class="input-group mb-3">
|
||
<input type="text" class="form-control alert alert-primary" id="auto-reload"
|
||
value="距离下次刷新还有10秒" disabled readonly>
|
||
</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="table-responsive">
|
||
<table class="table table-sm">
|
||
<thead>
|
||
<tr>
|
||
<th>发件人</th>
|
||
<th>标题</th>
|
||
<th>接收时间</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="mail-list">
|
||
<tr id="default-note">
|
||
<td colspan="4">
|
||
<div class="alert alert-primary" role="alert">
|
||
还没收到邮件哦
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<!-- 更多行 -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<footer class="footer">
|
||
<div class="container">
|
||
<span class="text-muted">版权所有 © 2023</span>
|
||
</div>
|
||
</footer>
|
||
</div>
|
||
|
||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
|
||
aria-hidden="true">
|
||
<div class="modal-dialog modal-xl" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
|
||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<!-- iframe 用于展示 API 返回的内容 -->
|
||
<iframe id="modalIframe"></iframe>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
|
||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"></script>
|
||
|
||
|
||
<script>
|
||
let block_prefix = JSON.parse('{!!json_encode($block_prefix)!!}');
|
||
let email = "";
|
||
let key = "{{$key}}";
|
||
let isRequestPending = false;
|
||
let countdown = 10;
|
||
|
||
let csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
|
||
|
||
|
||
function isValidDomain(domain) {
|
||
console.log(domain);
|
||
var pattern = /^(?!:\/\/)([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,11}$/;
|
||
return pattern.test(domain);
|
||
}
|
||
|
||
function dateFmt(dateString) {
|
||
let date = new Date(dateString);
|
||
|
||
let year = date.getFullYear();
|
||
let month = String(date.getMonth() + 1).padStart(2, '0'); // 月份是从0开始的
|
||
let day = String(date.getDate()).padStart(2, '0');
|
||
let hours = String(date.getHours()).padStart(2, '0');
|
||
let minutes = String(date.getMinutes()).padStart(2, '0');
|
||
let seconds = String(date.getSeconds()).padStart(2, '0');
|
||
|
||
let formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
return formattedDate;
|
||
}
|
||
|
||
|
||
function fetchMail() {
|
||
if (!isRequestPending) {
|
||
isRequestPending = true;
|
||
$.ajax({
|
||
url: '/mail', // 替换为你的后端接口
|
||
type: 'POST',
|
||
data: {
|
||
email: email,
|
||
key: key
|
||
},
|
||
success: function (response) {
|
||
key = response.data.new_key;
|
||
if (response.data.list.length > 0) {
|
||
$('#default-note').hide();
|
||
}
|
||
$.each(response.data.list, function (k, v) {
|
||
let temp_html = '<tr><td>' + v.from + '</td><td>' + v.title + '</td><td>' + dateFmt(v.received_at) + '</td><td><button class="btn btn-primary info-btn btn-sm" data-key="' + v.key + '" type="button">查看</button></td></tr>';
|
||
console.log(temp_html);
|
||
$('#default-note').parent().append(temp_html);
|
||
})
|
||
console.log('请求成功:', response);
|
||
// 在这里处理你的响应数据
|
||
},
|
||
error: function (xhr, status, error) {
|
||
console.error('请求失败:', error);
|
||
},
|
||
complete: function () {
|
||
isRequestPending = false;
|
||
}
|
||
});
|
||
} else {
|
||
console.log('上一个请求还未完成,跳过这次请求');
|
||
}
|
||
}
|
||
|
||
$(document).ready(function () {
|
||
|
||
$.ajaxSetup({
|
||
headers: {
|
||
'X-CSRF-TOKEN': csrfToken
|
||
}
|
||
});
|
||
|
||
$('[data-toggle="tooltip"]').tooltip();
|
||
$('.select2').select2({
|
||
tags: true
|
||
});
|
||
|
||
var clipboard = new ClipboardJS('.copy-btn');
|
||
clipboard.on('success', function (e) {
|
||
console.info('Action:', e.action);
|
||
console.info('Text:', e.text);
|
||
console.info('Trigger:', e.trigger);
|
||
|
||
e.clearSelection();
|
||
});
|
||
|
||
clipboard.on('error', function (e) {
|
||
console.error('Action:', e.action);
|
||
console.error('Trigger:', e.trigger);
|
||
});
|
||
|
||
$('#selectOption').on('change keyup', function () {
|
||
let domain = $('#selectOption').val();
|
||
if (!isValidDomain(domain)) {
|
||
$('#selectOption').addClass('is-invalid');
|
||
$('#domainInvalidFeedback').remove();
|
||
$('#selectOption').parent().append('<div id="domainInvalidFeedback" class="invalid-feedback">请输入一个合法的域名</div>');
|
||
$('#saveBtn').hide();
|
||
|
||
return false;
|
||
} else {
|
||
$('#selectOption').removeClass('is-invalid');
|
||
$('#domainInvalidFeedback').remove();
|
||
}
|
||
$('#saveBtn').show();
|
||
|
||
});
|
||
|
||
$('#inputText').on('change keyup', function () {
|
||
let textLength = $('#inputText').val().length;
|
||
if (textLength < 5 || textLength > 32) {
|
||
$('#inputText').addClass('is-invalid');
|
||
$('#perfixInvalidFeedback').remove();
|
||
$('#inputText').parent().append('<div id="perfixInvalidFeedback" class="invalid-feedback">长度必须在5到32位之间</div>');
|
||
$('#saveBtn').hide();
|
||
|
||
return false;
|
||
} else if (block_prefix.includes($('#inputText').val())) {
|
||
$('#inputText').addClass('is-invalid');
|
||
$('#perfixInvalidFeedback').remove();
|
||
$('#inputText').parent().append('<div id="perfixInvalidFeedback" class="invalid-feedback">该前缀不被允许</div>');
|
||
$('#saveBtn').hide();
|
||
return false;
|
||
|
||
}
|
||
else {
|
||
$('#inputText').removeClass('is-invalid');
|
||
$('#perfixInvalidFeedback').remove();
|
||
}
|
||
$('#saveBtn').show();
|
||
|
||
|
||
|
||
});
|
||
|
||
|
||
$('#saveBtn').click(function () {
|
||
email = $('#inputText').val() + "@" + $('#selectOption').val();
|
||
$('#mailToCopy').val(email);
|
||
console.log("邮箱:" + email);
|
||
$(this).hide();
|
||
});
|
||
|
||
$('#selectOption').val('{{$domain_list[0]}}');
|
||
$('#saveBtn').click();
|
||
|
||
var countdownTimer = setInterval(function () {
|
||
if (isRequestPending) {
|
||
$('#auto-reload').val('刷新中...');
|
||
return;
|
||
}
|
||
countdown--;
|
||
$('#auto-reload').val('距离下次刷新还有' + countdown + '秒');
|
||
if (countdown <= 0) {
|
||
fetchMail();
|
||
$('#auto-reload').val('刷新中...');
|
||
countdown = 11; // 重置为 11,因为下一次循环会立即减 1
|
||
|
||
}
|
||
}, 1000);
|
||
|
||
|
||
setInterval(function () {
|
||
$.get('/refresh-csrf', function (data) {
|
||
csrfToken = data.csrfToken
|
||
$.ajaxSetup({
|
||
headers: {
|
||
'X-CSRF-TOKEN': data.csrfToken
|
||
}
|
||
});
|
||
});
|
||
}, 1000 * 60);
|
||
|
||
$(document).on('click', '.info-btn', function () {
|
||
let key = $(this).data('key');
|
||
let apiUrl = '/mail/' + key;
|
||
|
||
// 发送 AJAX 请求获取 API 数据
|
||
$.ajax({
|
||
url: apiUrl,
|
||
method: 'POST',
|
||
success: function (response) {
|
||
try {
|
||
// 解码 base64
|
||
let decodedContent = atob(response.data.body);
|
||
let uint8Array = new Uint8Array(decodedContent.split("").map(char => char.charCodeAt(0)));
|
||
let text = new TextDecoder('utf-8').decode(uint8Array);
|
||
$('#modalIframe').attr('srcdoc', text);
|
||
|
||
let decodedTitle = atob(response.data.title);
|
||
uint8Array = new Uint8Array(decodedTitle.split("").map(char => char.charCodeAt(0)));
|
||
text = new TextDecoder('utf-8').decode(uint8Array);
|
||
|
||
$('#exampleModalLabel').text(text);
|
||
// 显示模态框
|
||
$('#myModal').modal('show');
|
||
} catch (e) {
|
||
console.error('Error parsing API response or decoding base64:', e);
|
||
}
|
||
},
|
||
error: function (error) {
|
||
console.error('Error fetching API data:', error);
|
||
}
|
||
});
|
||
});
|
||
|
||
});
|
||
</script>
|
||
</body>
|
||
|
||
</html> |