Commit d9fa4538 authored by Antonio.Suerte's avatar Antonio.Suerte

Payment API Major Revision

parent 013f79c8
This diff is collapsed.
...@@ -161,6 +161,13 @@ input[type="text"], input[type="password"], input[type="number"], input[type="em ...@@ -161,6 +161,13 @@ input[type="text"], input[type="password"], input[type="number"], input[type="em
margin:0 0 5px 0; margin:0 0 5px 0;
padding:10px; padding:10px;
} }
input:disabled{
cursor: default;
background-color: #e8e8e8;
border: solid 1px #aaa;
margin:0 0 5px 0;
padding:10px;
}
input[type="button"], input[type="reset"], input[type="submit"] { input[type="button"], input[type="reset"], input[type="submit"] {
-webkit-appearance: button; -webkit-appearance: button;
cursor: pointer; cursor: pointer;
...@@ -178,6 +185,7 @@ input.btn { ...@@ -178,6 +185,7 @@ input.btn {
text-align: center; text-align: center;
border-radius: 1px; border-radius: 1px;
} }
.bg-grad,.bg-filter { .bg-grad,.bg-filter {
text-align:center; text-align:center;
background: rgb(0,51,102); background: rgb(0,51,102);
...@@ -908,4 +916,175 @@ i.notice{ ...@@ -908,4 +916,175 @@ i.notice{
.ArrowNone{ .ArrowNone{
-webkit-appearance: none !important; -webkit-appearance: none !important;
} }
.px200 {width: 200px;} .px200 {width: 200px;}
\ No newline at end of file
.depositAmt_cont{
display: none;
}
/* Settlement API */
#loginAPI .col-3 {
display: inline-block;
width: 70%;
vertical-align: middle;
}
#loginAPI .col-1 {
display: inline-block;
width: 29%;
border-left: 1px solid #d8d8d8;
text-align: center;
vertical-align: middle;
}
#loginAPI .col-1 .sign-up-container {
min-height: 150px;
display: flex;
align-items: center;
line-height: 30px;
}
#loginAPI .col-1 .sign-up-container>div {
width: 100%;
font-weight: 600;
color: #036;
font-size: 12px;
}
#loginAPI .col-1 .sign-up-container>div a {
font-weight: 600;
color: #0426ff;
text-decoration:underline
}
@media (max-width: 1514px){
#loginAPI .col-1 {
border-top: 1px solid #e8e8e8;
border-left: 0px !important;
margin-top: 10px;
}
}
@media (max-width: 628px){
#loginAPI .col-3 {
width: 100%;
text-align: left;
}
#loginAPI .col-1 {
width: 70%;
}
}
/* pop up css */
/*.popup-overlay {
visibility: hidden;
position: absolute;
background: #ffffff;
border: 1px solid #9e9e9e;
width: 100%;
max-width: 900px;
padding: 20px;
left: 0;
right: 0;
top: 100px;
margin-left: auto;
margin-right: auto;
}*/
.overlay-cont, .error-cont, .loading-cont{
visibility: hidden;
position: fixed;
background: rgba(0,0,0,0.5);
transition: opacity 200ms;
opacity: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
@media (max-width: 1024px){
.overlay-cont, .error-cont, .loading-cont{
position: absolute;
}
}
/*.overlay:target{
visibility: visible;
opacity: 1;
}*/
/* pop up css */
.popup-overlay {
position: relative;
width: 100%;
max-width: 900px;
padding: 20px;
margin: 0 auto;
background: #fff;
border: 1px solid #9e9e9e;
box-shadow: 0 0 50px rgba(0,0,0,0.5);
}
.overlay-cont.active {
visibility: visible !important;
/*text-align: center;*/
opacity: 1;
}
.m_btn{
margin: 10px !important;
}
.f-bold{
font-weight: bold;
}
/* error pop-up */
.error-popup {
position: relative;
width: 100%;
margin: 0 auto;
background: #fff;
border: 1px solid #9e9e9e;
box-shadow: 0 0 50px rgba(0,0,0,0.5);
max-width: 600px;
padding: 40px;
}
.error-cont.active {
visibility: visible !important;
/*text-align: center;*/
opacity: 1;
}
/* loading pop-up */
.loading-popup{
position: relative;
background: #fff;
border: 1px solid #9e9e9e;
width: 100%;
max-width: 600px;
padding: 40px;
box-shadow: 0 0 50px rgba(0,0,0,0.5);
margin: 0 auto;
}
.loading-cont.active {
visibility: visible !important;
opacity: 1;
}
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #003368;
width: 100px;
height: 100px;
text-align: center;
-webkit-animation: spin 2s linear infinite;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
...@@ -1640,11 +1640,16 @@ table td.clr.selectC label.w33p { ...@@ -1640,11 +1640,16 @@ table td.clr.selectC label.w33p {
.dt250{ .dt250{
width:100%; width:100%;
float:none; float:none;
}
.dt-form{
width: 100% !important;
float: none !important;
} }
.dt300{ .dt300{
width:100%; width:100%;
float:none; float:none;
} }
.clearL{ .clearL{
float:none; float:none;
display:block; display:block;
...@@ -2243,4 +2248,131 @@ header .logo-block img { ...@@ -2243,4 +2248,131 @@ header .logo-block img {
.ui-pagination{ .ui-pagination{
padding-top: 15px; padding-top: 15px;
} }
\ No newline at end of file
/* Settlement API */
div#loginAPI {
width: 100%;
max-width: 650px;
border: solid 1px #ddd;
border-radius: 5px;
text-align: center;
padding: 20px;
margin: 30px 0px;
/*position: relative;*/
left: -140px;
}
.enlogin #loginAPI {
width: 500px;
box-shadow:none;
border:0;
border-radius:0px;
text-align: center;
margin: 10px auto;
/*position: relative;*/
left: -145px;
}
div#loginAPI h2 {
color: #036;
padding-bottom:10px;
}
div#loginAPI table {
width: 90%;
margin: 10px auto;
}
div#loginAPI table th {
width: 30%;
line-height: 1.1;
font-size: 14px;
font-weight: normal;
padding: 10px 0;
text-align: center;
}
div#loginAPI table td {
width: 70%;
line-height: 1.1;
font-size: 14px;
text-align: center;
}
.column_iwl {
float: left;
width: 50%;
padding: 40px;
}
.brd_div{
border-right: 1px solid #c3c2c2;
}
@media (max-width: 970px){
.api_header{
background: #003366;
}
}
@media (max-width: 1394px){
div#loginAPI {
margin: 60px auto;
}
.column_iwl {
float: none;
width: 100%;
}
div#loginAPI {
position: inherit;
}
aside#colLeft {
padding: 0 0 0 0px !important;
width: 100% !important;
display: none !important;
}
.brd_div{
border-right: initial;
}
.dt-form{
width: 250px;
float: left;
margin: 0 30px 0 0;
padding: 10px 0;
}
}
@media (max-width: 1517px){
.dt-form{
width: 100% !important;
float: none !important;
}
.settlement_cont{
background: none !important;
}
.api_aside{
visibility: hidden !important;
display: none !important;
}
.api_header{
visibility: visible !important;
}
}
.api_aside{
visibility: visible;
}
.api_header{
visibility: hidden;
}
.dt-label{
margin: 0 30px 0 0;
padding: 10px 0;
}
.dt-form{
width: 250px;
float: left;
margin: 0 30px 0 0;
padding: 10px 0;
}
/* Clear floats after the columns */
.row_iwl:after {
content: "";
display: table;
clear: both;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title><?php echo $page_title; ?> | iWallet</title>
<meta name="keywords" content="keywords">
<meta name="description" content="description">
<link rel="stylesheet" type="text/css" href="../files/css/mystyle.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="../css/user.css">
<link rel="stylesheet" href="../css/common.css">
<link rel="stylesheet" href="../js/jquery/jquery-ui.css" />
<link rel="stylesheet" href="../js/jquery/jquery.datetimepicker.css">
<script src="../js/jquery.js"></script>
<script src="../js/jquery/jquery-ui.min.js"></script>
<!-- <script src="../js/jquery/jquery.datetimepicker.js"></script> -->
<!--[if lt IE 9]><script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js"></script><![endif]-->
<!--[if lt IE 8]><script src="//cdnjs.cloudflare.com/ajax/libs/selectivizr/1.0.2/selectivizr-min.js"></script><![endif]-->
<link rel="stylesheet" type="text/css" href="../css/basictable.css" />
<link rel="stylesheet" type="text/css" ng-href="../css/ph-mystyle.less" />
<link rel="stylesheet" type="text/css" href="../css/ph-mystyle.min.css" />
<script type="text/javascript" src="../js/jquery.basictable.min.js"></script>
<script type="text/javascript" src="../js/common.js"></script>
<script src="../js/Validform_v4.0.js" type="text/javascript"></script>
<script src="../js/ui-choose.js" type="text/javascript"></script>
<link rel="stylesheet" href="../css/ui-choose.css">
<!-- <link rel="stylesheet" href="../css/change.css"> -->
</head>
<body>
<div id="container">
<div id="whole" class="settlement_cont">
<?php
$page_title = "Payment Request Form";
include_once('./config.php');
include_once('template/base_head_API.php');
?>
<aside id="colLeft" class="login api_aside">
<h1><a href="/en/menu"><img src="../img/logo.png" alt="iWallet"></a></h1>
<h2></h2>
<div class="sideLogin"></div>
</aside>
<div id="colMain" class="nonav">
<div class="mainIn">
<?php /* include_once('template/base_nav_logout.php'); */ ?>
<header class="api_header">
<a href="/en/menu"><img src="../img/logo.png" alt="iWallet"></a><nav id="navbar">
&nbsp;
</nav>
</header>
<div class="row_iwl">
<div class="column_iwl">
<article class="brd_div">
<div class="article-heading">
<h2><?php echo $page_title; ?></h2>
</div>
<div class="pleft40">
<p class="mb30">Please choose your payout currency</p>
<div class="clearfix shelfD">
<div class="dt-form font14 f-bold">Requestee Account Number</div>
<div class="dt-label font14">
<?php $this -> echoToAccount(); ?>
</div>
</div>
<div class="clearfix shelfD">
<div class="dt-form font14 f-bold">Requestee Name</div>
<div class="dt-label font14">
<?php $this -> dispSiteName(); ?>
</div>
</div>
<div class="clearfix shelfD">
<div class="dt-form font14 f-bold">Product</div>
<div class="dt-label font14">
<?php $this -> echoTitle(); ?>
</div>
</div>
<div class="clearfix shelfD">
<div class="dt-form font14 f-bold">Amount Received</div>
<div class="dt-label font14">
<?php $this -> echoCurrency(); ?> <?php $this -> echoAmount(); ?>
</div>
</div>
<div class="clearfix shelfD details_cont">
<div class="dt-form font14 f-bold " id="bg-cont">Payout Currency</div>
<select id="debit_currency" name="debit_currency" class="px100 ArrowNone">
<?php $this -> dispCurrency(); ?>
</select>&emsp;
</div>
<div class="clearfix shelfD">
<div class="dt-form font14 f-bold">Message</div>
<textarea rows="3" cols="40" id="message_field" name="message" class="w100p lalign"></textarea>
</div>
<div class="dt250 noborder"></div>
</div>
</article>
</div>
<div class="column_iwl ">
<!--
<p class="red mt20"><span class="fa fa-times-circle fa-lg mt"></span>
Please confirm the payment details first.
</p>
-->
<div id="loginAPI">
<div class="overlay-cont">
<div class="popup-overlay">
<div>
<h1 class="mt30">Settlement Confirmation</h1>
<div class="article-heading mt20">
<h2><?php echo $page_title; ?></h2>
</div>
<table class="table col bdr default odd withdrawT fontM mb20 ma90sp">
<tbody>
<tr>
<th>Requester Account Number</th>
<td><span class="w50p" id="spRequesterAcc"></span></td>
</tr>
<tr>
<th>Requester Name</th>
<td><span class="w50p" id="spRequesterName"></span></td>
</tr>
<tr>
<th>Requestee Account No.</th>
<td><span class="w50p"><?php $this -> echoToAccount(); ?></span></td>
</tr>
<tr>
<th>Requestee Name</th>
<td><span class="w50p"><?php $this -> dispSiteName(); ?></span></td>
</tr>
<tr>
<th>Product</th>
<td><span class="w50p"><?php $this -> echoTitle(); ?></span></td>
</tr>
<tr>
<th>Amount to pay</th>
<td><span class="w50p" id="spAmount"></span></td>
</tr>
<tr>
<th>Rate</th>
<td><span class="w50p" id="spRate"></span></td>
</tr>
<tr>
<th>Debit Amount</th>
<td><span class="w50p" id="spDebitAmount"></span></td>
</tr>
<tr>
<th>Message</th>
<td><span class="w50p" id="spMessage"></span></td>
</tr>
</tbody>
</table>
<div class="clearfix shelfD">
<div class="dt250 font14 f-bold">Payout Currency Balance</div>
<p class="dt250 font14 f-bold" id="spDebitCurBalance"></p>
</div>
<p class="pt20 pb20 settleInsufficient red f-bold"> Insufficient Funds</p>
<p class="pt20 pb20 settleQuestion"> Are your sure you want to proceed to your settlement?</p>
<div class="pt-20 mb10">
<a class="conf-settle-pop btn bg-grad px180 m_btn">Confirm</a>
<a class="close-pop btn bg-parent px180 m_btn">Cancel</a>
</div>
</div>
</div>
</div>
<form method="POST" id="authConfirm">
<div class="col-3">
<table>
<tr>
<th>Your Email Address</th>
<td><input type="text" name="user_name" id="user_name" class="w100p" autocomplete="off"></td>
</tr>
<tr>
<th>Password</th>
<td><input type="password" name="password" id="password" class="w100p" autocomplete="new-password"></td>
</tr>
</table>
</div>
<div class="col-1">
<div class="sign-up-container">
<div>New to iWallet?&nbsp; <a href="<?php echo $this -> getAgentCodeURL(); ?>" target="_blank">Sign Up</a> for a new account now!</div>
</div>
</div>
<input type="submit" value="Settle" class="btn bg-grad px80" >
</form>
<form id="acForm" action="" method="POST">
<input type="hidden" value="<?php $this -> echoSignature(); ?>" id="signature" name="signature" />
<input type="hidden" value="<?php $this -> echoToAccount(); ?>" id="user_account" name="user_account" />
<input type="hidden" value="<?php $this -> echoCurrency(); ?>" id="currency" name="currency" />
<input type="hidden" value="<?php $this -> echoAmount(); ?>" id="amount" name="amount" />
<input type="hidden" value="<?php $this -> echoTitle(); ?>" id="title" name="title" />
<input type="hidden" value="<?php $this -> echoSuccessUrl(); ?>" name="success_url" />
<input type="hidden" value="<?php $this -> echoFailUrl(); ?>" name="fail_url" />
<input type="hidden" value="<?php $this -> echoReturnUrl(); ?>" name="return_url" />
<input type="hidden" value="<?php $this -> echoPNum(); ?>" name="p_num" />
<input type="hidden" value="<?php $this -> echoFormName(); ?>" name="formName" />
<input type="hidden" value="" id="type" name="type" />
<input type="hidden" value="" id="uniqueSubmission" name="uniqueSubmission" />
<input type="hidden" value="" id="debit_currency_ac" name="debit_currency" />
<input type="hidden" value="" id="from_account" name="from_account" />
<input type="hidden" value="" id="message" name="message" />
<input type="hidden" value="" id="rate" name="rate" />
<?php $this -> echoParams(); ?>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- Error pop up -->
<div class="error-cont" >
<div class="error-popup">
<h2 class=" red mb20">Payment cannot be processed</h2>
<div id="errorTraces">
<p class="red mt10"><span class="fa fa-times-circle fa-lg mt"></span> Lorem ipsum dolor sit amet, consectetur adipisicing elit</p>
<p class="red mt10"><span class="fa fa-times-circle fa-lg mt"></span> Lorem ipsum dolor sit amet, consectetur adipisicing elit</p>
<p class="red mt10"><span class="fa fa-times-circle fa-lg mt"></span> Lorem ipsum dolor sit amet, consectetur adipisicing elit</p>
</div>
<div class="pt40 calign" >
<a class="error-close btn bg-parent px180 m_btn">Close</a>
</div>
</div>
</div>
<!-- loading popup -->
<div class="loading-cont">
<div class="loading-popup">
<h2 class="mt10 mb-20 blue">Please wait...</h2>
<div class="mt20 loader"></div>
</div>
</div>
</div>
<!-- /メインカラム -->
</div>
<?php include_once('template/base_foot.php'); ?>
</div>
<script src="../js/settlement.js"></script>
</body>
</html>
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<p class="ralign"><?php echo SITE_DOMAIN ?></p> <p class="ralign"><?php echo SITE_DOMAIN ?></p>
</header> </header>
<h2 class="calign mb20">Invalid parameter.</h2> <h2 class="calign mb20">Invalid parameter.</h2>
<?php $this -> echoMessage(); ?> <?php $this -> echoInvalidFormParams(); ?>
This process is unable to continue.<br/> This process is unable to continue.<br/>
For more details, please contact your merchant.<br/> For more details, please contact your merchant.<br/>
<footer> <footer>
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<p class="ralign"><?php echo SITE_DOMAIN ?></p> <p class="ralign"><?php echo SITE_DOMAIN ?></p>
</header> </header>
<h2 class="calign mb20">Parameter tidak valid.</h2> <h2 class="calign mb20">Parameter tidak valid.</h2>
<?php $this -> echoMessage(); ?> <?php $this -> echoInvalidFormParams() ?>
Proses ini tidak dapat dilanjutkan.<br/> Proses ini tidak dapat dilanjutkan.<br/>
Untuk lebih jelasnya, silakan hubungi merchant Anda.<br/> Untuk lebih jelasnya, silakan hubungi merchant Anda.<br/>
<footer> <footer>
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<p class="ralign"><?php echo SITE_DOMAIN ?></p> <p class="ralign"><?php echo SITE_DOMAIN ?></p>
</header> </header>
<h2 class="calign mb20">パラメータが不正です。</h2> <h2 class="calign mb20">パラメータが不正です。</h2>
<?php $this -> echoMessage(); ?> <?php $this -> echoInvalidFormParams() ?>
処理を続行できません。<br/> 処理を続行できません。<br/>
詳しくは、販売サイト様にお問い合わせ下さい。<br/> 詳しくは、販売サイト様にお問い合わせ下さい。<br/>
<footer> <footer>
......
...@@ -44,6 +44,14 @@ function postAction(target, params) { ...@@ -44,6 +44,14 @@ function postAction(target, params) {
}); });
} }
function isJSON(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
$(function(){ $(function(){
var menu = $('#navbar'), var menu = $('#navbar'),
......
$(function() { $(function() {
var _authSettlementRequest = function(form){
let transp = {};
form.find("input").each(function(e){
let type = $(this).attr("type").trim().toLowerCase()
if(type != "submit")
transp[$(this).attr("name")] = $(this).val()
})
$("#acForm input").each(function(e){
transp[$(this).attr("name")] = $(this).val()
})
transp["debit_currency"] = $("#debit_currency").val()
transp["message"] = $("#message_field").val()
$.ajaxSetup({
beforeSend : function(){
$(".loading-cont").addClass("active")
},
complete : function(){
$(".loading-cont").removeClass("active")
}
})
$.post("settlement?type=settle_express_check", transp, function(data){
if(isJSON(data) || typeof data == "object"){
let encoded = typeof data != "object" ? JSON.parse(data) : data;
let returns = encoded.returns;
let invalid = encoded.invalid;
let invkeys = Object.keys(invalid)
if(invkeys.length){
validation : {
if(invkeys.includes("OE04") && invkeys.length == 1)
break validation;
$("#errorTraces").empty()
$(".error-cont").addClass("active");
for(var ids in invalid){
let errRow = '<p class="red mt10"><span class="fa fa-times-circle fa-lg mt"></span>'+invalid[ids]+'</p>';
$("#errorTraces").append(errRow)
}
}
}
if(Object.keys(returns).length){
$(".overlay-cont").addClass("active");
$(".overlay-cont").hide().fadeIn(700);
let transactionDetails = returns.transaction_details;
$("#spRequesterAcc").html(transactionDetails.from_account)
$("#spRequesterName").html(transactionDetails.from_full_name)
$("#spRate").html(transactionDetails.rate)
$("#spDebitAmount").html(transactionDetails.debit_currency+' '
+transactionDetails.debit_amount)
$("#spAmount").html(transactionDetails.currency+' '
+transactionDetails.amount)
$("#spDebitCurBalance").html(transactionDetails.debit_currency+' '
+transactionDetails.balance)
$("#spMessage").html(transactionDetails.message)
if(transactionDetails.uniqueSubmission.length != 0){
$(".settleInsufficient").hide()
$(".settleQuestion").show()
$(".conf-settle-pop").show()
$(".conf-settle-pop").click(function(e){
e.preventDefault()
$(this).hide()
$(".loading-cont").addClass("active")
$("#uniqueSubmission").val(transactionDetails.uniqueSubmission)
$("#debit_currency_ac").val(transactionDetails.debit_currency)
$("#from_account").val(transactionDetails.from_account)
$("#message").val(transactionDetails.message)
$("#rate").val(transactionDetails.rate)
$("#type").val("settle_express_submit")
submitForm()
})
}else{
$(".settleInsufficient").show()
$(".settleQuestion").hide()
$(".conf-settle-pop").hide()
}
}
}else
alert("Internal Error Occurred.")
})
}
$("#authConfirm").submit(function(e){
e.preventDefault()
_authSettlementRequest($(this))
})
$('.close-pop').click(function(e) {
$(".conf-settle-pop").unbind()
$(".overlay-cont").removeClass("active")
$(".overlay-cont").fadeOut(1000)
$('#btnInput').click(function() { })
$('#type').val('input');
submitForm(); $('.error-close').click(function(e) {
}); $(".error-cont").removeClass("active")
})
$('#btnConfirm').click(function() { })
$('#type').val('confirm');
submitForm();
});
$('#btnComplete').click(function() {
$('#btnComplete').attr('disabled', true);
$('#type').val('complete');
submitForm();
});
$('#btnLogin').click(function() {
$('#type').val('login');
submitForm();
});
$('#debit_currency').change(function() {
getBalance();
});
$('#btnBalance').click(function() {
getBalance();
});
$('#btnBack').click(function() {
$('#type').val('input');
submitForm();
});
getBalance();
});
function getBalance() {
$('#balanceCurrency').text('Checking...');
// ポストアクション
postAction('../api/GetWalletBalance', {'currency':$('#debit_currency').val(), 'user_account':$('#from_account').val()})
.done(function(data) {
$('#balanceCurrency').text($('#debit_currency').val() + ' ' + data.balance.toString());
})
.fail(function(data) {
console.log(data);
});
}
$("#password").keypress(function(event) {
if (event.keyCode === 13) {
$("#btnLogin").click();
}
});
$("#user_name").keypress(function(event) {
if (event.keyCode === 13) {
$("#btnLogin").click();
}
});
<?php
use Firebase\JWT\JWT;
use Defuse\Crypto\Crypto;
use function GuzzleHttp\json_encode;
/**
*
* 目的: PaymentAPI
* 開発者: Anthony
*
*/
class PaymentAPI extends System {
/**
*
* シングルトンの一般的な変数
*
* @var object
*/
private static $singleton;
/**
*
* @var integer
*/
private $remarks = NO_COUNT;
/**
*
* @var payload
*/
private $data;
/**
*
* @var unknown
*/
private $paymentAPIconf;
/**
*
* @var unknown
*/
private $midconf;
private const INVALID_JSON_STRING = 1;
private const NO_PROGRAM_CODE = 2;
/**
*
* コンストラクタ
*
*/
private function __construct(){
parent::__construct();
$this -> initSettings();
}
private function initSettings(){
$this -> paymentAPIconf = $this -> getConfiguration("payment_api_conf");
$this -> midconf = $this -> getConfiguration("middleware_conf");
if(isset($this -> paymentAPIconf -> middleware_sig_passphrase)){
$replacements = [
"{curdate_int}" => strtotime(date("Ymd")),
"{curdate_str}" => date("Ymd")
];
foreach($replacements as $search => $replace){
$this -> paymentAPIconf -> middleware_sig_passphrase = str_replace(
$search,
$replace,
$this -> paymentAPIconf -> middleware_sig_passphrase);
}
}
}
/**
* シングルトンの機能
*
* @return PaymentAPI
*/
private static function getInstance() : PaymentAPI {
if(!isset(self::$singleton))
self::$singleton = new PaymentAPI();
return self::$singleton;
}
/**
*
* 目的の出力
*/
public static function action(){
$purpose = self::getInstance();
$purpose -> redirectToForm();
}
/**
*
* 公開的な確認
*
* @param string $data
* @param array $verdict
*/
public static function validation($data, &$verdict){
$purpose = self::getInstance();
$purpose -> setData($data);
$purpose -> checkSettlementPayload();
$purpose -> setVerdict($verdict);
}
/**
*
* 支払ペイロードの確認
*
*/
private function checkSettlementPayload(){
if($this -> checkJSONString($this -> data)){
$settleData = json_decode($this -> data, true);
$apiSignature = $this -> getRowData(
$this -> getAPISignatureCommon($this -> getColumnData($settleData, PARAM_P_NUM)));
if(!$this -> isLoopData($apiSignature)){
$this -> invalid[] = self::NO_PROGRAM_CODE;
}
}else
$this -> remarks = self::INVALID_JSON_STRING;
}
/**
*
*
* ペイロードデータの設定
*
* @param unknown $data
*/
private function setData($data){
$this -> data = $data;
}
/**
*
* 開発者の設定
*
* @return boolean|mixed
*/
private function getConfiguration($settingId){
$devSetting = $this -> getRowData($this -> accessSelect("SELECT_DEV_SETTING", [$settingId]));
if($this -> isLoopData($devSetting)){
if($this -> checkJSONString($this -> getColumnData($devSetting, "dev_setting_value"))){
$settingsValue = json_decode($this -> getColumnData($devSetting, "dev_setting_value"));
return $settingsValue;
}
}else
return false;
}
/**
*
* 確認の結果設定
*
* @param array $verdict
*/
private function setVerdict(&$verdict){
switch($this -> remarks){
case NO_COUNT:
$verdict = [
"validation" => true,
"description" => NO_STRING
];
break;
case self::INVALID_JSON_STRING:
$verdict = [
"validation" => false,
"description" => "Syntax Error on Payload JSON String found"
];
break;
case self::NO_PROGRAM_CODE:
$verdict = [
"validation" => false,
"description" => "Program Code doesn't exist"
];
break;
}
}
/**
*
* 支払いフォームIDの作成者
*
* @param array $registData
* @return boolean|unknown
*/
private function createSettlementFormId(Array $registData){
return $this -> accessModify("INSERT_SETTLEMENT_FORM",
array_merge(
$registData,
[base64_encode($this -> data)]
), false);
}
/**
*
*
* 支払フォームへのリダイレクト
*
*/
private function redirectToForm(){
$payloadData = json_decode($this -> data);
$uniqueKey = $this -> createUId();
$this -> createSettlementFormId([
$uniqueKey,
$payloadData -> p_num
]);
$midsignature = Crypto::encryptWithPassword(
json_encode([
"name" => "middleware_sig_M".strtotime("YmdHis"),
"uniqueKey" => $uniqueKey,
"creation" => date("Y-m-d H:i:s"),
"expiration" => date("Y-m-d H:i:s", strtotime($this -> paymentAPIconf -> form_duration)),
"signature" => $payloadData -> signature,
"p_num" => $payloadData -> p_num
]),
$this -> paymentAPIconf -> middleware_sig_passphrase);
unset($payloadData -> signature);
unset($payloadData -> p_num);
$formlinkPayload = [
"midsign" => $midsignature,
"data" => base64_encode(json_encode($payloadData))
];
$formToken = JWT::encode(
$formlinkPayload,
$this -> midconf -> token_secretkey.strtotime(date("Ymd")),
$this -> midconf -> algorithm);
$baseUrl = SITE_PROTOCOL."://".SITE_DOMAIN_FULL."/{$payloadData -> language}/settlement";
$params = "type=".TYPE_SETTLEMENT_EXPRESS_API."&ptoken={$formToken}";
$redirection = "{$baseUrl}?{$params}";
header("Location: {$redirection}");
}
/**
*
* 詳細をログ
*
* @param unknown $content
*/
private function logDetails($content){
$timestamp = date("Y-m-d H:i:s");
$logDir = SITE_ROOT."api/Logs/settlement/curl";
if(!@file_exists($logDir))
mkdir($logDir, 0777, true);
$logFile = "{$logDir}/Log_".date("Y-m-d").".log";
error_log("[{$timestamp}]\n\n{$content}\n\n", VAL_INT_3, $logFile);
}
}
\ No newline at end of file
...@@ -22,9 +22,6 @@ class ControlSettlement extends LogicSettlement { ...@@ -22,9 +22,6 @@ class ControlSettlement extends LogicSettlement {
* @return : なし * @return : なし
-------------------------------------------------------------------------*/ -------------------------------------------------------------------------*/
function action() { function action() {
// 変数宣言部
$result = NO_STRING;
try { try {
$this -> checkAvailability("site", function(){ $this -> checkAvailability("site", function(){
require_once $this -> getUserHTML('TEMPLATE_MAINTENANCE_MODE_SITE_PATH'); require_once $this -> getUserHTML('TEMPLATE_MAINTENANCE_MODE_SITE_PATH');
...@@ -32,40 +29,22 @@ class ControlSettlement extends LogicSettlement { ...@@ -32,40 +29,22 @@ class ControlSettlement extends LogicSettlement {
}); });
// アクション実行 // アクション実行
$result = $this -> logic(); $this -> logic();
// return NO_STRING; switch($this -> getType()){
case TYPE_SETTLEMENT_EXPRESS_API:
if($this -> getType() == CONTROL_NAME_LOGIN) { // 決済前ログイン require_once($this -> getUserHTML('TEMPLATE_SETTLEMENT_API_PATH'));
require_once($this -> getUserHTML('TEMPLATE_SETTLEMENT_LOGIN_PATH', $this -> dispHTML())); break;
case TYPE_SETTLEMENT_EXPRESS_CHECK:
} else if($this -> getType() == TYPE_INPUT) { // 決済情報入力 $this -> echoValidationResult();
require_once($this -> getUserHTML('TEMPLATE_SETTLEMENT_INPUT_PATH', $this -> dispHTML())); break;
case TYPE_FAIL:
} else if($this -> getType() == TYPE_CONFIRM) { // 決済情報確認 require_once($this -> getUserHTML('TEMPLATE_SETTLEMENT_FAIL_PATH'));
require_once($this -> getUserHTML('TEMPLATE_SETTLEMENT_CONFIRM_PATH', $this -> dispHTML())); break;
} else if($this -> getType() == TYPE_COMPLETE) { // 決済情報完了
require_once($this -> getUserHTML('TEMPLATE_SETTLEMENT_COMPLETE_PATH', $this -> dispHTML()));
} else if($this -> getType() == TYPE_FAIL) { // 決済情報エラー
require_once($this -> getUserHTML('TEMPLATE_SETTLEMENT_FAIL_PATH', $this -> dispHTML()));
} else if($this -> getType() == TYPE_REQUEST_SESSION_EXPIRED) { // 決済情報エラー
require_once($this -> getUserHTML('TEMPLATE_SETTLEMENT_REQUEST_EXPIRED_PATH', $this -> dispHTML()));
} else { // 決済情報エラー
// require_once($this -> getUserHTML('TEMPLATE_SETTLEMENT_LOGIN_PATH', $this -> dispHTML()));
require_once($this -> getUserHTML('TEMPLATE_SETTLEMENT_FAIL_PATH', $this -> dispHTML()));
} }
} catch (Exception $e) { } catch (Exception $e) {
header("Location: /{$this -> getLangage()}");
if($e -> getMessage() != NO_STRING) {
require_once($this -> getUserHTML('TEMPLATE_TMP_PROCESS_INVALID_PATH', $this -> dispHTML()));
} else {
require_once($this -> getUserHTML('TEMPLATE_SETTLEMENT_LOGIN_PATH', $this -> dispHTML()));
}
} }
} }
} }
......
...@@ -32,7 +32,8 @@ class LogicSettlement extends SettlementModelClass { ...@@ -32,7 +32,8 @@ class LogicSettlement extends SettlementModelClass {
$this -> biz(); $this -> biz();
// POSTのログを取る // POSTのログを取る
$this -> logPost($this -> getProgramCode()); if($this -> getProgramCode() != NO_STRING)
$this -> logPost($this -> getProgramCode());
} catch (Exception $e) { } catch (Exception $e) {
throw $e; throw $e;
} }
...@@ -44,45 +45,22 @@ class LogicSettlement extends SettlementModelClass { ...@@ -44,45 +45,22 @@ class LogicSettlement extends SettlementModelClass {
* @return : なし * @return : なし
-------------------------------------------------------------------------*/ -------------------------------------------------------------------------*/
private function biz() { private function biz() {
switch($this -> getType()){
//check if type is control action case TYPE_SETTLEMENT_EXPRESS_API:
if($this -> getType() == CONTROL_ACTION) { $this -> restore();
//unset session variable for previous type $this -> select();
unset($_SESSION['settlement_previous_type']); break;
} case TYPE_SETTLEMENT_EXPRESS_SUBMIT:
try {
if($this -> getType() == TYPE_COMPLETE) { $registResult = $this -> regist();
$this -> forward($registResult);
//unset session variables before redirection } catch(Exception $e) {
unset($_SESSION['settlement_amount']); $this -> forward(VAL_INT_1);
unset($_SESSION['settlement_previous_type']); }
unset($_SESSION['settlement_user_account']); break;
unset($_SESSION['settlement_debit_currency']); }
unset($_SESSION['settlement_currency']);
unset($_SESSION['to_fee']);
unset($_SESSION['from_fee']);
unset($_SESSION['request_token']);
try {
$registResult = $this -> regist();
$this -> forward($registResult);
} catch(Exception $e) {
$this -> forward(VAL_INT_1);
}
} else if($this -> getType() == TYPE_INPUT
|| $this -> getType() == TYPE_CONFIRM) {
$this -> select();
}
} }
/*-------------------------------------------------------------------------
* @function_name: データのロード
* @parameter : なし
* @return : なし
-------------------------------------------------------------------------*/
private function lists() {}
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* @function_name: データのロード * @function_name: データのロード
* @parameter : なし * @parameter : なし
...@@ -103,7 +81,7 @@ class LogicSettlement extends SettlementModelClass { ...@@ -103,7 +81,7 @@ class LogicSettlement extends SettlementModelClass {
// コミッションの登録(送金元) // コミッションの登録(送金元)
$this -> registCommision(VAR_TRANSFER $this -> registCommision(VAR_TRANSFER
, null , null
, $this -> getUserData(PARAM_USER_ACCOUNT) , $this -> getFromAccount()
, $this -> getDebitCurrency() , $this -> getDebitCurrency()
, $this -> getFromFee()); , $this -> getFromFee());
...@@ -121,7 +99,7 @@ class LogicSettlement extends SettlementModelClass { ...@@ -121,7 +99,7 @@ class LogicSettlement extends SettlementModelClass {
if($from != $to) { if($from != $to) {
// 着金額指定の場合 // 着金額指定の場合
$this -> registCommisionExchange($this -> getUserData(PARAM_USER_ACCOUNT) $this -> registCommisionExchange($this -> getFromAccount()
, $to , $to
, $from , $from
, $this -> currencyToInt($this -> getDebitAmount(), $from)); , $this -> currencyToInt($this -> getDebitAmount(), $from));
...@@ -140,6 +118,8 @@ class LogicSettlement extends SettlementModelClass { ...@@ -140,6 +118,8 @@ class LogicSettlement extends SettlementModelClass {
, $params , $params
, $params[VAL_INT_11] , $params[VAL_INT_11]
, VAR_CS_MAIL_ADDRESS); , VAR_CS_MAIL_ADDRESS);
$this -> updateSettlementFormStatus();
return NO_COUNT; return NO_COUNT;
} else { } else {
return VAL_INT_1; return VAL_INT_1;
...@@ -152,7 +132,6 @@ class LogicSettlement extends SettlementModelClass { ...@@ -152,7 +132,6 @@ class LogicSettlement extends SettlementModelClass {
* @return : なし * @return : なし
-------------------------------------------------------------------------*/ -------------------------------------------------------------------------*/
private function forward($result) { private function forward($result) {
// 変数宣言部 // 変数宣言部
$url = NO_STRING; $url = NO_STRING;
$data = null; $data = null;
...@@ -171,8 +150,7 @@ class LogicSettlement extends SettlementModelClass { ...@@ -171,8 +150,7 @@ class LogicSettlement extends SettlementModelClass {
$apiPath = dirname(SYSTEM_PATH).DIRECTORY_SEPARATOR.'api'; $apiPath = dirname(SYSTEM_PATH).DIRECTORY_SEPARATOR.'api';
$requestUrl = $apiPath.DIRECTORY_SEPARATOR.'Logs'.DIRECTORY_SEPARATOR.'settlement'.DIRECTORY_SEPARATOR.'settlement_response_data'; $requestUrl = $apiPath.DIRECTORY_SEPARATOR.'Logs'.DIRECTORY_SEPARATOR.'settlement'.DIRECTORY_SEPARATOR.'settlement_response_data';
if(!file_exists($requestUrl)) if(!file_exists($requestUrl)){
{
mkdir($requestUrl, 0777, true); mkdir($requestUrl, 0777, true);
} }
...@@ -200,6 +178,9 @@ class LogicSettlement extends SettlementModelClass { ...@@ -200,6 +178,9 @@ class LogicSettlement extends SettlementModelClass {
if(isset($_SERVER['HTTP_REFERER'])) { if(isset($_SERVER['HTTP_REFERER'])) {
$referer = $this -> sqlSanitation($_SERVER['HTTP_REFERER']); $referer = $this -> sqlSanitation($_SERVER['HTTP_REFERER']);
if(strlen($referer) > VAL_INT_256)
$referer = preg_replace("/\\?.*/", "", $referer);
} }
// 転送をする // 転送をする
...@@ -207,13 +188,7 @@ class LogicSettlement extends SettlementModelClass { ...@@ -207,13 +188,7 @@ class LogicSettlement extends SettlementModelClass {
&& $file == NO_COUNT && $file == NO_COUNT
&& $result == NO_COUNT) { // 正常終了 && $result == NO_COUNT) { // 正常終了
// logs the data that will be passed // this insert command also comtains data that will passed to merchant's system.
$this -> accessModifyCommon('INSERT_LOG_POST', array(
$ip,
$this -> getProgramCode(),
$referer,
"[TO_RETURN_URL_DATA]{$data}"));
$this -> accessModifyCommon('INSERT_LOG_POST', array( $this -> accessModifyCommon('INSERT_LOG_POST', array(
$ip, $ip,
$this -> getProgramCode(), $this -> getProgramCode(),
...@@ -233,13 +208,8 @@ class LogicSettlement extends SettlementModelClass { ...@@ -233,13 +208,8 @@ class LogicSettlement extends SettlementModelClass {
} }
} }
/*------------------------------------------------------------------------- function updateSettlementFormStatus(){
* @function_name: ページ出力文字列取得関数 $this -> accessModify("UPDATE_SETTLEMENT_FORM", [$this -> getFormName()], false);
* @parameter : なし
* @return : HTML文字列
-------------------------------------------------------------------------*/
function getDisplay() {
return $this -> htmlStr;
} }
} }
?> ?>
\ No newline at end of file
This diff is collapsed.
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<p class="ralign"><?php echo SITE_DOMAIN ?></p> <p class="ralign"><?php echo SITE_DOMAIN ?></p>
</header> </header>
<h2 class="calign mb20">参数无效。</h2> <h2 class="calign mb20">参数无效。</h2>
<?php $this -> echoMessage(); ?> <?php $this -> echoInvalidFormParams() ?>
无法执行此操作。<br/> 无法执行此操作。<br/>
更多详情,请联系您的代理商。<br/> 更多详情,请联系您的代理商。<br/>
<footer> <footer>
......
...@@ -85,6 +85,10 @@ define('TYPE_SAVE_RISK', 'save_risk'); ...@@ -85,6 +85,10 @@ define('TYPE_SAVE_RISK', 'save_risk');
define('TYPE_INPUT_ACCESS', 'input_access'); define('TYPE_INPUT_ACCESS', 'input_access');
define('TYPE_SAVE_ACCESS', 'save_access'); define('TYPE_SAVE_ACCESS', 'save_access');
define('TYPE_REQUEST_SESSION_EXPIRED', 'request_session_expired'); define('TYPE_REQUEST_SESSION_EXPIRED', 'request_session_expired');
define('TYPE_SETTLEMENT_EXPRESS_API', 'settle_express_api');
define('TYPE_SETTLEMENT_EXPRESS_CHECK', 'settle_express_check');
define('TYPE_SETTLEMENT_EXPRESS_SUBMIT', 'settle_express_submit');
define('TYPE_SETTLEMENT_EXPRESS_FORM', 'settle_express_form');
define('TYPE_LINK_ACCOUNT', 'link_account');//------Mikko 2019------// define('TYPE_LINK_ACCOUNT', 'link_account');//------Mikko 2019------//
define('TYPE_REMOVE_LINK', 'remove_link');//------Mikko 2019------// define('TYPE_REMOVE_LINK', 'remove_link');//------Mikko 2019------//
define('TYPE_NEW_DEV_CREDENTIAL', 'new_dev_credential'); define('TYPE_NEW_DEV_CREDENTIAL', 'new_dev_credential');
......
...@@ -123,6 +123,7 @@ define('VAL_STR_TARGET_COUNTRY', 'サービス主要対象国'); ...@@ -123,6 +123,7 @@ define('VAL_STR_TARGET_COUNTRY', 'サービス主要対象国');
define('VAL_STR_URL', 'URL'); define('VAL_STR_URL', 'URL');
define('VAL_STR_IP_ADDRESS_VALIDATION', 'IPアドレス確認'); define('VAL_STR_IP_ADDRESS_VALIDATION', 'IPアドレス確認');
define('VAL_STR_DOMAIN_NAME_VALIDATION', 'ドメイン名の確認'); define('VAL_STR_DOMAIN_NAME_VALIDATION', 'ドメイン名の確認');
define('VAL_STR_ALLOW_SERVER_TO_SERVER', 'ウェブサービスの許可');
define('VAL_STR_SITE_URL', 'サイトURL'); define('VAL_STR_SITE_URL', 'サイトURL');
define('VAL_STR_MANAGER_NAME', '口座取引責任者氏名'); define('VAL_STR_MANAGER_NAME', '口座取引責任者氏名');
define('VAL_STR_MANAGER_EMAIL', '責任者メールアドレス'); define('VAL_STR_MANAGER_EMAIL', '責任者メールアドレス');
......
...@@ -125,6 +125,7 @@ define('VAL_STR_TARGET_COUNTRY', 'Targeted country'); ...@@ -125,6 +125,7 @@ define('VAL_STR_TARGET_COUNTRY', 'Targeted country');
define('VAL_STR_URL', 'URL'); define('VAL_STR_URL', 'URL');
define('VAL_STR_IP_ADDRESS_VALIDATION', 'IP Address Validation'); define('VAL_STR_IP_ADDRESS_VALIDATION', 'IP Address Validation');
define('VAL_STR_DOMAIN_NAME_VALIDATION', 'Domain Name Validation'); define('VAL_STR_DOMAIN_NAME_VALIDATION', 'Domain Name Validation');
define('VAL_STR_ALLOW_SERVER_TO_SERVER', 'Allow Server-to-Server');
define('VAL_STR_SITE_URL', 'Website URL'); define('VAL_STR_SITE_URL', 'Website URL');
define('VAL_STR_MANAGER_NAME', 'Name of personal in charge of account'); define('VAL_STR_MANAGER_NAME', 'Name of personal in charge of account');
define('VAL_STR_MANAGER_EMAIL', 'E-mail address of personal in charge'); define('VAL_STR_MANAGER_EMAIL', 'E-mail address of personal in charge');
......
...@@ -385,6 +385,8 @@ define('PARAM_PIN', 'pin'); ...@@ -385,6 +385,8 @@ define('PARAM_PIN', 'pin');
define('PARAM_CODE', 'code'); define('PARAM_CODE', 'code');
define('PARAM_DATA', 'data'); define('PARAM_DATA', 'data');
define('PARAM_MONEYOUT_SOLUTION', 'moneyoutSolution'); define('PARAM_MONEYOUT_SOLUTION', 'moneyoutSolution');
define('PARAM_SETTLEMENT_ORIGIN', 'settlement_origin');
define('PARAM_SETTLEMENT_FREE_PARAMS', 'settlement_free_params');
define('PARAM_S_CARD_DEPOSIT_FLG', 's_card_deposit_flg'); define('PARAM_S_CARD_DEPOSIT_FLG', 's_card_deposit_flg');
......
{ {
"require": { "require": {
"aws/aws-sdk-php": "^3.140", "aws/aws-sdk-php": "^3.140",
"firebase/php-jwt": "^5.3" "firebase/php-jwt": "^5.3",
"defuse/php-encryption": "^2.3"
} }
} }
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "39d2d12ac9ec5ddf37a7adf68a2e7260", "content-hash": "eb718e51966814f232a0afef26dbca97",
"packages": [ "packages": [
{ {
"name": "aws/aws-sdk-php", "name": "aws/aws-sdk-php",
...@@ -90,6 +90,72 @@ ...@@ -90,6 +90,72 @@
], ],
"time": "2020-06-09T18:11:16+00:00" "time": "2020-06-09T18:11:16+00:00"
}, },
{
"name": "defuse/php-encryption",
"version": "v2.3.1",
"source": {
"type": "git",
"url": "https://github.com/defuse/php-encryption.git",
"reference": "77880488b9954b7884c25555c2a0ea9e7053f9d2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/defuse/php-encryption/zipball/77880488b9954b7884c25555c2a0ea9e7053f9d2",
"reference": "77880488b9954b7884c25555c2a0ea9e7053f9d2",
"shasum": ""
},
"require": {
"ext-openssl": "*",
"paragonie/random_compat": ">= 2",
"php": ">=5.6.0"
},
"require-dev": {
"phpunit/phpunit": "^4|^5|^6|^7|^8|^9"
},
"bin": [
"bin/generate-defuse-key"
],
"type": "library",
"autoload": {
"psr-4": {
"Defuse\\Crypto\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Hornby",
"email": "taylor@defuse.ca",
"homepage": "https://defuse.ca/"
},
{
"name": "Scott Arciszewski",
"email": "info@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "Secure PHP Encryption Library",
"keywords": [
"aes",
"authenticated encryption",
"cipher",
"crypto",
"cryptography",
"encrypt",
"encryption",
"openssl",
"security",
"symmetric key cryptography"
],
"support": {
"issues": "https://github.com/defuse/php-encryption/issues",
"source": "https://github.com/defuse/php-encryption/tree/v2.3.1"
},
"time": "2021-04-09T23:57:26+00:00"
},
{ {
"name": "firebase/php-jwt", "name": "firebase/php-jwt",
"version": "v5.3.0", "version": "v5.3.0",
...@@ -386,6 +452,56 @@ ...@@ -386,6 +452,56 @@
], ],
"time": "2019-12-30T18:03:34+00:00" "time": "2019-12-30T18:03:34+00:00"
}, },
{
"name": "paragonie/random_compat",
"version": "v9.99.100",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
"reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
"shasum": ""
},
"require": {
"php": ">= 7"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*",
"vimeo/psalm": "^1"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"polyfill",
"pseudorandom",
"random"
],
"support": {
"email": "info@paragonie.com",
"issues": "https://github.com/paragonie/random_compat/issues",
"source": "https://github.com/paragonie/random_compat"
},
"time": "2020-10-15T08:29:30+00:00"
},
{ {
"name": "psr/http-message", "name": "psr/http-message",
"version": "1.0.1", "version": "1.0.1",
...@@ -660,5 +776,6 @@ ...@@ -660,5 +776,6 @@
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": [], "platform": [],
"platform-dev": [] "platform-dev": [],
"plugin-api-version": "2.1.0"
} }
#!/usr/bin/env php
<?php
/**
* Proxy PHP file generated by Composer
*
* This file includes the referenced bin path (../defuse/php-encryption/bin/generate-defuse-key) using eval to remove the shebang if present
*
* @generated
*/
$binPath = realpath(__DIR__ . "/" . '../defuse/php-encryption/bin/generate-defuse-key');
$contents = file_get_contents($binPath);
$contents = preg_replace('{^#!/.+\r?\n<\?(php)?}', '', $contents, 1, $replaced);
if ($replaced) {
$contents = strtr($contents, array(
'__FILE__' => var_export($binPath, true),
'__DIR__' => var_export(dirname($binPath), true),
));
eval($contents);
exit(0);
}
include $binPath;
@ECHO OFF
setlocal DISABLEDELAYEDEXPANSION
SET BIN_TARGET=%~dp0/../defuse/php-encryption/bin/generate-defuse-key
php "%BIN_TARGET%" %*
...@@ -37,11 +37,13 @@ namespace Composer\Autoload; ...@@ -37,11 +37,13 @@ namespace Composer\Autoload;
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/ * @see https://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/ * @see https://www.php-fig.org/psr/psr-4/
*/ */
class ClassLoader class ClassLoader
{ {
private $vendorDir;
// PSR-4 // PSR-4
private $prefixLengthsPsr4 = array(); private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array(); private $prefixDirsPsr4 = array();
...@@ -57,10 +59,17 @@ class ClassLoader ...@@ -57,10 +59,17 @@ class ClassLoader
private $missingClasses = array(); private $missingClasses = array();
private $apcuPrefix; private $apcuPrefix;
private static $registeredLoaders = array();
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
}
public function getPrefixes() public function getPrefixes()
{ {
if (!empty($this->prefixesPsr0)) { if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0); return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
} }
return array(); return array();
...@@ -300,6 +309,17 @@ class ClassLoader ...@@ -300,6 +309,17 @@ class ClassLoader
public function register($prepend = false) public function register($prepend = false)
{ {
spl_autoload_register(array($this, 'loadClass'), true, $prepend); spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
} }
/** /**
...@@ -308,13 +328,17 @@ class ClassLoader ...@@ -308,13 +328,17 @@ class ClassLoader
public function unregister() public function unregister()
{ {
spl_autoload_unregister(array($this, 'loadClass')); spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
} }
/** /**
* Loads the given class or interface. * Loads the given class or interface.
* *
* @param string $class The name of the class * @param string $class The name of the class
* @return bool|null True if loaded, null otherwise * @return true|null True if loaded, null otherwise
*/ */
public function loadClass($class) public function loadClass($class)
{ {
...@@ -323,6 +347,8 @@ class ClassLoader ...@@ -323,6 +347,8 @@ class ClassLoader
return true; return true;
} }
return null;
} }
/** /**
...@@ -367,6 +393,16 @@ class ClassLoader ...@@ -367,6 +393,16 @@ class ClassLoader
return $file; return $file;
} }
/**
* Returns the currently registered loaders indexed by their corresponding vendor directories.
*
* @return self[]
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
private function findFileWithExtension($class, $ext) private function findFileWithExtension($class, $ext)
{ {
// PSR-4 lookup // PSR-4 lookup
......
This diff is collapsed.
...@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__)); ...@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
); );
...@@ -15,5 +15,6 @@ return array( ...@@ -15,5 +15,6 @@ return array(
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'), 'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'),
'Defuse\\Crypto\\' => array($vendorDir . '/defuse/php-encryption/src'),
'Aws\\' => array($vendorDir . '/aws/aws-sdk-php/src'), 'Aws\\' => array($vendorDir . '/aws/aws-sdk-php/src'),
); );
...@@ -13,19 +13,24 @@ class ComposerAutoloaderInit0256d657bbd336825ce06dd0b5c6ed01 ...@@ -13,19 +13,24 @@ class ComposerAutoloaderInit0256d657bbd336825ce06dd0b5c6ed01
} }
} }
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader() public static function getLoader()
{ {
if (null !== self::$loader) { if (null !== self::$loader) {
return self::$loader; return self::$loader;
} }
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInit0256d657bbd336825ce06dd0b5c6ed01', 'loadClassLoader'), true, true); spl_autoload_register(array('ComposerAutoloaderInit0256d657bbd336825ce06dd0b5c6ed01', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
spl_autoload_unregister(array('ComposerAutoloaderInit0256d657bbd336825ce06dd0b5c6ed01', 'loadClassLoader')); spl_autoload_unregister(array('ComposerAutoloaderInit0256d657bbd336825ce06dd0b5c6ed01', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) { if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php'; require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit0256d657bbd336825ce06dd0b5c6ed01::getInitializer($loader)); call_user_func(\Composer\Autoload\ComposerStaticInit0256d657bbd336825ce06dd0b5c6ed01::getInitializer($loader));
} else { } else {
......
...@@ -43,6 +43,10 @@ class ComposerStaticInit0256d657bbd336825ce06dd0b5c6ed01 ...@@ -43,6 +43,10 @@ class ComposerStaticInit0256d657bbd336825ce06dd0b5c6ed01
array ( array (
'Firebase\\JWT\\' => 13, 'Firebase\\JWT\\' => 13,
), ),
'D' =>
array (
'Defuse\\Crypto\\' => 14,
),
'A' => 'A' =>
array ( array (
'Aws\\' => 4, 'Aws\\' => 4,
...@@ -86,17 +90,26 @@ class ComposerStaticInit0256d657bbd336825ce06dd0b5c6ed01 ...@@ -86,17 +90,26 @@ class ComposerStaticInit0256d657bbd336825ce06dd0b5c6ed01
array ( array (
0 => __DIR__ . '/..' . '/firebase/php-jwt/src', 0 => __DIR__ . '/..' . '/firebase/php-jwt/src',
), ),
'Defuse\\Crypto\\' =>
array (
0 => __DIR__ . '/..' . '/defuse/php-encryption/src',
),
'Aws\\' => 'Aws\\' =>
array ( array (
0 => __DIR__ . '/..' . '/aws/aws-sdk-php/src', 0 => __DIR__ . '/..' . '/aws/aws-sdk-php/src',
), ),
); );
public static $classMap = array (
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
);
public static function getInitializer(ClassLoader $loader) public static function getInitializer(ClassLoader $loader)
{ {
return \Closure::bind(function () use ($loader) { return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit0256d657bbd336825ce06dd0b5c6ed01::$prefixLengthsPsr4; $loader->prefixLengthsPsr4 = ComposerStaticInit0256d657bbd336825ce06dd0b5c6ed01::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit0256d657bbd336825ce06dd0b5c6ed01::$prefixDirsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInit0256d657bbd336825ce06dd0b5c6ed01::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit0256d657bbd336825ce06dd0b5c6ed01::$classMap;
}, null, ClassLoader::class); }, null, ClassLoader::class);
} }
......
<?php return array(
'root' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '31d15e21dcaed1935c5dff47b9060339fb6eadac',
'name' => '__root__',
'dev' => true,
),
'versions' => array(
'__root__' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '31d15e21dcaed1935c5dff47b9060339fb6eadac',
'dev_requirement' => false,
),
'aws/aws-sdk-php' => array(
'pretty_version' => '3.140.4',
'version' => '3.140.4.0',
'type' => 'library',
'install_path' => __DIR__ . '/../aws/aws-sdk-php',
'aliases' => array(),
'reference' => '298ec070adad5760c4b90348219bb3e6bd7a9322',
'dev_requirement' => false,
),
'defuse/php-encryption' => array(
'pretty_version' => 'v2.3.1',
'version' => '2.3.1.0',
'type' => 'library',
'install_path' => __DIR__ . '/../defuse/php-encryption',
'aliases' => array(),
'reference' => '77880488b9954b7884c25555c2a0ea9e7053f9d2',
'dev_requirement' => false,
),
'firebase/php-jwt' => array(
'pretty_version' => 'v5.3.0',
'version' => '5.3.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../firebase/php-jwt',
'aliases' => array(),
'reference' => '3c2d70f2e64e2922345e89f2ceae47d2463faae1',
'dev_requirement' => false,
),
'guzzlehttp/guzzle' => array(
'pretty_version' => '6.5.4',
'version' => '6.5.4.0',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
'aliases' => array(),
'reference' => 'a4a1b6930528a8f7ee03518e6442ec7a44155d9d',
'dev_requirement' => false,
),
'guzzlehttp/promises' => array(
'pretty_version' => 'v1.3.1',
'version' => '1.3.1.0',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/promises',
'aliases' => array(),
'reference' => 'a59da6cf61d80060647ff4d3eb2c03a2bc694646',
'dev_requirement' => false,
),
'guzzlehttp/psr7' => array(
'pretty_version' => '1.6.1',
'version' => '1.6.1.0',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
'aliases' => array(),
'reference' => '239400de7a173fe9901b9ac7c06497751f00727a',
'dev_requirement' => false,
),
'mtdowling/jmespath.php' => array(
'pretty_version' => '2.5.0',
'version' => '2.5.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../mtdowling/jmespath.php',
'aliases' => array(),
'reference' => '52168cb9472de06979613d365c7f1ab8798be895',
'dev_requirement' => false,
),
'paragonie/random_compat' => array(
'pretty_version' => 'v9.99.100',
'version' => '9.99.100.0',
'type' => 'library',
'install_path' => __DIR__ . '/../paragonie/random_compat',
'aliases' => array(),
'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a',
'dev_requirement' => false,
),
'psr/http-message' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-message',
'aliases' => array(),
'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
'dev_requirement' => false,
),
'psr/http-message-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '1.0',
),
),
'ralouphie/getallheaders' => array(
'pretty_version' => '3.0.3',
'version' => '3.0.3.0',
'type' => 'library',
'install_path' => __DIR__ . '/../ralouphie/getallheaders',
'aliases' => array(),
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
'dev_requirement' => false,
),
'symfony/polyfill-intl-idn' => array(
'pretty_version' => 'v1.17.0',
'version' => '1.17.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
'aliases' => array(),
'reference' => '3bff59ea7047e925be6b7f2059d60af31bb46d6a',
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.17.0',
'version' => '1.17.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
'reference' => 'fa79b11539418b02fc5e1897267673ba2c19419c',
'dev_requirement' => false,
),
'symfony/polyfill-php72' => array(
'pretty_version' => 'v1.17.0',
'version' => '1.17.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php72',
'aliases' => array(),
'reference' => 'f048e612a3905f34931127360bdd2def19a5e582',
'dev_requirement' => false,
),
),
);
<?php
// platform_check.php @generated by Composer
$issues = array();
if (!(PHP_VERSION_ID >= 70000)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.0.0". You are running ' . PHP_VERSION . '.';
}
if ($issues) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
} elseif (!headers_sent()) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
}
}
trigger_error(
'Composer detected issues in your platform: ' . implode(' ', $issues),
E_USER_ERROR
);
}
The MIT License (MIT)
Copyright (c) 2016 Taylor Hornby <https://defuse.ca> and Paragon Initiative
Enterprises <https://paragonie.com>.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
php-encryption
===============
[![Build Status](https://travis-ci.org/defuse/php-encryption.svg?branch=master)](https://travis-ci.org/defuse/php-encryption)
[![codecov](https://codecov.io/gh/defuse/php-encryption/branch/master/graph/badge.svg)](https://codecov.io/gh/defuse/php-encryption)
[![Latest Stable Version](https://poser.pugx.org/defuse/php-encryption/v/stable)](https://packagist.org/packages/defuse/php-encryption)
[![License](https://poser.pugx.org/defuse/php-encryption/license)](https://packagist.org/packages/defuse/php-encryption)
[![Downloads](https://img.shields.io/packagist/dt/defuse/php-encryption.svg)](https://packagist.org/packages/defuse/php-encryption)
```terminal
composer require defuse/php-encryption
```
This is a library for encrypting data with a key or password in PHP. **It
requires PHP 5.6 or newer and OpenSSL 1.0.1 or newer.** We recommend using a
version of PHP that [still has security
support](https://www.php.net/supported-versions.php), which at the time of
writing means PHP 7.3 or later. Using this library with an unsupported
version of PHP could lead to security vulnerabilities.
The current version of `php-encryption` is v2.3.1. This library is expected to
remain stable and supported by its authors with security and bugfixes until at
least January 1st, 2022.
The library is a joint effort between [Taylor Hornby](https://defuse.ca/) and
[Scott Arciszewski](https://paragonie.com/blog/author/scott-arcizewski) as well
as numerous open-source contributors.
What separates this library from other PHP encryption libraries is, firstly,
that it is secure. The authors used to encounter insecure PHP encryption code on
a daily basis, so they created this library to bring more security to the
ecosystem. Secondly, this library is "difficult to misuse." Like
[libsodium](https://github.com/jedisct1/libsodium), its API is designed to be
easy to use in a secure way and hard to use in an insecure way.
Dependencies
------------
This library requires no special dependencies except for PHP 5.6 or newer with
the OpenSSL extensions (version 1.0.1 or later) enabled (this is the default).
It uses [random\_compat](https://github.com/paragonie/random_compat), which is
bundled in with this library so that your users will not need to follow any
special installation steps.
Getting Started
----------------
Start with the [**Tutorial**](docs/Tutorial.md). You can find instructions for
obtaining this library's code securely in the [Installing and
Verifying](docs/InstallingAndVerifying.md) documentation.
After you've read the tutorial and got the code, refer to the formal
documentation for each of the classes this library provides:
- [Crypto](docs/classes/Crypto.md)
- [File](docs/classes/File.md)
- [Key](docs/classes/Key.md)
- [KeyProtectedByPassword](docs/classes/KeyProtectedByPassword.md)
If you encounter difficulties, see the [FAQ](docs/FAQ.md) answers. The fixes to
the most commonly-reported problems are explained there.
If you're a cryptographer and want to understand the nitty-gritty details of how
this library works, look at the [Cryptography Details](docs/CryptoDetails.md)
documentation.
If you're interested in contributing to this library, see the [Internal
Developer Documentation](docs/InternalDeveloperDocs.md).
Other Language Support
----------------------
This library is intended for server-side PHP software that needs to encrypt data at rest.
If you are building software that needs to encrypt client-side, or building a system that
requires cross-platform encryption/decryption support, we strongly recommend using
[libsodium](https://download.libsodium.org/doc/bindings_for_other_languages) instead.
Examples
---------
If the documentation is not enough for you to understand how to use this
library, then you can look at an example project that uses this library:
- [encutil](https://github.com/defuse/encutil)
- [fileencrypt](https://github.com/tsusanka/fileencrypt)
Security Audit Status
---------------------
This code has not been subjected to a formal, paid, security audit. However, it
has received lots of review from members of the PHP security community, and the
authors are experienced with cryptography. In all likelihood, you are safer
using this library than almost any other encryption library for PHP.
If you use this library as a part of your business and would like to help fund
a formal audit, please [contact Taylor Hornby](https://defuse.ca/contact.htm).
Public Keys
------------
The GnuPG public key used to sign current and older releases is available in
[dist/signingkey.asc](https://github.com/defuse/php-encryption/raw/master/dist/signingkey.asc). Its fingerprint is:
```
2FA6 1D8D 99B9 2658 6BAC 3D53 385E E055 A129 1538
```
You can verify it against Taylor Hornby's [contact
page](https://defuse.ca/contact.htm) and
[twitter](https://twitter.com/DefuseSec/status/723741424253059074).
Due to the old key expiring, new releases will be signed with a new public key
available in [dist/signingkey-new.asc](https://github.com/defuse/php-encryption/raw/master/dist/signingkey-new.asc). Its fingerprint is:
```
6DD6 E677 0281 5846 FC85 25A3 DD2E 507F 7BDB 1669
```
A signature of this new key by the old key is available in
[dist/signingkey-new.asc.sig](https://github.com/defuse/php-encryption/raw/master/dist/signingkey-new.asc.sig).
#!/usr/bin/env php
<?php
use Defuse\Crypto\Key;
foreach ([__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoload.php'] as $file) {
if (file_exists($file)) {
require $file;
break;
}
}
$key = Key::createNewRandomKey();
echo $key->saveToAsciiSafeString(), "\n";
{
"name": "defuse/php-encryption",
"description": "Secure PHP Encryption Library",
"license": "MIT",
"keywords": ["security", "encryption", "AES", "openssl", "cipher", "cryptography", "symmetric key cryptography", "crypto", "encrypt", "authenticated encryption"],
"authors": [
{
"name": "Taylor Hornby",
"email": "taylor@defuse.ca",
"homepage": "https://defuse.ca/"
},
{
"name": "Scott Arciszewski",
"email": "info@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"autoload": {
"psr-4": {
"Defuse\\Crypto\\": "src"
}
},
"require": {
"paragonie/random_compat": ">= 2",
"ext-openssl": "*",
"php": ">=5.6.0"
},
"require-dev": {
"phpunit/phpunit": "^4|^5|^6|^7|^8|^9"
},
"bin": [
"bin/generate-defuse-key"
]
}
# This builds defuse-crypto.phar. To run this Makefile, `box` and `composer`
# must be installed and in your $PATH. Run it from inside the dist/ directory.
box := $(shell which box)
composer := $(shell which composer)
gitcommit := $(shell git rev-parse HEAD)
.PHONY: all
all: build-phar
.PHONY: sign-phar
sign-phar:
gpg -u DD2E507F7BDB1669 --armor --output defuse-crypto.phar.sig --detach-sig defuse-crypto.phar
# ensure we run in clean tree. export git tree and run there.
.PHONY: build-phar
build-phar:
@echo "Creating .phar from revision $(shell git rev-parse HEAD)."
rm -rf worktree
install -d worktree
(cd $(CURDIR)/..; git archive HEAD) | tar -x -C worktree
$(MAKE) -f $(CURDIR)/Makefile -C worktree defuse-crypto.phar
mv worktree/*.phar .
rm -rf worktree
.PHONY: clean
clean:
rm -vf defuse-crypto.phar defuse-crypto.phar.sig
# Inside workdir/:
defuse-crypto.phar: dist/box.json composer.lock
cp dist/box.json .
php -d phar.readonly=0 $(box) build -c box.json -v
composer.lock:
$(composer) config autoloader-suffix $(gitcommit)
$(composer) install --no-dev
{
"chmod": "0755",
"finder": [
{
"in": "src",
"name": "*.php"
},
{
"in": "vendor/composer",
"name": "*.php"
},
{
"in": "vendor/paragonie",
"name": "*.php",
"exclude": "other"
}
],
"compactors": [
"Herrera\\Box\\Compactor\\Php"
],
"main": "vendor/autoload.php",
"output": "defuse-crypto.phar",
"shebang": false,
"stub": true
}
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=Ysgx
-----END PGP PUBLIC KEY BLOCK-----
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2
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
IEgAL/CYqrk38w==
=lmD7
-----END PGP PUBLIC KEY BLOCK-----
Cryptography Details
=====================
Here is a high-level description of how this library works. Any discrepancy
between this documentation and the actual implementation will be considered
a security bug.
Let's start with the following definitions:
- HKDF-SHA256(*k*, *n*, *info*, *s*) is the key derivation function specified in
RFC 5869 (using the SHA256 hash function). The parameters are:
- *k*: The initial keying material.
- *n*: The number of output bytes.
- *info*: The info string.
- *s*: The salt.
- AES-256-CTR(*m*, *k*, *iv*) is AES-256 encryption in CTR mode. The parameters
are:
- *m*: An arbitrary-length (possibly zero-length) message.
- *k*: A 32-byte key.
- *iv*: A 16-byte initialization vector (nonce).
- PBKDF2-SHA256(*p*, *s*, *i*, *n*) is the password-based key derivation
function defined in RFC 2898 (using the SHA256 hash function). The parameters
are:
- *p*: The password string.
- *s*: The salt string.
- *i*: The iteration count.
- *n*: The output length in bytes.
- VERSION is the string `"\xDE\xF5\x02\x00"`.
- AUTHINFO is the string `"DefusePHP|V2|KeyForAuthentication"`.
- ENCRINFO is the string `"DefusePHP|V2|KeyForEncryption"`.
To encrypt a message *m* using a 32-byte key *k*, the following steps are taken:
1. Generate a random 32-byte string *salt*.
2. Derive the 32-byte authentication key *akey* = HKDF-SHA256(*k*, 32, AUTHINFO, *salt*).
3. Derive the 32-byte encryption key *ekey* = HKDF-SHA256(*k*, 32, ENCRINFO, *salt*).
4. Generate a random 16-byte initialization vector *iv*.
5. Compute *c* = AES-256-CTR(*m*, *ekey*, *iv*).
6. Combine *ctxt* = VERSION || *salt* || *iv* || *c*.
7. Compute *h* = HMAC-SHA256(*ctxt*, *akey*).
8. Output *ctxt* || *h*.
Decryption is roughly the reverse process (see the code for details, since the
security of the decryption routine is highly implementation-dependent).
For encryption using a password *p*, steps 1-3 above are replaced by:
1. Generate a random 32-byte string *salt*.
2. Compute *k* = PBKDF2-SHA256(SHA256(*p*), *salt*, 100000, 32).
3. Derive the 32-byte authentication key *akey* = HKDF-SHA256(*k*, 32, AUTHINFO, *salt*)
4. Derive the 32-byte encryption key *ekey* = HKDF-SHA256(*k*, 32, ENCRINFO, *salt*)
The remainder of the process is the same. Notice the reuse of the same *salt*
for PBKDF2-SHA256 and HKDF-SHA256. The prehashing of the password in step 2 is
done to prevent a [DoS attack using long
passwords](https://github.com/defuse/php-encryption/issues/230).
For `KeyProtectedByPassword`, the serialized key is encrypted according to the
password encryption defined above. However, the actual password used for
encryption is the SHA256 hash of the password the user provided. This is done in
order to provide domain separation between the message encryption in the user's
application and the internal key encryption done by this library. It fixes
a [key replacement chosen-protocol
attack](https://github.com/defuse/php-encryption/issues/240).
Frequently Asked Questions
===========================
How do I use this library to encrypt passwords?
------------------------------------------------
Passwords should not be encrypted, they should be hashed with a *slow* password
hashing function that's designed to slow down password guessing attacks. See
[How to Safely Store Your Users' Passwords in
2016](https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016).
How do I give it the same key every time instead of a new random key?
----------------------------------------------------------------------
A `Key` object can be saved to a string by calling its `saveToAsciiSafeString()`
method. You will have to save that string somewhere safe, and then load it back
into a `Key` object using `Key`'s `loadFromAsciiSafeString` static method.
Where you store the string depends on your application. For example if you are
using `KeyProtectedByPassword` to encrypt files with a user's login password,
then you should not store the `Key` at all. If you are protecting sensitive data
on a server that may be compromised, then you should store it in a hardware
security module. When in doubt, consult a security expert.
Why is an EnvironmentIsBrokenException getting thrown?
-------------------------------------------------------
Either you've encountered a bug in this library, or your system doesn't support
the use of this library. For example, if your system does not have a secure
random number generator, this library will refuse to run, by throwing that
exception, instead of falling back to an insecure random number generator.
Why am I getting a BadFormatException when loading a Key from a string?
------------------------------------------------------------------------
If you're getting this exception, then the string you're giving to
`loadFromAsciiSafeString()` is *not* the same as the string you got from
`saveToAsciiSafeString()`. Perhaps your database column isn't wide enough and
it's truncating the string as you insert it?
Does encrypting hide the length of the plaintext?
--------------------------------------------------
Encryption does not, and is not intended to, hide the length of the data being
encrypted. For example, it is not safe to encrypt a field in which only a small
number of different-length values are possible (e.g. "male" or "female") since
it would be possible to tell what the plaintext is by looking at the length of
the ciphertext. In order to do this safely, it is your responsibility to, before
encrypting, pad the data out to the length of the longest string that will ever
be encrypted. This way, all plaintexts are the same length, and no information
about the plaintext can be gleaned from the length of the ciphertext.
Getting The Code
=================
There are two ways to use this library in your applications. You can either:
1. Use [Composer](https://getcomposer.org/), or
2. `require_once` a single `.phar` file in your application.
If you are not using either option (for example, because you're using Git submodules), you may need to write your own autoloader ([example](https://gist.github.com/paragonie-scott/949daee819bb7f19c50e5e103170b400)).
Option 1: Using Composer
-------------------------
Run this inside the directory of your composer-enabled project:
```sh
composer require defuse/php-encryption
```
Unfortunately, composer doesn't provide a way for you to verify that the code
you're getting was signed by this library's authors. If you want a more secure
option, use the `.phar` method described below.
Option 2: Including a PHAR
----------------------------
The `.phar` option lets you include this library into your project simply by
calling `require_once` on a single file. Download `defuse-crypto.phar` and
`defuse-crypto.phar.sig` from this project's
[releases](https://github.com/defuse/php-encryption/releases) page.
You should verify the integrity of the `.phar`. The `defuse-crypto.phar.sig`
contains the signature of `defuse-crypto.phar`. It is signed with Taylor
Hornby's PGP key. You can find Taylor's public key in `dist/signingkey.asc`. You
can verify the public key's fingerprint against the Taylor Hornby's [contact
page](https://defuse.ca/contact.htm) and
[twitter](https://twitter.com/DefuseSec/status/723741424253059074).
Once you have verified the signature, it is safe to use the `.phar`. Place it
somewhere in your file system, e.g. `/var/www/lib/defuse-crypto.phar`, and then
pass that path to `require_once`.
```php
<?php
require_once('/var/www/lib/defuse-crypto.phar');
// ... the Crypto, File, Key, and KeyProtectedByPassword classes are now
// available ...
// ...
```
Information for the Developers of php-encryption
=================================================
Status
-------
This library is currently frozen under a long-term support release. We do not
plan to add any new features. We will maintain the library by fixing any bugs
that are reported, or security vulnerabilities that are found.
Development Environment
------------------------
Development is done on Linux. To run the tests, you will need to have the
following tools installed:
- `php` (with OpenSSL enabled, if you're compiling from source).
- `gpg`
- `composer`
Running the Tests
------------------
First do `composer install` and then you can run the tests by running
`./test.sh`. This will download a PHPUnit PHAR, verify its cryptographic
signatures, and then use it to run the tests in `test/unit`.
Getting and Using Psalm
-----------------------
[Psalm](https://github.com/vimeo/psalm) is a static analysis suite for PHP projects.
We use Psalm to ensure type safety throughout our library.
To install Psalm, you just need to run one command:
composer require --dev "vimeo/psalm:dev-master"
To verify that your code changes are still strictly type-safe, run the following
command:
vendor/bin/psalm
Reporting Bugs
---------------
Please report bugs, even critical security vulnerabilities, by opening an issue
on GitHub. We recommend disclosing security vulnerabilities found in this
library *publicly* as soon as possible.
Philosophy
-----------
This library is developed around several core values:
- Rule #1: Security is prioritized over everything else.
> Whenever there is a conflict between security and some other property,
> security will be favored. For example, the library has runtime tests,
> which make it slower, but will hopefully stop it from encrypting stuff
> if the platform it's running on is broken.
- Rule #2: It should be difficult to misuse the library.
> We assume the developers using this library have no experience with
> cryptography. We only assume that they know that the "key" is something
> you need to encrypt and decrypt the messages, and that it must be kept
> secret. Whenever possible, the library should refuse to encrypt or decrypt
> messages when it is not being used correctly.
- Rule #3: The library aims only to be compatible with itself.
> Other PHP encryption libraries try to support every possible type of
> encryption, even the insecure ones (e.g. ECB mode). Because there are so
> many options, inexperienced developers must decide whether to use "CBC
> mode" or "ECB mode" when both are meaningless terms to them. This
> inevitably leads to vulnerabilities.
> This library will only support one secure mode. A developer using this
> library will call "encrypt" and "decrypt" methods without worrying about
> how they are implemented.
- Rule #4: The library should require no special installation.
> Some PHP encryption libraries, like libsodium-php, are not straightforward
> to install and cannot packaged with "just download and extract"
> applications. This library will always be just a handful of PHP files that
> you can copy to your source tree and require().
Publishing Releases
--------------------
To make a release, you will need to install [composer](https://getcomposer.org/)
and [box](https://github.com/box-project/box2) on your system. They will need to
be available in your `$PATH` so that running the commands `composer` and `box`
in your terminal run them, respectively. You will also need the private key for
signing (ID: 7B4B2D98) available.
Once you have those tools installed and the key available follow these steps:
**Remember to set the version number in `composer.json`!**
Make a fresh clone of the repository:
```
git clone <url>
```
Check out the branch you want to release:
```
git checkout <branchname>
```
Check that the version number in composer.json is correct:
```
cat composer.json
```
Check that the version number and support lifetime in README.md are correct:
```
cat README.md
```
Run the tests:
```
composer install
./test.sh
```
Generate the `.phar`:
```
cd dist
make build-phar
```
Test the `.phar`:
```
cd ../
./test.sh dist/defuse-crypto.phar
```
Sign the `.phar`:
```
cd dist
make sign-phar
```
Tag the release:
```
git -c user.signingkey=DD2E507F7BDB1669 tag -s "<TAG NAME>" -m "<TAG MESSAGE>"
```
`<TAG NAME>` should be in the format `v2.0.0` and `<TAG MESSAGE>` should look
like "Release of v2.0.0."
Push the tag to github, then use the
[releases](https://github.com/defuse/php-encryption/releases) page to draft
a new release for that tag. Upload the `.phar` and the `.phar.sig` file to be
included as part of that release.
This diff is collapsed.
Upgrading From Version 1.2
===========================
With version 2.0.0 of this library came major changes to the ciphertext format,
algorithms used for encryption, and API.
In version 1.2, keys were represented by 16-byte string variables. In version
2.0.0, keys are represented by objects, instances of the `Key` class. This
change was made in order to make it harder to misuse the API. For example, in
version 1.2, you could pass in *any* 16-byte string, but in version 2.0.0 you
need a `Key` object, which you can only get if you're "doing the right thing."
This means that for all of your old version 1.2 keys, you'll have to:
1. Generate a new version 2.0.0 key.
2. For all of the ciphertexts encrypted under the old key:
1. Decrypt the ciphertext using the old version 1.2 key.
2. Re-encrypt it using the new version 2.0.0 key.
Use the special `Crypto::legacyDecrypt()` method to decrypt the old ciphertexts
using the old key and then re-encrypt them using `Crypto::encrypt()` with the
new key. Your code will look something like the following. To avoid data loss,
securely back up your keys and data before running your upgrade code.
```php
<?php
// ...
$legacy_ciphertext = // ... get the ciphertext you want to upgrade ...
$legacy_key = // ... get the key to decrypt this ciphertext ...
// Generate the new key that we'll re-encrypt the ciphertext with.
$new_key = Key::createNewRandomKey();
// ... save it somewhere ...
// Decrypt it.
try {
$plaintext = Crypto::legacyDecrypt($legacy_ciphertext, $legacy_key);
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex)
{
// ... TODO: handle this case appropriately ...
}
// Re-encrypt it.
$new_ciphertext = Crypto::encrypt($plaintext, $new_key);
// ... replace the old $legacy_ciphertext with the new $new_ciphertext
// ...
```
Class: Defuse\Crypto\Key
=========================
The `Key` class represents a secret key used for encrypting and decrypting. Once
you have a `Key` instance, you can use it with the `Crypto` class to encrypt and
decrypt strings and with the `File` class to encrypt and decrypt files.
Instance Methods
-----------------
### saveToAsciiSafeString()
**Description:**
Saves the encryption key to a string of printable ASCII characters, which can be
loaded again into a `Key` instance using `Key::loadFromAsciiSafeString()`.
**Parameters:**
This method does not take any parameters.
**Return value:**
Returns a string of printable ASCII characters representing this `Key` instance,
which can be loaded back into an instance of `Key` using
`Key::loadFromAsciiSafeString()`.
**Exceptions:**
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
the platform the code is running on cannot safely perform encryption for some
reason (e.g. it lacks a secure random number generator), or the runtime tests
detected a bug in this library.
**Side-effects and performance:**
None.
**Cautions:**
This method currently returns a hexadecimal string. You should not rely on this
behavior. For example, it may be improved in the future to return a base64
string.
Static Methods
---------------
### Key::createNewRandomKey()
**Description:**
Generates a new random key and returns an instance of `Key`.
**Parameters:**
This method does not take any parameters.
**Return value:**
Returns an instance of `Key` containing a randomly-generated encryption key.
**Exceptions:**
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
the platform the code is running on cannot safely perform encryption for some
reason (e.g. it lacks a secure random number generator), or the runtime tests
detected a bug in this library.
**Side-effects and performance:**
None.
**Cautions:**
None.
### Key::loadFromAsciiSafeString($saved\_key\_string, $do\_not\_trim = false)
**Description:**
Loads an instance of `Key` that was saved to a string by
`saveToAsciiSafeString()`.
By default, this function will call `Encoding::trimTrailingWhitespace()`
to remove trailing CR, LF, NUL, TAB, and SPACE characters, which are commonly
appended to files when working with text editors.
**Parameters:**
1. `$saved_key_string` is the string returned from `saveToAsciiSafeString()`
when the original `Key` instance was saved.
2. `$do_not_trim` should be set to `TRUE` if you do not wish for the library
to automatically strip trailing whitespace from the string.
**Return value:**
Returns an instance of `Key` representing the same encryption key as the one
that was represented by the `Key` instance that got saved into
`$saved_key_string` by a call to `saveToAsciiSafeString()`.
**Exceptions:**
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
the platform the code is running on cannot safely perform encryption for some
reason (e.g. it lacks a secure random number generator), or the runtime tests
detected a bug in this library.
- `Defuse\Crypto\Exception\BadFormatException` is thrown whenever
`$saved_key_string` does not represent a valid `Key` instance.
**Side-effects and performance:**
None.
**Cautions:**
None.
This diff is collapsed.
This diff is collapsed.
<?php
namespace Defuse\Crypto;
/**
* Class DerivedKeys
* @package Defuse\Crypto
*/
final class DerivedKeys
{
/**
* @var string
*/
private $akey = '';
/**
* @var string
*/
private $ekey = '';
/**
* Returns the authentication key.
* @return string
*/
public function getAuthenticationKey()
{
return $this->akey;
}
/**
* Returns the encryption key.
* @return string
*/
public function getEncryptionKey()
{
return $this->ekey;
}
/**
* Constructor for DerivedKeys.
*
* @param string $akey
* @param string $ekey
*/
public function __construct($akey, $ekey)
{
$this->akey = $akey;
$this->ekey = $ekey;
}
}
This diff is collapsed.
<?php
namespace Defuse\Crypto\Exception;
class BadFormatException extends \Defuse\Crypto\Exception\CryptoException
{
}
<?php
namespace Defuse\Crypto\Exception;
class CryptoException extends \Exception
{
}
<?php
namespace Defuse\Crypto\Exception;
class EnvironmentIsBrokenException extends \Defuse\Crypto\Exception\CryptoException
{
}
<?php
namespace Defuse\Crypto\Exception;
class IOException extends \Defuse\Crypto\Exception\CryptoException
{
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm
pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p
+h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc
-----END PUBLIC KEY-----
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment