Compare commits
82 Commits
v0.0.3
..
db39cea49b
| Author | SHA1 | Date | |
|---|---|---|---|
| db39cea49b | |||
| 41fe987f5d | |||
| f391716de4 | |||
| 7f0aff735f | |||
| f08abbe9f6 | |||
| 74f3b1d282 | |||
| 346073b544 | |||
| 81f0c4c233 | |||
| 626f381c1b | |||
| 76024459a9 | |||
| aea41d6ac5 | |||
| 92af9cdd81 | |||
| b9de6b4a98 | |||
| b0747071e9 | |||
| f64576f3e8 | |||
| 9009ec13fb | |||
| dc77c56b43 | |||
| a3bd756566 | |||
| c54974811c | |||
| 3ca0ce7600 | |||
| d323cc274b | |||
| 49e0c1191f | |||
| 862d129d00 | |||
| 615f09399d | |||
| 0c400e3918 | |||
| f2e9e1550e | |||
| 18c2b8668c | |||
| 3c31423bb1 | |||
| e27259dca9 | |||
| b949c910ea | |||
| 944ec49640 | |||
| ae98daa2ec | |||
| 902e0031d4 | |||
| 34406d81fa | |||
| 7e7080f23c | |||
| 10917727a8 | |||
| 4d4c75aa48 | |||
| cf8c2131bd | |||
| dff9b496cf | |||
| 961b003078 | |||
| 44e2295bb7 | |||
| cf2e761c5a | |||
| c2d4a49eb2 | |||
| 1b025a1563 | |||
| 83a246ee6e | |||
| 65e7601bda | |||
| ee4b81e348 | |||
| d88c823b9f | |||
| 7d7f5c00dc | |||
| 31ae9aa725 | |||
| e7f26e9a39 | |||
| 999520c31f | |||
| 285a4c2cfa | |||
| 45193b66b8 | |||
| 8a9df7b1df | |||
| b992d1f9b4 | |||
| 2261ab9d72 | |||
| 7447f7d96e | |||
| 0cc56dd4df | |||
| dabec5c244 | |||
| efc87db1ca | |||
| ad56540080 | |||
| 6d8cdc01ee | |||
| 6c40d4f22e | |||
| ef45fd4b6b | |||
| 76983004a6 | |||
| f3c2c37326 | |||
| 54296bf7d6 | |||
| e122fb93fc | |||
| cff0929205 | |||
| 8b8eaf88f9 | |||
| 46ed530ec1 | |||
| 2b38b02530 | |||
| 90ee3dd46f | |||
| f1e5d7eec7 | |||
| 0cd1f321f9 | |||
| 6956c7f409 | |||
| a456043ced | |||
| 1edcd3ea58 | |||
| 80d5044534 | |||
| f8b262ae54 | |||
| 6cce6a0a45 |
@@ -1,4 +1,4 @@
|
||||
FROM node:boron
|
||||
FROM node:erbium
|
||||
|
||||
# Create app directory
|
||||
RUN mkdir -p /usr/src/app
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
version: '3'
|
||||
services:
|
||||
flutterwave-transfer-micro:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
restart: unless-stopped
|
||||
image: registry.chiefsoft.net/flutterwave-transfer-micro:latest
|
||||
volumes:
|
||||
- ./:/app
|
||||
- '/app/node_modules'
|
||||
ports:
|
||||
- 9086:3000
|
||||
environment:
|
||||
- PORT=3000
|
||||
- POSTGRE_URL='postgresql://wrenchboard:wrenchboard@10.10.10.23:5432/wrenchboard'
|
||||
- FLUTTERWAVE_API='eyJCYXNlQXBpVXJsIjoiaHR0cHM6Ly9hcGkuZmx1dHRlcndhdmUuY29tIiwiUHVibGljS2V5IjoiRkxXUFVCS19URVNULTU0YzkwMTQxYjAyODc4OWQ2NzEwNjdiZDcyZjc4MWE5LVgiLCJTZWNyZXRLZXkiOiJGTFdTRUNLX1RFU1QtYzdiYmM4NmQ3ZTcxMDAyNTRjNWU1YmJmMTYyYmYyYjItWCIsIkVuY3J5cHRpb25LZXkiOiJGTFdTRUNLX1RFU1RlOTQ3NGQ0ZTJjZTYifQ=='
|
||||
volumes:
|
||||
src:
|
||||
+1696
-219
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "flutterwave-transfer-micro",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.4",
|
||||
"description": "A microservice to handle flutterware payment services",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
@@ -15,8 +15,12 @@
|
||||
"axios": "^0.24.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"express": "^4.17.1",
|
||||
"openapi-types": "^10.0.0",
|
||||
"pg": "8.7.1",
|
||||
"request": "^2.88.2",
|
||||
"swagger-autogen": "^2.17.2",
|
||||
"swagger-jsdoc": "^6.1.0",
|
||||
"swagger-ui-express": "^4.3.0",
|
||||
"underscore": "^1.8.3",
|
||||
"winston": "^2.3.1",
|
||||
"winston-papertrail": "^1.0.4"
|
||||
|
||||
@@ -1,8 +1,145 @@
|
||||
const express = require('express');
|
||||
const logger = require('./app/logger');
|
||||
const app = express();
|
||||
const swaggerUI = require('swagger-ui-express');
|
||||
const swaggerJSDocs = require('swagger-jsdoc');
|
||||
|
||||
const port = process.env.PORT || 3000;
|
||||
|
||||
const definition = {
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"version": "0.0.4",
|
||||
"title": "flutterwave-transfer-micro",
|
||||
"description": "A microservice to handle flitterware payment services"
|
||||
},
|
||||
"host": "localhost:3000",
|
||||
"basePath": "/",
|
||||
"tags": [],
|
||||
"schemes": [
|
||||
"http"
|
||||
],
|
||||
"consumes": ['application/json'],
|
||||
"produces": ['application/json'],
|
||||
"paths": {
|
||||
"/about": {
|
||||
"get": {
|
||||
"tags": [],
|
||||
"description": "About the microservice (service status)",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/create": {
|
||||
"post": {
|
||||
"tags": [],
|
||||
"description": "Create new transfer",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"parameters": [{
|
||||
"name":"transfer",
|
||||
"in": "body",
|
||||
"description": "Transfer to create",
|
||||
"required": true,
|
||||
"type":"object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/NewTransfer"
|
||||
},
|
||||
"example": {
|
||||
"account_bank": "044",
|
||||
"account_number": "0690000040",
|
||||
"amount": 5500,
|
||||
"narration": "Akhlm Pstmn Trnsfr xx007",
|
||||
"currency": "NGN",
|
||||
"reference": "akhlm-pstmnpyt-rfxx007_PMCKDU_1",
|
||||
"debit_currency": "NGN"
|
||||
}
|
||||
}],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/status/{id}": {
|
||||
"get": {
|
||||
"tags": [],
|
||||
"description": "Get transfer status",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"NewTransfer": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"account_bank",
|
||||
"account_number",
|
||||
"amount",
|
||||
"narration",
|
||||
"currency",
|
||||
"reference",
|
||||
"debit_currency"
|
||||
],
|
||||
"properties": {
|
||||
"account_bank": {
|
||||
"type": "string"
|
||||
},
|
||||
"account_number": {
|
||||
"type": "string"
|
||||
},
|
||||
"amount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"narration": {
|
||||
"type": "string"
|
||||
},
|
||||
"currency": {
|
||||
"type": "string"
|
||||
},
|
||||
"reference": {
|
||||
"type": "string"
|
||||
},
|
||||
"debit_currency": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const options = {
|
||||
definition,
|
||||
apis: ['./server.js'],
|
||||
};
|
||||
|
||||
const swaggerSpec = swaggerJSDocs(options);
|
||||
|
||||
const app = express();
|
||||
|
||||
app.get('/swagger.json', (req, res) => {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.send(swaggerSpec);
|
||||
});
|
||||
app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(swaggerSpec));
|
||||
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded());
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
const swaggerAutogen = require('swagger-autogen')();
|
||||
|
||||
const outputFile = './swagger.json';
|
||||
const endpointsFiles = ['./api/routes.js']
|
||||
|
||||
swaggerAutogen(outputFile, endpointsFiles).then(() => {
|
||||
require('./server.js')
|
||||
})
|
||||
@@ -16,17 +16,16 @@ img {height: auto;}
|
||||
.subhead {font-size: 12px; color: #ffffff; font-family: sans-serif; letter-spacing: 3px;}
|
||||
.h1, .h2, .bodycopy {color: #153643; font-family: sans-serif;}
|
||||
.h1 {font-size: 33px; line-height: 38px; font-weight: bold;}
|
||||
.h2 {padding: 0 0 15px 0; font-size: 24px; line-height: 28px; font-weight: bold;}
|
||||
.bodycopy {font-size: 14px; line-height: 20px;}
|
||||
.button {text-align: center; font-size: 16px; font-family: sans-serif; font-weight: bold; padding: 0 30px 0 30px;}
|
||||
.button a {color: #ffffff; text-decoration: none;}
|
||||
.footer {padding: 20px 30px 15px 30px;}
|
||||
.footer {padding: 20px 30px 15px 30px; bgcolor:#007bff; background-color:#007bff;}
|
||||
.footercopy {font-family: sans-serif; font-size: 14px; color: #ffffff;}
|
||||
.footercopy a {color: #ffffff; text-decoration: underline;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body yahoo bgcolor="#f6f8f1">
|
||||
<body bgcolor="#f6f8f1">
|
||||
<table width="100%" bgcolor="#f6f8f1" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td>
|
||||
@@ -50,12 +49,12 @@ img {height: auto;}
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
|
||||
<tr>
|
||||
<td class="h1" style="padding: 5px 0 0 0;">
|
||||
{{site_name}}
|
||||
<td style="padding: 1px 0 1px 0; text-align:center;">
|
||||
<a href="https://www.wrenchboard.com/"><img src="https://dashboard.wrenchboard.com/assets/ext/images/wrenchboard.png" alt="WrenchBoard"></a> <!-- {{site_name}} -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="subhead" style="padding: 0 0 0 3px;">
|
||||
<td class="subhead" style="padding: 0 0 0 3px; text-align:center;">
|
||||
{{site_trade_name}}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -131,13 +130,12 @@ For all support, contact us at <a href="https://{{server_name}}/contact">https:
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="footer" bgcolor="#44525f">
|
||||
<td class="footer">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="center" class="footercopy">
|
||||
® {{site_name}} 2018<br/>
|
||||
You received this email because you subscribe to {{site_name}}. If you get this email in error, please <a href="https://{{server_name}}/contactus" class="unsubscribe"><font color="#ffffff">contact</font></a> us.
|
||||
|
||||
® {{site_name}} 2022<br/>
|
||||
You received this email because you subscribe to {{site_name}}. If you get this email in error, please <a href="https://{{server_name}}/contact" class="unsubscribe"><font color="#ffffff">contact</font></a> us.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -150,7 +148,7 @@ You received this email because you subscribe to {{site_name}}. If you get this
|
||||
</a>
|
||||
</td>
|
||||
<td width="37" style="text-align: center; padding: 0 10px 0 10px;">
|
||||
<a href="https://twitter.com/wrenchboard">
|
||||
<a href="http://www.twitter.com/">
|
||||
<img src="https://{{server_name}}/assets/images/brands/twitter.png" width="37" height="37" alt="Twitter" border="0" />
|
||||
</a>
|
||||
</td>
|
||||
@@ -171,7 +169,8 @@ You received this email because you subscribe to {{site_name}}. If you get this
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--analytics-->
|
||||
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Subject: {{site_name}} - Log in Confirmation
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta charset="utf-8">
|
||||
<title>{{site_name}} - Log in Confirmation</title>
|
||||
<style type="text/css">
|
||||
body {margin: 0; padding: 0; min-width: 100%!important;}
|
||||
@@ -16,17 +16,16 @@ img {height: auto;}
|
||||
.subhead {font-size: 12px; color: #ffffff; font-family: sans-serif; letter-spacing: 3px;}
|
||||
.h1, .h2, .bodycopy {color: #153643; font-family: sans-serif;}
|
||||
.h1 {font-size: 33px; line-height: 38px; font-weight: bold;}
|
||||
.h2 {padding: 0 0 15px 0; font-size: 24px; line-height: 28px; font-weight: bold;}
|
||||
.bodycopy {font-size: 14px; line-height: 20px;}
|
||||
.button {text-align: center; font-size: 16px; font-family: sans-serif; font-weight: bold; padding: 0 30px 0 30px;}
|
||||
.button a {color: #ffffff; text-decoration: none;}
|
||||
.footer {padding: 20px 30px 15px 30px;}
|
||||
.footer {padding: 20px 30px 15px 30px; bgcolor:#007bff; background-color:#007bff;}
|
||||
.footercopy {font-family: sans-serif; font-size: 14px; color: #ffffff;}
|
||||
.footercopy a {color: #ffffff; text-decoration: underline;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body yahoo bgcolor="#f6f8f1">
|
||||
<body bgcolor="#f6f8f1">
|
||||
<table width="100%" bgcolor="#f6f8f1" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td>
|
||||
@@ -43,18 +42,18 @@ img {height: auto;}
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
<table class="col425" align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 425px;">
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 600px;">
|
||||
<tr>
|
||||
<td height="50">
|
||||
<td height="30" border="0" style="text-align:center;">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
|
||||
<tr>
|
||||
<td class="h1" style="padding: 5px 0 0 0;">
|
||||
{{site_name}}
|
||||
<td style="padding: 1px 0 1px 0; text-align:center;">
|
||||
<a href="https://www.wrenchboard.com/"><img src="https://dashboard.wrenchboard.com/assets/ext/images/wrenchboard.png" alt="WrenchBoard"></a> <!-- {{site_name}} -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="subhead" style="padding: 0 0 0 3px;">
|
||||
<td class="subhead" style="padding: 0 0 0 3px; text-align:center;">
|
||||
{{site_trade_name}}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -69,18 +68,7 @@ img {height: auto;}
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="innerpadding borderbottom">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td>
|
||||
Hello {{firstname}},
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="innerpadding borderbottom">
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
@@ -90,29 +78,22 @@ Hello {{firstname}},
|
||||
<![endif]-->
|
||||
<table class="col380" align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%;">
|
||||
<tr>
|
||||
<td class="bodycopy">
|
||||
Hello {{firstname}},
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td class="bodycopy">
|
||||
Please be informed that you logged on to {{site_name}} account at <b>{{last_login2}}</b> from <b>{{loc}}</b>.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="bodycopy">
|
||||
Please be informed that you logged on to {{site_name}} account at <b>{{last_login2}}</b>.
|
||||
If you did not log on to your account at the time detailed above, please contact us immediately.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</table>
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
</td>
|
||||
@@ -156,12 +137,12 @@ Recently added task(s)
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="footer" bgcolor="#44525f">
|
||||
<td class="footer">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="center" class="footercopy">
|
||||
® {{site_name}} 2018<br/>
|
||||
You received this email because you subscribe to {{site_name}}. If you get this email in error, please <a href="https://{{server_name}}/contactus" class="unsubscribe"><font color="#ffffff">contact</font></a> us.
|
||||
® {{site_name}} 2022<br/>
|
||||
You received this email because you subscribe to {{site_name}}. If you get this email in error, please <a href="https://{{server_name}}/contact" class="unsubscribe"><font color="#ffffff">contact</font></a> us.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -195,8 +176,5 @@ You received this email because you subscribe to {{site_name}}. If you get this
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--analytics-->
|
||||
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -97,7 +97,7 @@ body[yahoo] .unsubscribe {display: block; margin-top: 20px; padding: 10px 50px;
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td>
|
||||
Dear {{firstname}},
|
||||
Dear {{firstname}},
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -4,33 +4,28 @@ Subject: {{site_name}} - Pending Signup - Verify {{email}}
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta charset="utf-8">
|
||||
<title>{{site_name}} - Pending Signup - Verify {{email}}</title>
|
||||
<style type="text/css">
|
||||
body {margin: 0; padding: 0; min-width: 100%!important;}
|
||||
img {height: auto;}
|
||||
.content {width: 100%; max-width: 600px;}
|
||||
.header {padding: 10px 10px 10px 10px;}
|
||||
.innerpadding {padding: 30px 30px 30px 30px;}
|
||||
.innerpadding {padding: 10px 10px 10px 10px;}
|
||||
.borderbottom {border-bottom: 1px solid #f2eeed;}
|
||||
.subhead {font-size: 12px; color: #ffffff; font-family: sans-serif; letter-spacing: 3px;}
|
||||
.h1, .h2, .bodycopy {color: #153643; font-family: sans-serif;}
|
||||
.h1 {font-size: 33px; line-height: 38px; font-weight: bold;}
|
||||
.h2 {padding: 0 0 15px 0; font-size: 24px; line-height: 28px; font-weight: bold;}
|
||||
.h3 {padding: 0 0 15px 0; font-size: 20px; line-height: 20px; font-weight: bold;}
|
||||
.bodycopy {font-size: 16px; line-height: 22px;}
|
||||
.button {text-align: center; font-size: 18px; font-family: sans-serif; font-weight: bold; padding: 0 30px 0 30px;}
|
||||
.bodycopy {font-size: 14px; line-height: 20px;}
|
||||
.button {text-align: center; font-size: 16px; font-family: sans-serif; font-weight: bold; padding: 0 30px 0 30px;}
|
||||
.button a {color: #ffffff; text-decoration: none;}
|
||||
.footer {padding: 20px 30px 15px 30px;}
|
||||
.footer {padding: 20px 30px 15px 30px; bgcolor:#007bff; background-color:#007bff;}
|
||||
.footercopy {font-family: sans-serif; font-size: 14px; color: #ffffff;}
|
||||
.footercopy a {color: #ffffff; text-decoration: underline;}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body yahoo bgcolor="#f6f8f1">
|
||||
<body bgcolor="#f6f8f1">
|
||||
<table width="100%" bgcolor="#f6f8f1" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td>
|
||||
@@ -47,18 +42,18 @@ img {height: auto;}
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
<table class="col425" align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 100%;">
|
||||
<table align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 600px;">
|
||||
<tr>
|
||||
<td height="50">
|
||||
<td height="30" border="0" style="text-align:center;">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
|
||||
<tr>
|
||||
<td class="h1" style="padding: 5px 0 0 0;">
|
||||
{{site_name}}
|
||||
<td style="padding: 1px 0 1px 0; text-align:center;">
|
||||
<a href="https://www.wrenchboard.com/"><img src="https://dashboard.wrenchboard.com/assets/ext/images/wrenchboard.png" alt="WrenchBoard"></a> <!-- {{site_name}} -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="subhead" style="padding: 0 0 0 3px;">
|
||||
<td class="subhead" style="padding: 0 0 0 3px; text-align:center;">
|
||||
{{site_trade_name}}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -73,17 +68,23 @@ img {height: auto;}
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="innerpadding borderbottom">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
<table width="100%" align="left" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
Dear {{firstname}},
|
||||
<![endif]-->
|
||||
<table class="col380" align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%;">
|
||||
<tr>
|
||||
<td class="bodycopy">
|
||||
Hello {{firstname}},
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bodycopy">
|
||||
Welcome to {{site_name}}!. In order to complete your registration , use the number below to complete registration.
|
||||
Welcome to {{site_name}}!. In order to complete your registration , use the number below to complete registration.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -103,25 +104,17 @@ Welcome to {{site_name}}!. In order to complete your registration , use the numb
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td class="bodycopy">
|
||||
<b>Enter the number to continue :</b> <h2>{{signup_random}}</h2>
|
||||
<br>
|
||||
For app sign up ,enter the number <b>{{signup_random}}</b> to continue.
|
||||
<hr size="1">
|
||||
For Web sign up , <a href="https://{{server_name}}/vemail?vlnk={{verify_link}}">Click here to verify account</a> to continue.
|
||||
<hr size="1">
|
||||
Or
|
||||
<table class="buttonwrapper" bgcolor="#e05443" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td class="button" height="45" style="align-center;">
|
||||
<a href="https://{{server_name}}/vemail?vlnk={{verify_link}}">Click to Verify Account</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bodycopy" style="color:#ff0033">
|
||||
The Link will expire by {{expire}}
|
||||
Note : The link will expire by:{{expire}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -134,15 +127,10 @@ The Link will expire by {{expire}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="innerpadding borderbottom">
|
||||
<img class="fix" src="https://{{server_name}}/assets/images/wrenchboard_email_banner.jpg" width="100%" border="0" alt="" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="innerpadding bodycopy">
|
||||
If you did not initiate this account creation or have any further support question, Please contact us at https://{{server_name}}/contact<br>
|
||||
If you did not initiate this account creation or have any further support question, Please contact us at https://{{server_name}}/contact<br>
|
||||
<hr size="1">
|
||||
With <a href="http://{{server_name}}">{{site_name}}</a>, you can enjoy free coordinated skills training section. Empower yourself and be around those that work with latest to update your knowledge.
|
||||
With <a href="http://{{server_name}}">{{site_name}}</a>,you can enjoy free connection to makerplace for all of your ability. We are simply here to empower you..
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -153,12 +141,12 @@ With <a href="http://{{server_name}}">{{site_name}}</a>, you can enjoy free coor
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="footer" bgcolor="#44525f">
|
||||
<td class="footer">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="center" class="footercopy">
|
||||
® {{site_name}} 2018<br/>
|
||||
You received this email because you subscribe to {{site_name}}. If you get this email in error, please <a href="https://{{server_name}}/contactus" class="unsubscribe"><font color="#ffffff">contact</font></a> us.
|
||||
® {{site_name}} 2022<br/>
|
||||
You received this email because you subscribe to {{site_name}}. If you get this email in error, please <a href="https://{{server_name}}/contact" class="unsubscribe"><font color="#ffffff">contact</font></a> us.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -192,8 +180,6 @@ You received this email because you subscribe to {{site_name}}. If you get this
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--analytics-->
|
||||
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -16,17 +16,16 @@ img {height: auto;}
|
||||
.subhead {font-size: 12px; color: #ffffff; font-family: sans-serif; letter-spacing: 3px;}
|
||||
.h1, .h2, .bodycopy {color: #153643; font-family: sans-serif;}
|
||||
.h1 {font-size: 33px; line-height: 38px; font-weight: bold;}
|
||||
.h2 {padding: 0 0 15px 0; font-size: 24px; line-height: 28px; font-weight: bold;}
|
||||
.bodycopy {font-size: 14px; line-height: 20px;}
|
||||
.button {text-align: center; font-size: 16px; font-family: sans-serif; font-weight: bold; padding: 0 30px 0 30px;}
|
||||
.button a {color: #ffffff; text-decoration: none;}
|
||||
.footer {padding: 20px 30px 15px 30px;}
|
||||
.footer {padding: 20px 30px 15px 30px; bgcolor:#007bff; background-color:#007bff;}
|
||||
.footercopy {font-family: sans-serif; font-size: 14px; color: #ffffff;}
|
||||
.footercopy a {color: #ffffff; text-decoration: underline;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body yahoo bgcolor="#f6f8f1">
|
||||
<body bgcolor="#f6f8f1">
|
||||
<table width="100%" bgcolor="#f6f8f1" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td>
|
||||
@@ -44,22 +43,22 @@ img {height: auto;}
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
<table class="col425" align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 425px;">
|
||||
<table class="col425" align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 600px;">
|
||||
<tr>
|
||||
<td height="50">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
|
||||
<tr>
|
||||
<td class="h1" style="padding: 5px 0 0 0;">
|
||||
{{site_name}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="subhead" style="padding: 0 0 0 3px;">
|
||||
{{site_trade_name}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<tr>
|
||||
<td style="padding: 1px 0 1px 0; text-align:center;">
|
||||
<a href="https://www.wrenchboard.com/"><img src="https://dashboard.wrenchboard.com/assets/ext/images/wrenchboard.png" alt="WrenchBoard"></a> <!-- {{site_name}} -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="subhead" style="padding: 0 0 0 3px; text-align:center;">
|
||||
{{site_trade_name}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -74,7 +73,7 @@ img {height: auto;}
|
||||
<td class="innerpadding borderbottom">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td class="h2">
|
||||
<td class="bodycopy">
|
||||
Hello {{firstname}},
|
||||
</td>
|
||||
</tr>
|
||||
@@ -107,8 +106,8 @@ img {height: auto;}
|
||||
<td style="padding: 20px 0 0 0;">
|
||||
<table class="buttonwrapper" bgcolor="#e05443" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td class="button" height="45">
|
||||
<a href="https://{{server_name}}/complereset?passlink={{pass_link}}">Click to Reset Password</a>
|
||||
<td class="button" height="45" style="text-align:center;" >
|
||||
<a href="{{server_name}}/complereset?passlink={{pass_link}}">Click to Reset Password</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -128,7 +127,7 @@ img {height: auto;}
|
||||
|
||||
<tr>
|
||||
<td class="innerpadding bodycopy">
|
||||
If you did not initiate this password reset or have any further support question, please contact us at https://{{server_name}}/contact
|
||||
If you did not initiate this password reset or have any further support question, please contact us at {{server_name}}/contact
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -139,47 +138,47 @@ img {height: auto;}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="footer" bgcolor="#44525f">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="center" class="footercopy">
|
||||
® {{site_name}} 2018<br/>
|
||||
You received this email because you subscribe to {{site_name}}. If you get this email in error, please <a href="https://{{server_name}}/contactus" class="unsubscribe"><font color="#ffffff">contact</font></a> us.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="padding: 20px 0 0 0;">
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td width="37" style="text-align: center; padding: 0 10px 0 10px;">
|
||||
<a href="https://www.facebook.com/wrenchboard/">
|
||||
<img src="https://{{server_name}}/assets/images/brands/facebook.png" width="37" height="37" alt="Facebook" border="0" />
|
||||
</a>
|
||||
</td>
|
||||
<td width="37" style="text-align: center; padding: 0 10px 0 10px;">
|
||||
<a href="https://twitter.com/wrenchboard">
|
||||
<img src="https://{{server_name}}/assets/images/brands/twitter.png" width="37" height="37" alt="Twitter" border="0" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
<td class="footer">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="center" class="footercopy">
|
||||
® {{site_name}} 2022<br/>
|
||||
You received this email because you subscribe to {{site_name}}. If you get this email in error, please <a href="https://{{server_name}}/contact" class="unsubscribe"><font color="#ffffff">contact</font></a> us.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="padding: 20px 0 0 0;">
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td width="37" style="text-align: center; padding: 0 10px 0 10px;">
|
||||
<a href="https://www.facebook.com/wrenchboard/">
|
||||
<img src="https://{{server_name}}/assets/images/brands/facebook.png" width="37" height="37" alt="Facebook" border="0" />
|
||||
</a>
|
||||
</td>
|
||||
<td width="37" style="text-align: center; padding: 0 10px 0 10px;">
|
||||
<a href="http://www.twitter.com/">
|
||||
<img src="https://{{server_name}}/assets/images/brands/twitter.png" width="37" height="37" alt="Twitter" border="0" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--analytics-->
|
||||
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,42 +6,26 @@ Subject: Welcome to {{site_name}}
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>Welcome to {{site_name}}</title>
|
||||
<style type="text/css">
|
||||
body {margin: 0; padding: 0; min-width: 100%!important;}
|
||||
img {height: auto;}
|
||||
.content {width: 100%; max-width: 600px;}
|
||||
.header {padding: 40px 30px 20px 30px;}
|
||||
.innerpadding {padding: 30px 30px 30px 30px;}
|
||||
.borderbottom {border-bottom: 1px solid #f2eeed;}
|
||||
.subhead {font-size: 12px; color: #ffffff; font-family: sans-serif; letter-spacing: 3px;}
|
||||
.h1, .h2, .bodycopy {color: #153643; font-family: sans-serif;}
|
||||
.h1 {font-size: 33px; line-height: 38px; font-weight: bold;}
|
||||
.h2 {padding: 0 0 15px 0; font-size: 24px; line-height: 28px; font-weight: bold;}
|
||||
.bodycopy {font-size: 16px; line-height: 22px;}
|
||||
.button {text-align: center; font-size: 18px; font-family: sans-serif; font-weight: bold; padding: 0 30px 0 30px;}
|
||||
.button a {color: #ffffff; text-decoration: none;}
|
||||
.footer {padding: 20px 30px 15px 30px;}
|
||||
.footercopy {font-family: sans-serif; font-size: 14px; color: #ffffff;}
|
||||
.footercopy a {color: #ffffff; text-decoration: underline;}
|
||||
|
||||
@media only screen and (max-width: 550px), screen and (max-device-width: 550px) {
|
||||
body[yahoo] .hide {display: none!important;}
|
||||
body[yahoo] .buttonwrapper {background-color: transparent!important;}
|
||||
body[yahoo] .button {padding: 0px!important;}
|
||||
body[yahoo] .button a {background-color: #e05443; padding: 15px 15px 13px!important;}
|
||||
body[yahoo] .unsubscribe {display: block; margin-top: 20px; padding: 10px 50px; background: #2f3942; border-radius: 5px; text-decoration: none!important; font-weight: bold;}
|
||||
}
|
||||
|
||||
/*@media only screen and (min-device-width: 601px) {
|
||||
.content {width: 600px !important;}
|
||||
.col425 {width: 425px!important;}
|
||||
.col380 {width: 380px!important;}
|
||||
}*/
|
||||
|
||||
</style>
|
||||
<style type="text/css">
|
||||
body {margin: 0; padding: 0; min-width: 100%!important;}
|
||||
img {height: auto;}
|
||||
.content {width: 100%; max-width: 600px;}
|
||||
.header {padding: 10px 10px 10px 10px;}
|
||||
.innerpadding {padding: 10px 10px 10px 10px;}
|
||||
.borderbottom {border-bottom: 1px solid #f2eeed;}
|
||||
.subhead {font-size: 12px; color: #ffffff; font-family: sans-serif; letter-spacing: 3px;}
|
||||
.h1, .h2, .bodycopy {color: #153643; font-family: sans-serif;}
|
||||
.h1 {font-size: 33px; line-height: 38px; font-weight: bold;}
|
||||
.bodycopy {font-size: 14px; line-height: 20px;}
|
||||
.button {text-align: center; font-size: 16px; font-family: sans-serif; font-weight: bold; padding: 0 30px 0 30px;}
|
||||
.button a {color: #ffffff; text-decoration: none;}
|
||||
.footer {padding: 20px 30px 15px 30px; bgcolor:#007bff; background-color:#007bff;}
|
||||
.footercopy {font-family: sans-serif; font-size: 14px; color: #ffffff;}
|
||||
.footercopy a {color: #ffffff; text-decoration: underline;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body yahoo bgcolor="#f6f8f1">
|
||||
<body bgcolor="#f6f8f1">
|
||||
<table width="100%" bgcolor="#f6f8f1" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td>
|
||||
@@ -53,42 +37,20 @@ Subject: Welcome to {{site_name}}
|
||||
<table bgcolor="#ffffff" class="content" align="center" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td bgcolor="#c7d8a7" class="header">
|
||||
<table width="70" align="left" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td height="70" style="padding: 0 20px 20px 0;">
|
||||
<img class="fix" src="https://{{server_name}}/assets/images/wrenchboard-icon.gif" width="70" height="70" border="0" alt="WrenchBoard" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
<table width="425" align="left" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
<table class="col425" align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 425px;">
|
||||
<tr>
|
||||
<td height="50">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
|
||||
<tr>
|
||||
<td class="h1" style="padding: 5px 0 0 0;">
|
||||
{{site_name}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="subhead" style="padding: 0 0 0 3px;">
|
||||
{{site_trade_name}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
<tr>
|
||||
<td style="padding: 1px 0 1px 0; text-align:center;">
|
||||
<a href="https://www.wrenchboard.com/"><img src="https://dashboard.wrenchboard.com/assets/ext/images/wrenchboard.png" alt="WrenchBoard"></a> <!-- {{site_name}} -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="subhead" style="padding: 0 0 0 3px; text-align:center;">
|
||||
{{site_trade_name}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -160,11 +122,11 @@ With <a href="http://{{server_name}}">{{site_name}}</a>, you can enjoy free coor
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="footer" bgcolor="#44525f">
|
||||
<td class="footer">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="center" class="footercopy">
|
||||
® {{site_name}} 2017<br/>
|
||||
® {{site_name}} 2022<br/>
|
||||
You received this email because you subscribe to {{site_name}}. If you get this email in error, please <a href="https://{{server_name}}/contactus" class="unsubscribe"><font color="#ffffff">contact</font></a> us.
|
||||
|
||||
</td>
|
||||
@@ -199,8 +161,5 @@ With <a href="http://{{server_name}}">{{site_name}}</a>, you can enjoy free coor
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--analytics-->
|
||||
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -11,20 +11,17 @@ body {margin: 0; padding: 0; min-width: 100%!important;}
|
||||
img {height: auto;}
|
||||
.content {width: 100%; max-width: 600px;}
|
||||
.header {padding: 10px 10px 10px 10px;}
|
||||
.innerpadding {padding: 30px 30px 30px 30px;}
|
||||
.innerpadding {padding: 10px 10px 10px 10px;}
|
||||
.borderbottom {border-bottom: 1px solid #f2eeed;}
|
||||
.subhead {font-size: 12px; color: #ffffff; font-family: sans-serif; letter-spacing: 3px;}
|
||||
.h1, .h2, .bodycopy {color: #153643; font-family: sans-serif;}
|
||||
.h1 {font-size: 33px; line-height: 38px; font-weight: bold;}
|
||||
.h2 {padding: 0 0 15px 0; font-size: 24px; line-height: 28px; font-weight: bold;}
|
||||
.bodycopy {font-size: 14px; line-height: 20px;}
|
||||
.button {text-align: center; font-size: 16px; font-family: sans-serif; font-weight: bold; padding: 0 30px 0 30px;}
|
||||
.button a {color: #ffffff; text-decoration: none;}
|
||||
.footer {padding: 20px 30px 15px 30px;}
|
||||
.footer {padding: 20px 30px 15px 30px; bgcolor:#007bff; background-color:#007bff;}
|
||||
.footercopy {font-family: sans-serif; font-size: 14px; color: #ffffff;}
|
||||
.footercopy a {color: #ffffff; text-decoration: underline;}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -52,8 +49,8 @@ img {height: auto;}
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
|
||||
<tr>
|
||||
<td class="h1" style="padding: 5px 0 0 0;">
|
||||
{{site_name}}
|
||||
<td style="padding: 1px 0 1px 0; text-align:center;">
|
||||
<a href="https://www.wrenchboard.com/"><img src="https://dashboard.wrenchboard.com/assets/ext/images/wrenchboard.png" alt="WrenchBoard"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -75,13 +72,6 @@ img {height: auto;}
|
||||
|
||||
<tr>
|
||||
<td class="innerpadding borderbottom">
|
||||
<table width="115" align="left" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td height="115" style="padding: 0 20px 20px 0;">
|
||||
<img class="fix" src="https://{{server_name}}/assets/images/article1.png" width="115" height="115" border="0" alt="" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
<table width="380" align="left" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
@@ -94,8 +84,10 @@ img {height: auto;}
|
||||
<td>
|
||||
<table width="100%" border="0" cellspacing="1" cellpadding="0" class="bodycopy" style="font-size: 14px; font-family: sans-serif; border: 1px solid #f2eeed; background-color:#e6f9ff;">
|
||||
<tr >
|
||||
<td colspan="2"><h3>Signup Pending-{{added}}</h3></td>
|
||||
<td class="left" style="width:100px">Signup Pending</td>
|
||||
<td class="bodycopy">{{added}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<tr >
|
||||
<td class="left" style="width:100px">Firstname</td>
|
||||
@@ -125,15 +117,14 @@ img {height: auto;}
|
||||
<td class="bodycopy">{{verify_link}}</td>
|
||||
</tr>
|
||||
|
||||
<tr >
|
||||
<td class="left" colspan="2">Please <a href ="https://{{server_name}}/bko">login</a> into BackOffice from authorized system to support the user.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><h4>Please <a href ="https://{{server_name}}/bko">login</a> into BackOffice from authorized system to support the user.</h4>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
</td>
|
||||
@@ -144,7 +135,7 @@ img {height: auto;}
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="innerpadding borderbottom">
|
||||
<img class="fix" src="https://{{server_name}}/assets/images/wrenchboard_email_banner.jpg" width="100%" border="0" alt="" />
|
||||
<img class="fix" src="https://dashboard.wrenchboard.com/assets/images/wrenchboard_email_banner.jpg" width="100%" border="0" alt="" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -156,11 +147,11 @@ img {height: auto;}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="footer" bgcolor="#44525f">
|
||||
<td class="footer">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0" >
|
||||
<tr>
|
||||
<td align="center" class="footercopy">
|
||||
® {{site_name}} 2017<br/>
|
||||
® {{site_name}} 2022<br/>
|
||||
You received this email because you are a support user for {{site_name}}. If you get this email in error, please <a href="https://{{server_name}}/contactus" class="unsubscribe"><font color="#ffffff">contact</font></a> us.
|
||||
</td>
|
||||
</tr>
|
||||
@@ -196,6 +187,5 @@ You received this email because you are a support user for {{site_name}}. If you
|
||||
</table>
|
||||
|
||||
<!--analytics-->
|
||||
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -16,16 +16,12 @@ img {height: auto;}
|
||||
.subhead {font-size: 12px; color: #ffffff; font-family: sans-serif; letter-spacing: 3px;}
|
||||
.h1, .h2, .bodycopy {color: #153643; font-family: sans-serif;}
|
||||
.h1 {font-size: 33px; line-height: 38px; font-weight: bold;}
|
||||
.h2 {padding: 0 0 15px 0; font-size: 24px; line-height: 28px; font-weight: bold;}
|
||||
.bodycopy {font-size: 14px; line-height: 20px;}
|
||||
.button {text-align: center; font-size: 16px; font-family: sans-serif; font-weight: bold; padding: 0 30px 0 30px;}
|
||||
.button a {color: #ffffff; text-decoration: none;}
|
||||
.footer {padding: 20px 30px 15px 30px;}
|
||||
.footer {padding: 20px 30px 15px 30px; bgcolor:#007bff; background-color:#007bff;}
|
||||
.footercopy {font-family: sans-serif; font-size: 14px; color: #ffffff;}
|
||||
.footercopy a {color: #ffffff; text-decoration: underline;}
|
||||
|
||||
|
||||
</style>
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -47,18 +43,18 @@ img {height: auto;}
|
||||
<tr>
|
||||
<td>
|
||||
<![endif]-->
|
||||
<table class="col425" align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 425px;">
|
||||
<table class="col425" align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 600px;">
|
||||
<tr>
|
||||
<td height="50">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
|
||||
<tr>
|
||||
<td class="h1" style="padding: 5px 0 0 0;">
|
||||
{{site_name}}
|
||||
<td style="padding: 1px 0 1px 0; text-align:center;">
|
||||
<a href="https://www.wrenchboard.com/"><img src="https://dashboard.wrenchboard.com/assets/ext/images/wrenchboard.png" alt="WrenchBoard"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="subhead" style="padding: 0 0 0 3px;">
|
||||
<td class="subhead" style="padding: 0 0 0 3px; text-align:center;">
|
||||
{{site_trade_name}}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -77,7 +73,7 @@ img {height: auto;}
|
||||
<td class="innerpadding borderbottom">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td class="h2">
|
||||
<td class="bodycopy">
|
||||
Dear {{firstname}},
|
||||
</td>
|
||||
</tr>
|
||||
@@ -95,7 +91,7 @@ You have posted a job offer at <a href="https://{{server_name}}">{{site_name}}</
|
||||
<table width="115" align="left" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td height="115" style="padding: 0 20px 20px 0;">
|
||||
<img class="fix" src="https://{{server_name}}/assets/images/article1.png" width="115" height="115" border="0" alt="" />
|
||||
<img class="fix" src="https://dashboard.wrenchboard.com/assets/images/article1.png" width="115" height="115" border="0" alt="" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -186,7 +182,7 @@ Offer Expire
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="innerpadding borderbottom">
|
||||
<img class="fix" src="https://{{server_name}}/assets/images/wrenchboard_email_banner.jpg" width="100%" border="0" alt="" />
|
||||
<img class="fix" src="https://dashboard.wrenchboard.com/assets/images/wrenchboard_email_banner.jpg" width="100%" border="0" alt="" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -202,12 +198,12 @@ Please contact us at https://{{server_name}}/contact if you have any question a
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="footer" bgcolor="#44525f">
|
||||
<td class="footer">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0" >
|
||||
<tr>
|
||||
<td align="center" class="footercopy">
|
||||
® {{site_name}} 2018<br/>
|
||||
You received this email because a user sent a job to you from {{site_name}}. If you get this email in error, please <a href="https://{{server_name}}/contactus" class="unsubscribe"><font color="#ffffff">contact</font></a> us.
|
||||
® {{site_name}} 2022<br/>
|
||||
You received this email because a user sent a job to you from {{site_name}}. If you get this email in error, please <a href="https://{{server_name}}/contact" class="unsubscribe"><font color="#ffffff">contact</font></a> us.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -242,6 +238,5 @@ Please contact us at https://{{server_name}}/contact if you have any question a
|
||||
</table>
|
||||
|
||||
<!--analytics-->
|
||||
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -46,13 +46,16 @@ Paypal:
|
||||
|
||||
stripe:
|
||||
{
|
||||
publishable_key = "pk_test_X7TylEk9BkZCarcj0FyKRYXc";
|
||||
secret_key = "sk_test_MA2ltfGlT70Nu7uWlmHowBRB";
|
||||
publishable_key = "pk_test_51JwvOXCMmfol61TL2IlTEWytKObMLrZTAxJRHdepqWggXm4ENMyrrnR5dxfd5cPeflvCUG1HsErQI43BjOAmUEh500N0FWOZoE";
|
||||
old_publishable_key ="pk_test_X7TylEk9BkZCarcj0FyKRYXc";
|
||||
secret_key = "sk_test_51JwvOXCMmfol61TLadZlDf2rxq6Q1IC50JITRixcbyig8T2zdqpO8HY2NEcwNHacRQKQpTf6JGh7haqUVEH0rccA00eFht1ewi";
|
||||
old_secret_key = "sk_test_MA2ltfGlT70Nu7uWlmHowBRB";
|
||||
};
|
||||
|
||||
database:
|
||||
{
|
||||
host = "127.0.0.1";
|
||||
#- using docker 10.23 host = "127.0.0.1";
|
||||
host = "10.10.10.23";
|
||||
name = "wrenchboard";
|
||||
user = "wrenchboard";
|
||||
pass = "wrenchboard";
|
||||
|
||||
@@ -10,11 +10,11 @@ generated by GNU Autoconf 2.69. Invocation command line was
|
||||
## Platform. ##
|
||||
## --------- ##
|
||||
|
||||
hostname = localhost.localdomain
|
||||
hostname = WrenchBoardDev
|
||||
uname -m = x86_64
|
||||
uname -r = 4.18.0-193.el8.x86_64
|
||||
uname -r = 4.18.0-193.14.2.el8_2.x86_64
|
||||
uname -s = Linux
|
||||
uname -v = #1 SMP Fri May 8 10:59:10 UTC 2020
|
||||
uname -v = #1 SMP Sun Jul 26 03:54:29 UTC 2020
|
||||
|
||||
/usr/bin/uname -p = x86_64
|
||||
/bin/uname -X = unknown
|
||||
@@ -534,10 +534,9 @@ generated by GNU Autoconf 2.69. Invocation command line was
|
||||
CONFIG_COMMANDS =
|
||||
$ ./config.status
|
||||
|
||||
on localhost.localdomain
|
||||
on WrenchBoardDev
|
||||
|
||||
config.status:944: creating config.h
|
||||
config.status:1034: config.h is unchanged
|
||||
config.status:1048: executing libtool commands
|
||||
|
||||
## ---------------- ##
|
||||
|
||||
@@ -117,7 +117,7 @@ int SMTP2( const char * _server, const char * _from, char * _to, char * _body, c
|
||||
}
|
||||
|
||||
// Google
|
||||
snprintf( name, BUF_SIZE, EMAIL_PREFIX"/../src/modules/mailsend -smtp %s -f %s -t %s -domain %s -name '%s' +cc +bcc -v -starttls -port 587 -auth-plain -user %s -pass %s -sub '%s' -content-type 'text/html' -mime-type 'text/html' -M '%s'",
|
||||
snprintf( name, BUF_SIZE, EMAIL_PREFIX"/../src/modules/mailsend -smtp %s -f %s -t %s -domain %s -name '%s' +cc +bcc -v -starttls -port 587 -auth-plain -user %s -pass %s -sub '%s' -content-type 'multipart/mixed' -mime-type 'text/html' -disposition inline -M '%s'",
|
||||
_server, _from, _to, _domain, _name, _user, _pass, subject, body != NULL ? body : _body );
|
||||
/*
|
||||
// Virtualmail
|
||||
|
||||
@@ -9,5 +9,11 @@ long WrenchRefundoffer( CVars in, CVars &out );
|
||||
long WrenchContractPayment( CVars in, CVars &out );
|
||||
long WrenchCanceContractPayment( CVars in, CVars &out );
|
||||
|
||||
|
||||
long WrenchNewCardPayment( CVars in, CVars &out );
|
||||
long WrenchCardRechargePayment( CVars in, CVars &out );
|
||||
long CheckWallet(long member_id,CVars in);
|
||||
long DeductMemberWallet(long member_id,long wallet_id,long amount, long payment_id);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -167,6 +167,12 @@ enum { PARTNER_STRIPE };
|
||||
#define WRENCHBOARD_USER_SENDMONEY 11051
|
||||
#define WRENCHBOARD_USER_SENDJOBINT 11052
|
||||
|
||||
#define WRENCHBOARD_USER_ADNEWCC 11054
|
||||
#define WRENCHBOARD_USER_USESAVEDCC 11056
|
||||
|
||||
#define WRENCHBOARD_ACCOUNT_WALLETS 11060
|
||||
|
||||
#define WRENCHBOARD_USER_DELETEACC 11990
|
||||
#define WRENCHBOARD_ACCOUNT_END 11999
|
||||
//**************************************************************
|
||||
#define WRENCHBOARD_GROUP_START 12000
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Generated automatically by config.status ()
|
||||
# Libtool was configured on host localhost.localdomain:
|
||||
# Libtool was configured on host WrenchBoardDev:
|
||||
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
|
||||
|
||||
# Provide generalized library-building support services.
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <curl/curl.h>
|
||||
#include "smoney.h"
|
||||
#include "account_mngt.h"
|
||||
#include "creditcards.h"
|
||||
#include "payments.h"
|
||||
|
||||
#include "jobs.h"
|
||||
|
||||
@@ -109,6 +111,7 @@ created timestamp without time zone DEFAULT now()
|
||||
long WrenchBoardMobileSendMoney(CVars in, CVars &out);
|
||||
long WrenchBoardMobileSendJobInterest(CVars in, CVars &out);
|
||||
long WrenchReturnPendingJobList(CVars in, CVars &out);
|
||||
long WrenchBoardMobileSendUserWallet(CVars in, CVars &out);
|
||||
|
||||
long test() {
|
||||
FILE* oldFile = Output2FILE::Stream();
|
||||
@@ -143,7 +146,7 @@ test();
|
||||
break;
|
||||
|
||||
case WRENCHBOARD_RESET_PASSWORD:
|
||||
|
||||
return WrenchResetMemberPass(in, out);
|
||||
break;
|
||||
|
||||
case WRENCHBOARD_MOBILE_MESSAGE:
|
||||
@@ -294,18 +297,43 @@ test();
|
||||
return WrenchLoadDashData(in, out);
|
||||
break;
|
||||
|
||||
case WRENCHBOARD_USER_GETBANKLIST:
|
||||
return WrenchReturnMemberBankAccount(in, out);
|
||||
break;
|
||||
|
||||
case WRENCHBOARD_USER_SENDMONEY:
|
||||
return WrenchBoardMobileSendMoney(in, out);
|
||||
case WRENCHBOARD_USER_GETBANKLIST:
|
||||
return WrenchReturnMemberBankAccount(in, out);
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
case WRENCHBOARD_USER_SENDJOBINT:
|
||||
return WrenchBoardMobileSendJobInterest(in, out);
|
||||
break;
|
||||
case WRENCHBOARD_USER_SENDMONEY:
|
||||
return WrenchBoardMobileSendMoney(in, out);
|
||||
break;
|
||||
|
||||
case WRENCHBOARD_USER_SENDJOBINT:
|
||||
return WrenchBoardMobileSendJobInterest(in, out);
|
||||
break;
|
||||
|
||||
case WRENCHBOARD_USER_ADNEWCC:
|
||||
return WrenchNewCardPayment(in, out);
|
||||
break;
|
||||
|
||||
case WRENCHBOARD_USER_USESAVEDCC:
|
||||
return WrenchCardRechargePayment(in, out);
|
||||
break;
|
||||
|
||||
case WRENCHBOARD_ACCOUNT_WALLETS:
|
||||
logfmt(logINFO, "/account_calls()");
|
||||
return WrenchBoardMobileSendUserWallet(in, out);
|
||||
break;
|
||||
|
||||
case WRENCHBOARD_USER_DELETEACC:
|
||||
REQ_LONG(in, "member_id", 1, -1);
|
||||
REQ_STRING(in, "reason", 2, 149, "(.*)");
|
||||
CVars xx;
|
||||
xx["member_id"] = in["member_id"]; xx["member_id"].set_valid(true);
|
||||
xx["reason"] = in["reason"]; xx["reason"].set_valid(true);
|
||||
out["delete_id"] = insert_db_record(DBS_VALID, "members_delete", "members_delete_id_seq", xx);
|
||||
ret = PHP_API_OK;
|
||||
/*
|
||||
DO THE DELETE HERE NOW
|
||||
*/
|
||||
break;
|
||||
|
||||
}
|
||||
logfmt(logINFO, "/account_calls()");
|
||||
@@ -314,6 +342,42 @@ test();
|
||||
|
||||
#define PHP_API_TRANSFER_COMPLETE 200
|
||||
|
||||
long WrenchBoardMobileSendUserWallet(CVars in, CVars &out) {
|
||||
logfmt(logINFO, "WrenchBoardMobileSendUserWallet()");
|
||||
char vname[30];
|
||||
long ret = PHP_API_BAD_PARAM;
|
||||
|
||||
try {
|
||||
REQ_LONG(in, "member_id", 1, -1);
|
||||
out["total_record"] = "0";
|
||||
const PGresult *res;
|
||||
res = pgsql_query(" SELECT * FROM members_wallet WHERE member_id = %lu", in["member_id"].Long());
|
||||
|
||||
if (res != NULL && pgsql_num_rows(res) > 0) {
|
||||
out["total_record"] = pgsql_num_rows(res);
|
||||
|
||||
for (int i = 0, n = pgsql_num_rows(res); i < n; i++) {
|
||||
map<const char*, const char*>f = pgsql_fetch_assoc(res, i);
|
||||
if (f.empty()) continue;
|
||||
CVars rec;
|
||||
map_to_cvars(f, rec);
|
||||
|
||||
snprintf(vname, sizeof (vname), "amount_%05d", i);
|
||||
out[vname] = rec["amount"];
|
||||
snprintf(vname, sizeof (vname), "currency_%05d", i);
|
||||
out[vname] = rec["currency"];
|
||||
}
|
||||
}
|
||||
ret = PHP_API_OK;
|
||||
out["status"] = "OK";
|
||||
} catch (bad_parameter) {
|
||||
logfmt(logINFO, "ERROR CALL long WrenchBoardMobileSendUserWallet(CVars in, CVars &out)");
|
||||
}
|
||||
logfmt(logINFO, "/WrenchBoardMobileSendUserWallet()");
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
long WrenchBoardMobileSendJobInterest(CVars in, CVars &out) {
|
||||
long ret = PHP_API_BAD_PARAM;
|
||||
try {
|
||||
@@ -363,6 +427,7 @@ long WrenchBoardMobileSendJobInterest(CVars in, CVars &out) {
|
||||
return ret;
|
||||
}
|
||||
long WrenchBoardMobileSendMoney(CVars in, CVars &out){
|
||||
logfmt(logINFO, "long *************** WrenchBoardMobileSendMoney(CVars in, CVars out)");
|
||||
long ret = PHP_API_BAD_PARAM;
|
||||
|
||||
try{
|
||||
@@ -377,7 +442,7 @@ long WrenchBoardMobileSendMoney(CVars in, CVars &out){
|
||||
sprintf(send_trxid, "T%04lu", r1);
|
||||
|
||||
logfmt(logINFO, "Recipient ID =====() %lu",in["bankid"].Long() );
|
||||
out["sendmoney_message"] ="Processing...";
|
||||
out["sendmoney_message"] ="Processing...";
|
||||
|
||||
|
||||
REQ_LONG(in, "bankid", 1, -1);
|
||||
@@ -672,6 +737,9 @@ long WrenchReturnStartJobList(CVars in, CVars &out) {
|
||||
snprintf(vname, sizeof (vname), "description_%05d", i);
|
||||
out[vname] = rec["description"];
|
||||
|
||||
snprintf(vname, sizeof (vname), "expire_%05d", i);
|
||||
out[vname] = rec["expire"];
|
||||
|
||||
snprintf(vname, sizeof (vname), "id_%05d", i);
|
||||
out[vname] = rec["job_id"];
|
||||
}
|
||||
@@ -1146,6 +1214,13 @@ long LoginWrenchBoardAccount(CVars in, CVars &out) {
|
||||
|
||||
ret = load_db_record(out, "SELECT *,id AS member_id , to_char(last_login, 'Day Mon dd, yyyy HH:MI AM') AS last_login2 FROM members WHERE status=1 AND LOWER(username)=LOWER('%s') AND password= md5('%s')", in["username"].c_str(), in["password"].c_str());
|
||||
if (ret) {
|
||||
CVars vw;
|
||||
vw["currency"] = "NAIRA"; // this might become a variable based on the country
|
||||
vw["currency"].set_valid( true );
|
||||
long wallet_id = CheckWallet(out["member_id"].Long(),vw);
|
||||
|
||||
load_db_record( out, "SELECT amount AS balance FROM members_wallet WHERE member_id = %lu AND currency='%s' ", out["member_id"].Long(), vw["currency"].c_str());
|
||||
|
||||
|
||||
pgsql_exec("DELETE FROM members_session WHERE member_id=%ld ", out["member_id"].Long());
|
||||
// remove all existing session
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "pgsql_wrapper.h"
|
||||
#include "cfg.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "payments.h"
|
||||
#include "account.h"
|
||||
|
||||
|
||||
@@ -514,6 +514,12 @@ long CreateWrenchBoardAccount(CVars in, CVars &out) {
|
||||
x["member_id"].set_valid(true);
|
||||
x["pending_id"] = out["pending_id"];
|
||||
x["pending_id"].set_valid(true);
|
||||
|
||||
CVars vw;
|
||||
vw["currency"] = "NAIRA"; // this will become a variable based on the country
|
||||
vw["currency"].set_valid( true );
|
||||
out["wallet_id"] = CheckWallet(out["member_id"].Long(),vw); // initial wallet
|
||||
|
||||
// - password already set pgsql_query("UPDATE members SET password = md5('%s') WHERE id = %lu",in["pass1"].c_str(),ret);
|
||||
pgsql_query("UPDATE members_pending SET status = 5 WHERE id = %lu", out["pending_id"].Long());
|
||||
pgsql_query("UPDATE members_refer_friend SET status = 5 WHERE status = 1 AND email = '%s'", x["email"].c_str());
|
||||
|
||||
@@ -22,14 +22,14 @@ long save_creditcard(CVars in, CVars &out) {
|
||||
try {
|
||||
CVars v;
|
||||
|
||||
REQ_LONG(in, "member_id", 1, -1); // Does not make any sence without member persitence
|
||||
REQ_LONG(in, "member_id", 1, -1); // Does not make any sence without member persitence
|
||||
REQ_STRING(in, "cardnumber", 12, 16, "(.*)"); //4111111111111111"
|
||||
REQ_STRING(in, "cvc", 3, 4, "(.*)"); //234"
|
||||
REQ_LONG(in, "paymenttype", 0, -1);
|
||||
REQ_STRING(in, "exp_month", 2, 2, "(.*)");
|
||||
REQ_STRING(in, "exp_year", 4, 4, "(.*)");
|
||||
|
||||
if ( load_db_record( v, "SELECT a.id AS member_id,a.firstname,a.lastname,'' AS street1,'' AS street2,a.city,'' AS postal,a.state,a.country FROM members a WHERE a.id=%lu", in["member_id"].Long()) > 0) {
|
||||
if ( load_db_record( v, "SELECT a.id AS member_id,a.firstname,a.lastname,'' AS street1,'' AS street2,a.city,zip_code AS postal,a.state,a.country FROM members a WHERE a.id=%lu", in["member_id"].Long()) > 0) {
|
||||
|
||||
logfmt(logDEBUG, "Loaded member %s %s", v["firstname"].c_str(), v["lastname"].c_str());
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ long SendmarketMessage(CVars in, CVars &out) {
|
||||
form.LetStr("site_trade_name", "Connecting Experts with Clients");
|
||||
vars2form(in, form);
|
||||
|
||||
in["server_name"] = "https://www.wrenchboard.com";
|
||||
in["server_name"] = "https://dashboard.wrenchboard.com";
|
||||
|
||||
int c = 0;
|
||||
|
||||
@@ -157,7 +157,7 @@ long cron_email(long mailtype, CVars in, CVars &out) {
|
||||
if (load_db_record(x, "SELECT *,email as email2,to_char(last_login, 'Day Mon dd, yyyy HH:MI AM') AS last_login2 FROM members WHERE id = %lu ", in["member_id"].Long())) {
|
||||
|
||||
|
||||
in["server_name"] = "https://www.wrenchboard.com";
|
||||
in["server_name"] = "https://dashboard.wrenchboard.com";
|
||||
|
||||
int c = 0;
|
||||
|
||||
@@ -233,7 +233,7 @@ long account_email(long mailtype, CVars in, CVars &out) {
|
||||
const PGresult *res;
|
||||
|
||||
char * server_name = getenv("SERVER_NAME");
|
||||
form.LetStr("server_name", server_name);
|
||||
form.LetStr("server_name", "https://dashboard.wrenchboard.com");
|
||||
form.LetStr("site_name", "WrenchBoard");
|
||||
form.LetStr("site_trade_name", "Connecting Experts with Clients");
|
||||
|
||||
@@ -275,7 +275,7 @@ long account_email(long mailtype, CVars in, CVars &out) {
|
||||
if (load_db_record(x, "SELECT *,email as email2,to_char(last_login, 'Day Mon dd, yyyy HH:MI AM') AS last_login2 FROM members WHERE id = %lu ", in["member_id"].Long())) {
|
||||
|
||||
|
||||
in["server_name"] = "https://www.wrenchboard.com";
|
||||
in["server_name"] = "https://dashboard.wrenchboard.com";
|
||||
|
||||
int c = 0;
|
||||
|
||||
@@ -321,6 +321,7 @@ long account_email(long mailtype, CVars in, CVars &out) {
|
||||
break;
|
||||
|
||||
case ACCOUNT_PASSWORD_RESET:
|
||||
|
||||
REQ_LONG(in, "password_reset_id", 1, -1);
|
||||
if (load_db_record(x, "select p.*,m.firstname,m.lastname,m.email, "
|
||||
" TO_CHAR(expired :: TIMESTAMP, 'Day Mon dd, yyyy HH:MI AM') AS long_expired , "
|
||||
@@ -328,6 +329,7 @@ long account_email(long mailtype, CVars in, CVars &out) {
|
||||
" FROM password_reset p "
|
||||
" LEFT JOIN members m ON m.id =p.member_id WHERE p.id = %lu ", in["password_reset_id"].Long())) {
|
||||
vars2form(x, form);
|
||||
form.LetStr("server_name", server_name);
|
||||
form.Email("ACCOUNT/member_resetpass.mailfile");
|
||||
}
|
||||
break;
|
||||
@@ -417,7 +419,7 @@ long job_email(long mailtype, CVars in, CVars &out) {
|
||||
vars2form(y, form);
|
||||
// FOR CRON JOBS SET SERVER NAME
|
||||
form.LetStr("preview_count", in["preview_count"].c_str());
|
||||
form.LetStr("server_name", "www.wrenchboard.com");
|
||||
form.LetStr("server_name", "dashboard.wrenchboard.com");
|
||||
vars2form(x, form);
|
||||
form.LetStr("subject", "Completed Task Processing Past Due");
|
||||
form.LetStr("email", y["email"].c_str());
|
||||
@@ -431,7 +433,7 @@ long job_email(long mailtype, CVars in, CVars &out) {
|
||||
|
||||
if (load_db_record(x, "SELECT m.firstname,m.email,mj.title,c.* FROM members_jobs_contract c LEFT JOIN members m ON m.id=c.client_id LEFT JOIN members_jobs mj ON mj.id = c.job_id WHERE c.id=%lu AND c.due_remind IS NULL", in["contract_id"].Long())) {
|
||||
// FOR CRON JOBS SET SERVER NAME
|
||||
form.LetStr("server_name", "www.wrenchboard.com");
|
||||
form.LetStr("server_name", "dashboard.wrenchboard.com");
|
||||
vars2form(x, form);
|
||||
form.LetStr("subject", "Task Due Date Approaching");
|
||||
form.LetStr("email", x["email"].c_str());
|
||||
@@ -897,7 +899,7 @@ long SignupPendingAlertMailfile(CVars in) {
|
||||
form.LetStr("site_name", "WrenchBoard");
|
||||
form.LetStr("subject", "WrenchBoard Contact Us Alert");
|
||||
|
||||
if (load_db_record(x, "SELECT *,email as email2 FROM members_pending WHERE id = %lu ", in["pending_id"].Long())) {
|
||||
if (load_db_record(x, "SELECT *,email as email2,to_char(expire, 'Day Mon dd, yyyy HH:MI AM') AS expire,to_char(added, 'Day Mon dd, yyyy HH:MI AM') AS added FROM members_pending WHERE id = %lu ", in["pending_id"].Long())) {
|
||||
vars2form(x, form);
|
||||
form.LetStr("email", out["alertemail"].c_str());
|
||||
form.Email("ALERT/alert_signup.mailfile");
|
||||
@@ -973,7 +975,7 @@ long AccountPendingMail(CVars in) //TESTED
|
||||
form.LetStr("site_name", "WrenchBoard");
|
||||
form.LetStr("site_trade_name", "Connecting Experts with Clients");
|
||||
|
||||
if (load_db_record(x, "SELECT * FROM members_pending WHERE id = %lu ", in["pending_id"].Long())) {
|
||||
if (load_db_record(x, "SELECT *,to_char(expire, 'Day Mon dd, yyyy HH:MI AM') AS expire FROM members_pending WHERE id = %lu ", in["pending_id"].Long())) {
|
||||
vars2form(x, form);
|
||||
form.LetStr("email", x["email"].c_str());
|
||||
if (x["signup_random"] != "" && x["signup_random"].Long() > 0 && in["mobile_email"].Long() == 100) {
|
||||
@@ -1001,7 +1003,7 @@ long WelcomeAccountMail(CVars in) // TESTED
|
||||
C_CGI_Form form("", "");
|
||||
|
||||
char * server_name = getenv("SERVER_NAME");
|
||||
form.LetStr("server_name", server_name);
|
||||
form.LetStr("server_name", "https://dashboard.wrenchboard.com");
|
||||
form.LetStr("site_name", "WrenchBoard");
|
||||
|
||||
if (load_db_record(x, "SELECT * FROM members WHERE id = %lu ", in["member_id"].Long())) {
|
||||
@@ -1027,7 +1029,7 @@ long JobAddedMail(CVars in) //TESTED
|
||||
C_CGI_Form form("", "");
|
||||
|
||||
char * server_name = getenv("SERVER_NAME");
|
||||
form.LetStr("server_name", server_name);
|
||||
form.LetStr("server_name", "https://dashboard.wrenchboard.com");
|
||||
form.LetStr("site_name", "WrenchBoard");
|
||||
|
||||
if (load_db_record(x, "SELECT j.*,j.title as title2,m.email,m.firstname FROM members_jobs j LEFT JOIN members m ON m.id = j.member_id WHERE j.id = %lu AND j.member_id = %lu", in["job_id"].Long(), in["member_id"].Long())) {
|
||||
@@ -1040,7 +1042,7 @@ long JobAddedMail(CVars in) //TESTED
|
||||
vars2form(x, form2);
|
||||
out["alertemail"] = CfgReadChar("transnotif.contact");
|
||||
char * server_name = getenv("SERVER_NAME");
|
||||
form2.LetStr("server_name", server_name);
|
||||
form2.LetStr("server_name", "https://dashboard.wrenchboard.com");
|
||||
form2.LetStr("site_name", "WrenchBoard");
|
||||
in["title"] = "Job Added Alert";
|
||||
in["message"] = "Job Added Alert";
|
||||
@@ -1063,7 +1065,7 @@ long CreateWrenchBoardGroupMail(CVars in) {
|
||||
C_CGI_Form form("", "");
|
||||
|
||||
char * server_name = getenv("SERVER_NAME");
|
||||
form.LetStr("server_name", server_name);
|
||||
form.LetStr("server_name", "https://dashboard.wrenchboard.com");
|
||||
form.LetStr("site_name", "WrenchBoard");
|
||||
|
||||
if (load_db_record(x, "select g.*,m.email,m.firstname,m.lastname from members_groups g LEFT JOIN members m ON m.id = g.member_id WHERE g.id = %lu ", in["group_id"].Long())) {
|
||||
@@ -1082,7 +1084,7 @@ long GroupCreateMemberMail(CVars in) {
|
||||
C_CGI_Form form("", "");
|
||||
|
||||
char * server_name = getenv("SERVER_NAME");
|
||||
form.LetStr("server_name", server_name);
|
||||
form.LetStr("server_name", "https://dashboard.wrenchboard.com");
|
||||
form.LetStr("site_name", "WrenchBoard");
|
||||
|
||||
if (load_db_record(x, "SELECT gm.*,m.*,e.email FROM group_members gm LEFT JOIN members_groups m ON m.id=gm.group_id LEFT JOIN members e ON e.id=gm.member_id WHERE gm.id = %lu", in["group_member_id"].Long())) {
|
||||
@@ -1117,7 +1119,7 @@ long EmailCustBalUpdt(CVars in) {
|
||||
CVars x;
|
||||
|
||||
vars2form(x, form);
|
||||
form.LetStr("site", server_name);
|
||||
form.LetStr("server_name", "https://dashboard.wrenchboard.com");
|
||||
form.Email("test.mailfile");
|
||||
return 0;
|
||||
}
|
||||
@@ -1209,7 +1211,7 @@ long StartPassResetEmail(CVars in) {
|
||||
vars2form(x, form);
|
||||
|
||||
|
||||
form.LetStr("site", server_name);
|
||||
form.LetStr("server_name", "https://dashboard.wrenchboard.com");
|
||||
/*
|
||||
CREATE TABLE lostpass (
|
||||
id serial NOT NULL,
|
||||
@@ -1245,7 +1247,7 @@ long CompletePassResetEmail(CVars in) {
|
||||
vars2form(x, form);
|
||||
|
||||
|
||||
form.LetStr("site", server_name);
|
||||
form.LetStr("server_name", "https://dashboard.wrenchboard.com");
|
||||
|
||||
|
||||
|
||||
@@ -1296,7 +1298,7 @@ long CustomerAirSalePayment(CVars in) {
|
||||
form.LetStr("paymode", "Payment with card");
|
||||
}
|
||||
|
||||
|
||||
form.LetStr("server_name", "https://dashboard.wrenchboard.com");
|
||||
form.LetStr("site", server_name);
|
||||
form.LetStr("email", x["email2"].c_str());
|
||||
form.Email("topup_payment.mailfile"); //customer notification
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "input.h"
|
||||
#include "wrenchboard_api.h"
|
||||
#include "payments.h"
|
||||
#include "creditcards.h"
|
||||
#include "common_tool.h"
|
||||
#include "email.h"
|
||||
#include "safestring.h"
|
||||
@@ -28,6 +29,188 @@ INSERT INTO payment_types(type_code,code,dir) VALUES('OFFER_PYM_DEPOSIT','OFDPS'
|
||||
INSERT INTO payment_types(type_code,code,dir) VALUES('OFFER_PYM_REFUND','OFRFD',1); -- // refund if offer was rejected or not accepted
|
||||
*/
|
||||
|
||||
long UpdateMemberWallet(long member_id,long wallet_id,long amount, long payment_id);
|
||||
|
||||
/*
|
||||
call to verify the user have the wallet in place - or create it
|
||||
if this fail , dont continue with collecting money , no place to put it.
|
||||
*/
|
||||
long CheckWallet(long member_id,CVars in){
|
||||
logfmt(FLOG_MAX, "long CheckWallet()" );
|
||||
long wallet_id = 0;
|
||||
CVars y;
|
||||
if ( load_db_record( y, "SELECT * FROM members_wallet WHERE currency ='%s' AND member_id =%lu",in["currency"].c_str(),member_id ) > 0 )
|
||||
{
|
||||
wallet_id = y["id"].Long();
|
||||
}
|
||||
else{
|
||||
|
||||
CVars x;
|
||||
x["member_id"] = member_id; x["member_id"].set_valid( true );
|
||||
x["currency"] = in["currency"]; x["currency"].set_valid( true );
|
||||
wallet_id = insert_db_record( DBS_VALID, "members_wallet", "members_wallet_id_seq", x );
|
||||
}
|
||||
return wallet_id;
|
||||
}
|
||||
|
||||
long UpdateMemberWallet(long member_id,long wallet_id,long amount, long payment_id){
|
||||
CVars y;
|
||||
if ( load_db_record( y, "SELECT * FROM members_wallet WHERE id = %lu AND member_id =%lu", wallet_id,member_id ) > 0 )
|
||||
{
|
||||
|
||||
CVars x;
|
||||
x["member_id"] = member_id; x["member_id"].set_valid( true ); //
|
||||
x["payment_id"] = payment_id; x["payment_id"].set_valid( true ); //
|
||||
x["amount"] = amount; x["amount"].set_valid( true ); //
|
||||
x["balance"] = y["amount"]; x["balance"].set_valid( true ); //
|
||||
insert_db_record( DBS_VALID, "members_wallet_detail", "members_wallet_detail_id_seq", x );
|
||||
|
||||
|
||||
pgsql_exec("UPDATE members_wallet SET amount=amount + %lu,prev_amount=%lu WHERE member_id = %lu AND id=%lu",amount,y["amount"].Long(),member_id , wallet_id); // pay attention to who you pay here
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
long DeductMemberWallet(long member_id,long wallet_id,long amount, long payment_id){
|
||||
logfmt(FLOG_MAX, "DeductMemberWallet ************************" );
|
||||
logfmt(FLOG_MAX, "Review this design so as not to loose money ");
|
||||
logfmt(FLOG_MAX, "DeductMemberWallet ************************" );
|
||||
|
||||
CVars y;
|
||||
if ( load_db_record( y, "SELECT * FROM members_wallet WHERE id = %lu AND member_id =%lu", wallet_id,member_id ) > 0 )
|
||||
{
|
||||
|
||||
CVars x;
|
||||
x["member_id"] = member_id; x["member_id"].set_valid( true ); //
|
||||
x["payment_id"] = payment_id; x["payment_id"].set_valid( true ); //
|
||||
x["amount"] = amount; x["amount"].set_valid( true ); //
|
||||
x["balance"] = y["amount"]; x["balance"].set_valid( true ); //
|
||||
insert_db_record( DBS_VALID, "members_wallet_detail", "members_wallet_detail_id_seq", x );
|
||||
pgsql_exec("UPDATE members_wallet SET amount=amount - %lu,prev_amount=%lu WHERE member_id = %lu AND id=%lu",amount,y["amount"].Long(),member_id , wallet_id); // pay attention to who you pay here
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
long WrenchNewCardPayment( CVars in, CVars &out )
|
||||
{
|
||||
long payment_return = 0; // just return 0 if not okay , payment_id is all okay
|
||||
logfmt(FLOG_MAX, "long WrenchNewCardPayment(CVars in, CVars &out)" );
|
||||
long member_id = REQ_LONG( in, "member_id", 1, -1 );
|
||||
long amount = REQ_LONG( in, "amount", 1, -1 );
|
||||
OPTIONAL(in, "WHAT_CHARGE_TYPE") REQ_STRING(in, "WHAT_CHARGE_TYPE", 3, 15, "(.*)");
|
||||
long card_id = 0;
|
||||
|
||||
if ( in["WHAT_CHARGE_TYPE"] == "USE_CARD_ID"){
|
||||
card_id = REQ_LONG( in, "card_id", 1, -1 );
|
||||
in["what_purhcase"] = "MEMBER_RETCARD_PAYM"; in["what_purhcase"].set_valid( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
REQ_STRING(in, "cardnumber", 12, 16, "(.*)"); //4111111111111111"
|
||||
REQ_STRING(in, "cvc", 3, 4, "(.*)"); //234"
|
||||
REQ_LONG(in, "paymenttype", 0, -1);
|
||||
REQ_STRING(in, "exp_month", 2, 2, "(.*)");
|
||||
REQ_STRING(in, "exp_year", 4, 4, "(.*)");
|
||||
in["what_purhcase"] = "MEMBER_NEWCARD_PAYM"; in["what_purhcase"].set_valid( true );
|
||||
}
|
||||
|
||||
|
||||
const char * loc = getenv("REMOTE_ADDR");
|
||||
in["loc"] = loc; in["loc"].set_valid(true);
|
||||
|
||||
long payment_id =0;
|
||||
|
||||
// do we have a wallet for this action
|
||||
CVars vw;
|
||||
vw["currency"] = "USD"; // this might become a variable based on the country
|
||||
vw["currency"].set_valid( true );
|
||||
long wallet_id = CheckWallet(member_id,vw);
|
||||
if(!wallet_id || wallet_id == 0 ){
|
||||
return -1; // no wallet
|
||||
}
|
||||
in["curr_balance"] ="0";
|
||||
long retDb = load_db_record( out, "SELECT amount AS curr_balance FROM members_wallet WHERE member_id = %lu AND currency='%s' ", member_id, vw["currency"].c_str());
|
||||
if (retDb)
|
||||
{ in["curr_balance"] =out["curr_balance"]; in["curr_balance"].set_valid( true );
|
||||
logfmt(FLOG_MAX, "Current balance Read ********************" );
|
||||
}
|
||||
else { return -1; /* unable to read wallet*/ }
|
||||
|
||||
// verify if allowed
|
||||
|
||||
// take in sessionid to verify if allaowed too
|
||||
|
||||
// Get the code and dir contruct
|
||||
long retTc = load_db_record( out, "SELECT * FROM payment_types WHERE type_code = '%s' ",in["what_purhcase"].c_str());
|
||||
if (retTc)
|
||||
{
|
||||
in["code"] = out["code"]; in["code"].set_valid( true );
|
||||
in["dir"] = out["dir"]; in["dir"].set_valid( true );
|
||||
}
|
||||
else { return -1; /* unable to get payment type*/ }
|
||||
|
||||
CVars x;
|
||||
x["member_id"] = member_id; x["member_id"].set_valid( true ); //
|
||||
x["loc"] = in["loc"]; x["loc"].set_valid( true ); //
|
||||
x["curr_balance"] = in["curr_balance"]; x["curr_balance"].set_valid( true ); //
|
||||
x["amount"] = amount; x["amount"].set_valid( true );
|
||||
x["fee"] = "0"; x["fee"].set_valid( true );
|
||||
x["code"] = in["code"]; x["code"].set_valid( true );
|
||||
x["dir"] = in["dir"]; x["dir"].set_valid( true );
|
||||
x["flags"] = FLAG_INIT; x["flags"].set_valid( true ); // starting the pprocess
|
||||
x["currency"] = vw["currency"]; x["currency"].set_valid( true );
|
||||
|
||||
payment_id = insert_db_record( DBS_VALID, "members_payments", "members_payments_id_seq", x );
|
||||
// ALL STRIPE COMPATIBLE
|
||||
if ( card_id == 0 ){
|
||||
card_id = save_creditcard(in, out);
|
||||
}
|
||||
|
||||
|
||||
if (card_id && card_id> 0){
|
||||
pgsql_exec("UPDATE members_payments SET account_id = %lu WHERE id = %lu",card_id,payment_id );
|
||||
}
|
||||
else{
|
||||
return -1;
|
||||
}
|
||||
|
||||
CVars yx;
|
||||
yx["member_id"] = member_id; yx["member_id"].set_valid( true );
|
||||
yx["payment_id"] = payment_id; yx["payment_id"].set_valid( true );
|
||||
long stripe_payment = stripe_charge_member_paymentid(yx, out); // go for stripe now
|
||||
|
||||
if (stripe_payment==PHP_API_OK) {
|
||||
x["flags"] = FLAG_START; x["flags"].set_valid( true ); // done not completed yet
|
||||
//pgsql_exec("UPDATE members_wallet SET amount=amount + %lu,prev_amount=%lu WHERE member_id = %lu AND id=%lu",x["amount"].Long(),x["curr_balance"].Long(),x["member_id"].Long() , wallet_id); // pay attention to who you pay here
|
||||
|
||||
char confirmation[15] = "";
|
||||
Confirmation(payment_id, confirmation, sizeof (confirmation)); // this stamp the offer code directly in that call
|
||||
UpdateMemberWallet( member_id, wallet_id,x["amount"].Long(), payment_id); // correct this dont send amount
|
||||
x["flags"] = FLAG_OK; x["flags"].set_valid( true );
|
||||
x["payment_id"] = payment_id; x["payment_id"].set_valid( true );
|
||||
pgsql_exec("UPDATE members_payments SET flags = %lu WHERE id = %lu",x["flags"].Long(),payment_id );
|
||||
load_db_record( out, "SELECT * FROM members_payments WHERE id = %lu ", payment_id );
|
||||
payment_return = payment_id;
|
||||
} else {
|
||||
out["status"] = "Unable to create payment";
|
||||
}
|
||||
|
||||
logfmt(FLOG_MAX, "/long WrenchNewCardPayment(CVars in, CVars &out)" );
|
||||
return payment_return;
|
||||
}
|
||||
|
||||
long WrenchCardRechargePayment( CVars in, CVars &out )
|
||||
{
|
||||
logfmt(FLOG_MAX, "long WrenchCardRechargePayment(CVars in, CVars &out)" );
|
||||
long member_id = REQ_LONG( in, "member_id", 1, -1 );
|
||||
long amount = REQ_LONG( in, "amount", 1, -1 );
|
||||
long card_id = REQ_LONG( in, "card_id", 1, -1 );
|
||||
in["WHAT_CHARGE_TYPE"] = "USE_CARD_ID"; in["WHAT_CHARGE_TYPE"].set_valid( true ); //
|
||||
return WrenchNewCardPayment( in, out );
|
||||
logfmt(FLOG_MAX, "/long WrenchCardRechargePayment(CVars in, CVars &out)" );
|
||||
}
|
||||
|
||||
long WrenchCanceContractPayment( CVars in, CVars &out )
|
||||
{
|
||||
|
||||
@@ -200,7 +383,11 @@ Foreign-key constraints:
|
||||
REQ_LONG( in, "dir", 1, -1 );
|
||||
REQ_LONG( in, "offer_id", 1, -1 );
|
||||
|
||||
|
||||
CVars vw;
|
||||
vw["currency"] = "NAIRA"; // this might become a variable based on the country
|
||||
vw["currency"].set_valid( true );
|
||||
long wallet_id = CheckWallet(in["member_id"].Long(),vw);
|
||||
|
||||
|
||||
long retDb = load_db_record( out, "SELECT balance AS curr_balance FROM members WHERE id = %lu", in["member_id"].Long());
|
||||
|
||||
@@ -251,7 +438,8 @@ Foreign-key constraints:
|
||||
ret = PHP_CREATED_OK;
|
||||
x["flags"] = FLAG_START; x["flags"].set_valid( true ); // done not completed yet
|
||||
// now generate the confirmation
|
||||
pgsql_exec("UPDATE members SET balance=balance - %lu WHERE id = %lu",in["amount"].Long() + in["fee"].Long(),in["member_id"].Long() );
|
||||
pgsql_exec("UPDATE members SET balance=balance - %lu WHERE id = %lu",in["amount"].Long() + in["fee"].Long(),in["member_id"].Long() );
|
||||
DeductMemberWallet(in["member_id"].Long(), wallet_id,in["amount"].Long(), payment_id);
|
||||
char confirmation[15] = "";
|
||||
Confirmation(payment_id, confirmation, sizeof (confirmation)); // this stamp the offer code directly in that call
|
||||
x["flags"] = FLAG_OK; x["flags"].set_valid( true );
|
||||
@@ -496,6 +684,11 @@ Foreign-key constraints:
|
||||
REQ_LONG( in, "dir", 1, -1 );
|
||||
REQ_LONG( in, "sendmoney_id", 1, -1 );
|
||||
|
||||
CVars vw;
|
||||
vw["currency"] = "NAIRA"; // this might become a variable based on the country
|
||||
vw["currency"].set_valid( true );
|
||||
long wallet_id = CheckWallet(in["member_id"].Long(),vw);
|
||||
|
||||
|
||||
long retDb = load_db_record( out, "SELECT balance AS curr_balance FROM members WHERE id = %lu", in["member_id"].Long());
|
||||
|
||||
@@ -553,27 +746,22 @@ Foreign-key constraints:
|
||||
out["status"] = "Failure to create";
|
||||
return PHP_API_BAD_PARAM;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
out["payment_id"] = payment_id; out["payment_id"].set_valid( true );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (payment_id) {
|
||||
ret = PHP_CREATED_OK;
|
||||
|
||||
x["flags"] = FLAG_START; x["flags"].set_valid( true ); // done not completed yet
|
||||
// now generate the confirmation
|
||||
pgsql_exec("UPDATE members SET balance=balance - %lu WHERE id = %lu",in["amount"].Long() + in["fee"].Long(),in["member_id"].Long() );
|
||||
//pgsql_exec("UPDATE members SET balance=balance - %lu WHERE id = %lu",in["amount"].Long() + in["fee"].Long(),in["member_id"].Long() );
|
||||
DeductMemberWallet(in["member_id"].Long(), wallet_id,in["amount"].Long() + in["fee"].Long(), payment_id);
|
||||
char confirmation[15] = "";
|
||||
Confirmation(payment_id, confirmation, sizeof (confirmation)); // this stamp the offer code directly in that call
|
||||
x["flags"] = FLAG_OK; x["flags"].set_valid( true );
|
||||
x["payment_id"] = payment_id; x["payment_id"].set_valid( true );
|
||||
pgsql_exec("UPDATE members_payments SET flags = %lu WHERE id = %lu",x["flags"].Long(),payment_id );
|
||||
load_db_record( out, "SELECT * FROM members_payments WHERE id = %lu ", payment_id );
|
||||
ret = PHP_CREATED_OK;
|
||||
|
||||
load_db_record( out, "SELECT * FROM members_payments WHERE id = %lu ", payment_id );
|
||||
} else {
|
||||
out["status"] = "Uanble to create payment";
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
#include "pgsql.h"
|
||||
#include "pgsql_wrapper.h"
|
||||
#include <curl/curl.h>
|
||||
#include "email.h"
|
||||
#include "payments.h"
|
||||
#include "common_tool.h"
|
||||
|
||||
long smoney_calls(CVars in, CVars &out) {
|
||||
logfmt(logINFO, "smoney_calls()");
|
||||
@@ -130,11 +133,17 @@ long member_sendmoney_fee(CVars in, CVars &out) {
|
||||
return out["processing_fee"].Long();
|
||||
}
|
||||
|
||||
long WRB_doServiceTransferComplete(CVars in, CVars &out);
|
||||
long do_transferPayment(CVars in) ;
|
||||
long INTW_configure(CVars in, CVars &out) ;
|
||||
|
||||
long member_sendmoney(CVars in, CVars &out) {
|
||||
//plog->SetFileName( PREFIX"/logs/member_sendmoney.log" );
|
||||
//return INTW_doServiceTransfer(in, out);
|
||||
return -1L;
|
||||
//return 0;
|
||||
long ret = WRB_doServiceTransferComplete(in, out);
|
||||
|
||||
logfmt(logINFO, "************************ E****** member_sendmoney(CVars in, CVars out) =%lu",ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
long member_addrecipient(CVars in, CVars &out) {
|
||||
@@ -233,3 +242,367 @@ Referenced by:
|
||||
|
||||
|
||||
|
||||
long INTW_configure(CVars in, CVars &out) {
|
||||
logfmt(logINFO, "long INTW_configure(CVars in, CVars &out)");
|
||||
long ret = PHP_API_BAD_PARAM;
|
||||
try {
|
||||
// Configure Interswitch SSL
|
||||
|
||||
|
||||
out["interswitch_ver"] = CfgReadLong("interswitch.version");
|
||||
out["interswitch_sep"] = CfgReadChar("interswitch.soap_endpoint");
|
||||
out["interswitch_tid"] = CfgReadChar("interswitch.terminal_id");
|
||||
out["interswitch_code"] = CfgReadChar("interswitch.entity_code");
|
||||
out["interswitch_mkey"] = CfgReadChar("interswitch.master_key");
|
||||
out["interswitch_pin"] = CfgReadChar("interswitch.pin");
|
||||
out["interswitch_pfix"] = CfgReadChar("interswitch.prefix");
|
||||
out["interswitch_keyf"] = CfgReadChar("interswitch.keyfile");
|
||||
out["interswitch_pass"] = CfgReadChar("interswitch.password");
|
||||
out["interswitch_cert"] = CfgReadChar("interswitch.cacert");
|
||||
|
||||
ret = PHP_API_OK;
|
||||
|
||||
} catch (bad_parameter) {
|
||||
|
||||
out["status"] = "Bad parameter";
|
||||
|
||||
} catch (...) {
|
||||
|
||||
out["status"] = "Unhandled exception in INTW_configure";
|
||||
|
||||
}
|
||||
logfmt(logINFO, "/long INTW_configure(CVars in, CVars &out)");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
long do_transferPayment(CVars in) {
|
||||
long ret = PHP_API_BAD_PARAM;
|
||||
CVars out;
|
||||
|
||||
long customer_id = REQ_LONG(in, "customer_id", 1, -1);
|
||||
long transfer_id = REQ_LONG(in, "transfer_id", 1, -1);
|
||||
long payMode = REQ_LONG(in, "mode", 1, -1);
|
||||
long payment_id = 0;
|
||||
long amount = 0;
|
||||
long fee = 0;
|
||||
long total = 0;
|
||||
|
||||
|
||||
/*
|
||||
CREATE TABLE sendmoney_payment
|
||||
(
|
||||
id serial NOT NULL,
|
||||
transfer_mode integer NOT NULL,
|
||||
customer_id INT REFERENCES customer(id),
|
||||
transfer_id INT REFERENCES interswitch_money_transfer(id),
|
||||
amount integer DEFAULT 0,
|
||||
fee integer DEFAULT 0,
|
||||
total integer DEFAULT 0,
|
||||
current_balance integer DEFAULT 0,
|
||||
new_balance integer DEFAULT 0,
|
||||
status integer DEFAULT 1,
|
||||
added TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
*/
|
||||
|
||||
ret = load_db_record(out, "SELECT balance FROM members WHERE id = %lu AND status = 1", customer_id);
|
||||
if (ret < 1L) {
|
||||
throw new bad_parameter(out, "senderid");
|
||||
}
|
||||
|
||||
if (payMode == PAYMENT_MODE) {
|
||||
amount = REQ_LONG(in, "amount", 1, -1);
|
||||
fee = REQ_LONG(in, "fee", 1, -1);
|
||||
total = amount + fee; // make sure you are cent here
|
||||
|
||||
if (out["balance"].Long() >= total) // do you have this money
|
||||
{
|
||||
CVars x;
|
||||
x["transfer_mode"] = PAYMENT_MODE;
|
||||
x["transfer_mode"].set_valid(true);
|
||||
x["member_id"] = customer_id;
|
||||
x["member_id"].set_valid(true);
|
||||
x["transfer_id"] = transfer_id;
|
||||
x["transfer_id"].set_valid(true);
|
||||
x["amount"] = amount;
|
||||
x["amount"].set_valid(true);
|
||||
x["fee"] = fee;
|
||||
x["fee"].set_valid(true);
|
||||
x["total"] = total;
|
||||
x["total"].set_valid(true);
|
||||
x["current_balance"] = out["balance"];
|
||||
x["current_balance"].set_valid(true);
|
||||
payment_id = 0;
|
||||
|
||||
out["payment_id"] = insert_db_record(DBS_VALID, "sendmoney_payment", "sendmoney_payment_id_seq", x);
|
||||
char confirmation[20] = "";
|
||||
Confirmation(payment_id, confirmation, sizeof (confirmation));
|
||||
|
||||
|
||||
|
||||
|
||||
ret = PHP_API_BAD_PARAM; // it is still a failure if we get here and did not take the money out of the balance
|
||||
|
||||
CVars y;
|
||||
y["member_id"] = x["member_id"];
|
||||
y["member_id"].set_valid(true);
|
||||
y["sendmoney_id"] = x["transfer_id"];
|
||||
y["sendmoney_id"].set_valid(true);
|
||||
y["code"] = "SMPAY";
|
||||
y["code"].set_valid(true);
|
||||
y["dir"] = DIR_TARGET;
|
||||
y["dir"].set_valid(true);
|
||||
//y["payment_id"] = out["payment_id"]; y["payment_id"].set_valid( true );
|
||||
|
||||
ret = WrenchSendMoneyPayment(y, out);
|
||||
|
||||
if (ret == PHP_CREATED_OK) {
|
||||
load_db_record(out, "SELECT balance AS new_balance FROM members WHERE id = %lu", customer_id);
|
||||
pgsql_exec("UPDATE sendmoney_payment SET new_balance=%lu WHERE id=%lu", out["new_balance"].Long(), out["payment_id"].Long());
|
||||
ret = PHP_API_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (payMode == REFUND_MODE) {
|
||||
if (load_db_record(out, "SELECT * FROM sendmoney_payment WHERE transfer_id = %lu AND member_id = %lu", transfer_id, customer_id)) {
|
||||
logfmt(logINFO, "*****WE RE DO VERIFICATION and NO DUPLICATES)");
|
||||
logfmt(logINFO, "**)");
|
||||
logfmt(logINFO, "**)");
|
||||
logfmt(logINFO, "**)");
|
||||
logfmt(logINFO, "**)");
|
||||
logfmt(logINFO, "**)");
|
||||
logfmt(logINFO, "**)");
|
||||
logfmt(logINFO, "**)");
|
||||
logfmt(logINFO, "**)");
|
||||
CVars out;
|
||||
/*REQ_STRING( in, "TransferCode", 3, 30, "(.*)" );
|
||||
REQ_STRING( in, "requestReference", 3, 30, "(.*)" );*/
|
||||
|
||||
//int vRet = INTW_querySendMoneyTransaction(in, out);
|
||||
ret = PHP_API_OK;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//PAYMENT_MODE
|
||||
//REFUND_MODE
|
||||
|
||||
return ret;
|
||||
}
|
||||
//*****************************************************************************/
|
||||
|
||||
long WRB_doServiceTransferComplete(CVars in, CVars &out) {
|
||||
//plog->SetFileName( PREFIX"/logs/send_money.log" );
|
||||
|
||||
logfmt(logINFO, "long WRB_doServiceTransferComplete(CVars in, CVars &out)");
|
||||
long ret = PHP_API_BAD_PARAM;
|
||||
try {
|
||||
|
||||
out = in;
|
||||
// Initiate interswitch session
|
||||
CVars setup;
|
||||
INTW_configure(in, setup);
|
||||
|
||||
|
||||
in["action"].set_valid(false);
|
||||
REQ_STRING(in, "InitiatingEntityCode", 3, 3, "(.*)");
|
||||
REQ_LONG(in, "InitiatingAmount", 1, -1);
|
||||
REQ_LONG(in, "Fee", 1, -1);
|
||||
REQ_LONG(in, "InitiatingChannel", 1, -1);
|
||||
REQ_STRING(in, "InitiatingPaymentMethodCode", 2, 2, "(.*)");
|
||||
REQ_STRING(in, "InitiatingCurrencyCode", 3, 3, "(.*)");
|
||||
REQ_STRING(in, "TerminatingPaymentMethodCode", 2, 2, "(.*)");
|
||||
REQ_LONG(in, "TerminatingAmount", 1, -1);
|
||||
REQ_STRING(in, "TerminatingCurrencyCode", 3, 3, "(.*)");
|
||||
REQ_STRING(in, "TerminatingCountryCode", 2, 2, "(.*)");
|
||||
|
||||
//REQ_STRING( in, "TerminatingEntityCode", 1, 5, "(.*)" );
|
||||
//REQ_STRING( in, "TerminatingAccountNumber", 1, 50, "(.*)" );
|
||||
//REQ_STRING( in, "TerminatingAccountType", 2, 2, "(.*)" );
|
||||
|
||||
long senderid = REQ_LONG(in, "senderid", 1, -1);
|
||||
long recipientid = REQ_LONG(in, "recipientid", 1, -1);
|
||||
|
||||
in["InitiatingEntityCode"] = "MBA";
|
||||
in["InitiatingEntityCode"].set_valid(true);
|
||||
|
||||
|
||||
CVars sender; // Load sender
|
||||
ret = load_db_record(sender, "SELECT firstname,lastname,balance FROM members WHERE id = %lu AND status = 1", senderid);
|
||||
if (ret < 1L) {
|
||||
throw new bad_parameter(out, "senderid");
|
||||
}
|
||||
|
||||
long LongTotalCost = in["Fee"].Long() + in["TerminatingAmount"].Long() + 0;
|
||||
|
||||
if (sender["balance"].Long() < LongTotalCost) {
|
||||
throw new bad_parameter(out, "insufficient balance for transaction");
|
||||
}
|
||||
|
||||
|
||||
|
||||
CVars recipient; // Load recipient
|
||||
/*recipient["firstname"] = in["firstname"]; recipient["firstname"].set_valid( true );
|
||||
recipient["lastname"] = in["lastname"]; recipient["lastname"].set_valid( true );
|
||||
recipient["account_no"] = in["account_no"]; recipient["account_no"].set_valid( true );
|
||||
recipient["bank_code"] = in["bank_code"]; recipient["bank_code"].set_valid( true );
|
||||
recipient["account_type"] = in["account_type"]; recipient["account_type"].set_valid( true );*/
|
||||
ret = load_db_record(recipient, "SELECT firstname,lastname,account_no,bank_code,account_type FROM sendmoney_recipient WHERE id = %lu AND member_id = %lu AND status = 1", recipientid, senderid);
|
||||
if (ret < 1L) {
|
||||
throw new bad_parameter(out, "recipientid");
|
||||
}
|
||||
|
||||
in["TerminatingEntityCode"] = recipient["bank_code"];
|
||||
in["TerminatingEntityCode"].set_valid(true);
|
||||
in["TerminatingAccountNumber"] = recipient["account_no"];
|
||||
in["TerminatingAccountNumber"].set_valid(true);
|
||||
in["transactionID"] = in["transaction_id"];
|
||||
in["transactionID"].set_valid(true);
|
||||
|
||||
CVars inx;
|
||||
inx["Fee"] = in["Fee"];
|
||||
inx["Fee"].set_valid(true);
|
||||
inx["InitiatingAmount"] = in["InitiatingAmount"];
|
||||
inx["InitiatingAmount"].set_valid(true);
|
||||
|
||||
inx["InitiatingChannel"] = in["InitiatingChannel"];
|
||||
inx["InitiatingChannel"].set_valid(true);
|
||||
inx["InitiatingCurrencyCode"] = in["InitiatingCurrencyCode"];
|
||||
inx["InitiatingCurrencyCode"].set_valid(true);
|
||||
|
||||
inx["InitiatingEntityCode"] = in["InitiatingEntityCode"];
|
||||
inx["InitiatingEntityCode"].set_valid(true);
|
||||
inx["InitiatingPaymentMethodCode"] = in["InitiatingPaymentMethodCode"];
|
||||
inx["InitiatingPaymentMethodCode"].set_valid(true);
|
||||
|
||||
inx["TerminatingAccountNumber"] = in["TerminatingAccountNumber"];
|
||||
inx["TerminatingAccountNumber"].set_valid(true);
|
||||
inx["TerminatingAmount"] = in["TerminatingAmount"];
|
||||
inx["TerminatingAmount"].set_valid(true);
|
||||
|
||||
inx["TerminatingCountryCode"] = in["TerminatingCountryCode"];
|
||||
inx["TerminatingCountryCode"].set_valid(true);
|
||||
inx["TerminatingCurrencyCode"] = in["TerminatingCurrencyCode"];
|
||||
inx["TerminatingCurrencyCode"].set_valid(true);
|
||||
|
||||
inx["TerminatingEntityCode"] = in["TerminatingEntityCode"];
|
||||
inx["TerminatingEntityCode"].set_valid(true);
|
||||
inx["TerminatingPaymentMethodCode"] = in["TerminatingPaymentMethodCode"];
|
||||
inx["TerminatingPaymentMethodCode"].set_valid(true);
|
||||
|
||||
inx["recipientid"] = in["recipientid"];
|
||||
inx["recipientid"].set_valid(true);
|
||||
inx["member_id"] = in["senderid"];
|
||||
inx["member_id"].set_valid(true);
|
||||
inx["transactionID"] = in["transactionID"];
|
||||
inx["transactionID"].set_valid(true);
|
||||
|
||||
inx["transfer_code"] = "";
|
||||
inx["transfer_code"].set_valid(true);
|
||||
|
||||
|
||||
out["money_transfer_id"] = insert_db_record(DBS_VALID, "money_transfer", " money_transfer_id_seq", inx);
|
||||
if (out["money_transfer_id"].Long() < 1L) {
|
||||
throw new runtime_error("Failed to create money transfer record");
|
||||
}
|
||||
|
||||
const PGresult *res = pgsql_query("SELECT * FROM money_transfer WHERE id=%lu AND member_id = %lu", out["money_transfer_id"].Long(), in["member_id"].Long());
|
||||
if (res != NULL && pgsql_num_rows(res) > 0) {
|
||||
|
||||
} else {
|
||||
throw new runtime_error("Failed to create money_transfer record");
|
||||
}
|
||||
|
||||
CVars transaction;
|
||||
transaction["detail_id"] = out["money_transfer_id"];
|
||||
transaction["detail_id"].set_valid(true);
|
||||
transaction["type"] = 2L;
|
||||
/* DoTransfer */ transaction["type"].set_valid(true);
|
||||
out["transaction_id"] = insert_db_record(DBS_VALID, "money_transfer_transaction", "money_transfer_transaction_id_seq", transaction);
|
||||
if (out["transaction_id"].Long() < 1L) {
|
||||
throw new runtime_error("Failed to create money_transfer_transaction record");
|
||||
}
|
||||
CVars transaction_final;
|
||||
|
||||
char xtid[12], uniqueRef[20];
|
||||
memset(uniqueRef, 0, 20);
|
||||
// TransferCode - RequestReference - UniqueRef => request prefix for terminal owner + ID
|
||||
sprintf(uniqueRef, "%s%s000000", setup["interswitch_pfix"].c_str(), out["transaction_id"].c_str());
|
||||
//sprintf( uniqueRef, "%s%-09lu", setup["interswitch_pfix"].c_str(), out["transaction_id"].Long() );
|
||||
|
||||
transaction["transfer_code"] = uniqueRef;
|
||||
transaction["transfer_code"].set_valid(true);
|
||||
transaction_final["transfer_code"] = transaction["transfer_code"];
|
||||
transaction_final["transfer_code"].set_valid(true);
|
||||
|
||||
pgsql_exec("UPDATE money_transfer SET transfer_code='%s' WHERE id=%lu", transaction_final["transfer_code"].c_str(), out["money_transfer_id"].Long());
|
||||
|
||||
//sprintf( xtid, "%s", setup["interswitch_tid"].c_str() );
|
||||
sprintf(xtid, "%s", setup["interswitch_tid"].c_str());
|
||||
|
||||
|
||||
//in["SenderEmail"] = sender["email"]; in["SenderEmail"].set_valid(true);
|
||||
//in["BeneficiaryEmail"] = recipient["email"]; in["BeneficiaryEmail"].set_valid(true);
|
||||
|
||||
//*TAKE THE MONEY NOW
|
||||
CVars pm;
|
||||
pm["customer_id"] = senderid;
|
||||
pm["customer_id"].set_valid(true);
|
||||
pm["transfer_id"] = out["money_transfer_id"];
|
||||
pm["transfer_id"].set_valid(true);
|
||||
pm["amount"] = in["InitiatingAmount"];
|
||||
pm["amount"].set_valid(true);
|
||||
pm["fee"] = in["Fee"];
|
||||
pm["fee"].set_valid(true);
|
||||
pm["mode"] = PAYMENT_MODE;
|
||||
pm["mode"].set_valid(true);
|
||||
|
||||
/*
|
||||
#define SM_PENDING 1
|
||||
#define SM_CANCEL 3
|
||||
#define SM_FAILED 4
|
||||
#define SM_COMPLETED 5
|
||||
*/
|
||||
if (do_transferPayment(pm) == PHP_API_OK) {
|
||||
out["sendmoney_status"] = SM_PENDING;
|
||||
in["sendmoney_id"] = out["money_transfer_id"];
|
||||
ret = PHP_API_OK;
|
||||
sendmoney_email(SM_PENDING, in, out);
|
||||
// all is good on money side
|
||||
logfmt(logINFO, "*** ALL Good ------ ****** ");
|
||||
} else {
|
||||
out["sendmoney_status"] = SM_FAILED;
|
||||
throw new runtime_error("Failed to create payment record");
|
||||
}
|
||||
|
||||
load_db_record(out, "SELECT r.firstname, r.lastname, m.*,mp.confirmation,r.firstname||' '||r.lastname AS Recitient,r.account_no,b.name AS bank_name FROM money_transfer m LEFT JOIN members_payments mp ON mp.what_sendmoney = m.id LEFT JOIN sendmoney_recipient r ON r.id = m.recipientid LEFT JOIN bank_entity_codes b ON b.code = r.bank_code WHERE m.id=%lu", out["money_transfer_id"].Long());
|
||||
|
||||
} catch (runtime_error& ex) {
|
||||
|
||||
out["status"] = ex.what();
|
||||
ret = PHP_API_BAD_PARAM;
|
||||
|
||||
} catch (bad_parameter) {
|
||||
|
||||
out["status"] = "Invalid input";
|
||||
ret = PHP_API_BAD_PARAM;
|
||||
|
||||
} catch (...) {
|
||||
|
||||
out["status"] = "Unhandled exception in INTW_doTransfer";
|
||||
ret = PHP_API_BAD_PARAM;
|
||||
|
||||
}
|
||||
|
||||
//out["wallet"].set_valid( false );
|
||||
|
||||
logfmt(logINFO, "/long WRB_doServiceTransferComplete(CVars in, CVars &out)");
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
@@ -294,10 +294,9 @@ long stripe_charge_member_paymentid(CVars in, CVars &out) {
|
||||
logfmt(logINFO, "stripe_charge_member_paymentid()");
|
||||
out["result"] = "stripe_charge_member_paymentid() call in progress...";
|
||||
long res, ret = PHP_API_BAD_PARAM;
|
||||
|
||||
|
||||
try {
|
||||
REQ_LONG(in, "service_id", 0, -1);
|
||||
// REQ_LONG(in, "service_id", 0, -1);
|
||||
// REQ_LONG(in, "payment_id", 0, -1);
|
||||
REQ_LONG(in, "member_id", 0, -1);
|
||||
long payment_id = REQ_LONG(in, "payment_id", 0, -1);
|
||||
|
||||
@@ -318,7 +317,7 @@ long stripe_charge_member_paymentid(CVars in, CVars &out) {
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
in["description"] = "Laundry Pickup";
|
||||
in["description"] = "Account Recharge";
|
||||
in["invoice_id"] = in["payment_id"];
|
||||
|
||||
|
||||
@@ -350,7 +349,10 @@ long stripe_charge_member_paymentid(CVars in, CVars &out) {
|
||||
ret = PHP_API_OK;
|
||||
out["id"] = id;
|
||||
pgsql_exec("UPDATE members_payments SET stripe_confirm='%s',dt_confirmed=now() WHERE id = %lu", id, payment_id);
|
||||
//pgsql_exec("UPDATE members_service_request SET payment_id=%lu,dt_confirmed=now(),flags=%lu WHERE id = %lu",payment_id, CONFIRMED , in["service_id"].Long());
|
||||
/*
|
||||
|
||||
|
||||
*/
|
||||
|
||||
out["result"] = "Charge success";
|
||||
} else {
|
||||
|
||||
+89
-3
@@ -1,4 +1,90 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
function excudedEmails(){
|
||||
return [
|
||||
'ses6681+1@gmail.com',
|
||||
'tokslawus@gmail.com',
|
||||
'ses6681+1@gmail.com',
|
||||
'ameye@chiefsoft.com',
|
||||
'ses66181@gmail.com',
|
||||
];
|
||||
}
|
||||
|
||||
if (in_array("ses6681+3@gmail.com", excudedEmails()))
|
||||
{
|
||||
echo "found";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "not found";
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
|
||||
/*
|
||||
$ar1 = [
|
||||
"color" => "red",
|
||||
"sex" => "male",
|
||||
];
|
||||
|
||||
|
||||
$ar2 = ["color" => "green", ];
|
||||
$result = array_merge_recursive($ar1, $ar2);
|
||||
print_r($result);*/
|
||||
print_r( spaTranslationsCall());
|
||||
|
||||
|
||||
function spaTranslationsCall()
|
||||
{
|
||||
return array_merge_recursive(spaTranslations(),[
|
||||
'hide_boards' => 'Hide Boards',
|
||||
'draw_numbers' => 'Draw Number(s)',
|
||||
'next_draw' => 'Next Draw',
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function spaTranslations(){
|
||||
return [
|
||||
'cart_title' => 'Below you can review and adjust the games you have added',
|
||||
'cart_subtitle' => 'Select a row to see more details',
|
||||
'cart_empty' => 'Your cart is empty.',
|
||||
'cart_summary_title' => 'Below are the entries you purchased!',
|
||||
'cart_summary_title_fail' => 'Your transaction could not be completed, please try again.',
|
||||
'cart_summary_title_some_fail' => 'Some tickets could not be played, please return to cart and try again.',
|
||||
'show_boards' => 'Expand to display boards',
|
||||
'board' => 'Board',
|
||||
'week' => 'Week',
|
||||
'current_shopping_cart_total' => 'Your current Shopping Cart total is',
|
||||
'subtotal' => 'Subtotal',
|
||||
'discount' => 'Discount',
|
||||
'voucher_discount' => 'Voucher Discount',
|
||||
'total' => 'Total',
|
||||
'clear_cart_confirmation' => 'Do you realy want to empty your cart?',
|
||||
'cart_delete_confirmation' => 'Do you really want to delete this cart item?',
|
||||
'number_of_draws' => 'Multi draws',
|
||||
'ticket_update' => 'Update Ticket',
|
||||
'ticket_updated' => 'Your ticket was Updated, return to cart to replay.',
|
||||
'ticket_id' => 'Ticket ID',
|
||||
'wager_id' => 'Wager ID',
|
||||
'next_draw' => 'Next draw',
|
||||
'btn_continue_playing' => 'Continue Playing',
|
||||
'cart_draw_date' => 'Date',
|
||||
'details_date_at' => 'at',
|
||||
'details_date_from' => 'from',
|
||||
'details_date_to' => 'to',
|
||||
'no_of_draws' => 'No of Draws',
|
||||
'handling_fee' => 'Handling Fee',
|
||||
'price_details_title' => 'Price Details',
|
||||
'cart_item_price' => 'Price',
|
||||
'details_total' => 'Total',
|
||||
'system_played' => 'System',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
$USER = $_SERVER['SCRIPT_FILENAME'];
|
||||
$USER = str_replace('/home', '', $USER);
|
||||
$USER = strtok($USER, '/');
|
||||
@@ -7,6 +93,6 @@ $USER = strtok($USER, '/');
|
||||
$wrenchboard_class = 'wrenchboard_api_' . $USER . '\\WrenchBoard';
|
||||
$wrenchboard = new $wrenchboard_class();
|
||||
$ret = $wrenchboard->wrenchboard_api($in,$out);
|
||||
var_dump($ret);
|
||||
phpinfo();
|
||||
//var_dump($ret);
|
||||
//phpinfo();
|
||||
?>
|
||||
|
||||
+2
-1
@@ -11,13 +11,14 @@ $wrenchboard = new $wrenchboard_class();
|
||||
|
||||
|
||||
|
||||
Array ( [title] => Re:Week 1 CAT 2: “Muddiest” Point [description] => sffss [timeline] => 3 [job_detail] => sgsagsagashas [price] => 5000 [action] => 0 )
|
||||
//Array ( [title] => Re:Week 1 CAT 2: “Muddiest” Point [description] => sffss [timeline] => 3 [job_detail] => sgsagsagashas [price] => 5000 [action] => 0 )
|
||||
|
||||
|
||||
$data['firstname'] = 'Olu';
|
||||
$data['lastname'] = 'Amey';
|
||||
|
||||
$email = 'ses66181+1@gmail.com';
|
||||
$email = 'acidumirae@gmail.com';
|
||||
$data['email'] = $email;
|
||||
$data['username'] = $email;
|
||||
$data['password'] = 'may12002';
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
require_once 'config.php';
|
||||
$url = $local_url . "/createuser";
|
||||
|
||||
$username = urlencode("ses66181+" . rand(1000, 9999) . "@gmail.com");
|
||||
$username = urlencode("jubaworker+" . rand(1000, 9999) . "@gmail.com");
|
||||
|
||||
$username = "ses66181+" . rand(1000, 9999) . "@gmail.com";
|
||||
$username = "jubaworker+" . rand(1000, 9999) . "@gmail.com";
|
||||
//$username = "ameye+" . rand(1000, 9999) . "@chiefsoft.com";
|
||||
//$username = "ses66181+" . rand(1000, 9999) . "@gmail.com";
|
||||
$phone = (rand(1, 2) > 1) ? "770222" . rand(2222, 9999) : '';
|
||||
|
||||
include 'sample_data.php'; // just for sample data
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<pre>
|
||||
<?php
|
||||
//#define WRENCHBOARD_USER_ADNEWCC 11054
|
||||
|
||||
include('../backend.php');
|
||||
$hostname = $wrenchboard->cfgReadChar("database.host");
|
||||
@@ -16,7 +17,7 @@ $in=array(
|
||||
"action" => 90005, /* WRENCHBOARD_STRIPE_CHARGE_NEW */
|
||||
"ccnum" => "4242424242424242",
|
||||
"ccexpm" => "12",
|
||||
"ccexpy" => "18",
|
||||
"ccexpy" => "26",
|
||||
"cccvc" => "123",
|
||||
"amount" => "100",
|
||||
"customer_id" => $f["id"],
|
||||
|
||||
@@ -92,7 +92,7 @@ define('PHP_API_OK', 0);
|
||||
define('PHP_LOGIN_OK', 100);
|
||||
define('PHP_CREATED_OK', 10);
|
||||
define('PHP_API_BAD_PARAM', -1);
|
||||
define('SESSION_TIMEOUT_LOGOUT',72000);
|
||||
define('SESSION_TIMEOUT_LOGOUT',144000);
|
||||
|
||||
define('SUPPORT_PHONE','+234 (818)-3866434');
|
||||
|
||||
@@ -169,6 +169,10 @@ define('WRENCHBOARD_LOG_MEMBER', 11040);
|
||||
define('WRENCHBOARD_DELETE_RECACC', 11041);
|
||||
define('WRENCHBOARD_SAVE_GALLERY', 11042);
|
||||
|
||||
define('WRENCHBOARD_USER_ADNEWCC', 11054);
|
||||
define('WRENCHBOARD_USER_USESAVEDCC', 11056);
|
||||
|
||||
define('WRENCHBOARD_USER_DELETEACC', 11990);
|
||||
define('WRENCHBOARD_ACCOUNT_END', 11999);
|
||||
//**************************************************************
|
||||
define('WRENCHBOARD_JOB_CREATEJOB',13010 );
|
||||
@@ -269,3 +273,7 @@ define('PAY_MODE_BONUS', 9);
|
||||
define('APPROVED_BALANCE', 5);
|
||||
define('DISAPROVE_BALANCE', 3);
|
||||
|
||||
|
||||
define('WRENCHBOARD_USER_SENDMONEY', 11051);
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,9 @@ defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
| Examples: my-controller/index -> my_controller/index
|
||||
| my-controller/my-method -> my_controller/my_method
|
||||
*/
|
||||
$route['default_controller'] = 'site';
|
||||
$route['default_controller'] = 'login';
|
||||
$route['404_override'] = 'Wrb404';
|
||||
$route['translate_uri_dashes'] = FALSE;
|
||||
$route['auth/(.+)'] = 'home/auth/$1';
|
||||
|
||||
$route['cardreciepts/(.+)'] = 'paymnt/cardreciepts/$1';
|
||||
|
||||
@@ -25,7 +25,8 @@ class Bkotransaction extends Bko_Controller {
|
||||
$mysql = "SELECT m.id,mp.confirmation, m.added,me.firstname||' '||me.lastname||'<br>'||me.email AS Sender,"
|
||||
. "sr.firstname||' '||sr.lastname||'<br>ACC:'||sr.account_no||'-'||be.name AS recipient, m.initiatingamount*0.01 AS Amount,m.fee*0.01 AS Fee, "
|
||||
. "'<input type=submit id=\"accs'||m.id||'\" onclick=\"return smoneyDetail('||m.id||')\" name=\"manage\" class=\"btn btn-info btn-sm\" value=\"Detail\">' As Detail, "
|
||||
. "'<input type=submit id=\"acc'||m.id||'\" onclick=\"return smoneyProcess('||m.id||')\" name=\"manage\" class=\"btn btn-info btn-sm\" value=\"Process\">' As Process "
|
||||
. "'<input type=submit id=\"acc'||m.id||'\" onclick=\"return smoneyProcess('||m.id||')\" name=\"manage\" class=\"btn btn-info btn-sm\" value=\"Process\">' As Process, "
|
||||
. "m.initiatingamount AS raw_amount, m.fee AS raw_fee, sr.bank_code, sr.account_no "
|
||||
. "FROM money_transfer m "
|
||||
. "LEFT JOIN members me ON me.id=m.member_id "
|
||||
. "LEFT JOIN sendmoney_recipient sr ON sr.id=m.recipientid "
|
||||
@@ -39,7 +40,7 @@ class Bkotransaction extends Bko_Controller {
|
||||
|
||||
break;
|
||||
|
||||
case 'TRANSDETAIL':
|
||||
case 'TRANSDETAIL':
|
||||
|
||||
$mysql = "SELECT m.id,mp.confirmation, m.added,me.firstname||' '||me.lastname||'<br>'||me.email AS Sender,"
|
||||
. "sr.firstname||' '||sr.lastname||'<br>ACC:'||sr.account_no||'-'||be.name AS recipient, m.initiatingamount*0.01 AS Amount,m.fee*0.01 AS Fee "
|
||||
@@ -65,93 +66,155 @@ class Bkotransaction extends Bko_Controller {
|
||||
|
||||
case 'COMPLETE':
|
||||
//echo 'complete 1';
|
||||
// url: "/bkotransaction/smprocess?proc=COMPLETE&sendmoney_id="+link_id+'&tcode='+tcode+'&tref='+tref
|
||||
// url: "/bkotransaction/smprocess?proc=COMPLETE&sendmoney_id="+link_id+'&tcode='+tcode+'&tref='+tref
|
||||
$data["trans_code"] = $this->input->get('tcode');
|
||||
$data["trans_tref"] = $this->input->get('tref');
|
||||
$data["sendmoney_id"] = $sendmoney_id;
|
||||
$data['action'] = WRENCHBOARD_SMONEY_BKOPROC;
|
||||
$data['action_mode'] = SMONEY_PROCC_MANUAL;
|
||||
$this->load->model('backend_model');
|
||||
$out = array();
|
||||
$this->backend_model->wrenchboard_api($data, $out);
|
||||
echo $out['status'];
|
||||
|
||||
|
||||
echo $this->sendmoneyCompletePage($data);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
protected function sendmoneyCompletePage($data) {
|
||||
$data['action'] = WRENCHBOARD_SMONEY_BKOPROC;
|
||||
$data['action_mode'] = SMONEY_PROCC_MANUAL;
|
||||
$this->load->model('backend_model');
|
||||
$out = array();
|
||||
$this->backend_model->wrenchboard_api($data, $out);
|
||||
return $out['status'];
|
||||
}
|
||||
|
||||
|
||||
public function smTransmitProcess() {
|
||||
// url: "/bkotransaction/smprocess?proc=PROCESS&sendmoney_id="+link_id
|
||||
$proc = $this->input->get('proc');
|
||||
$sendmoney_id = $this->input->get('sendmoney_id');
|
||||
// url: "/bkotransaction/smprocess?proc=PROCESS&sendmoney_id="+link_id
|
||||
$proc = $this->input->get('proc');
|
||||
$sendmoney_id = $this->input->get('sendmoney_id');
|
||||
|
||||
switch ($proc) {
|
||||
case 'PROCESS':
|
||||
$mysql = "SELECT m.id,mp.confirmation, m.added,me.firstname||' '||me.lastname||'<br>'||me.email AS Sender,"
|
||||
. "sr.firstname||' '||sr.lastname||'<br>ACC:'||sr.account_no||'-'||be.name AS recipient, m.initiatingamount*0.01 AS Amount,m.fee*0.01 AS Fee, "
|
||||
. "'<input type=submit id=\"accs'||m.id||'\" onclick=\"return smoneyDetail('||m.id||')\" name=\"manage\" class=\"btn btn-info btn-sm\" value=\"Detail\">' As Detail, "
|
||||
. "'<input type=submit id=\"acc'||m.id||'\" onclick=\"return smoneyProcess('||m.id||')\" name=\"manage\" class=\"btn btn-info btn-sm\" value=\"Process\">' As Process "
|
||||
. "FROM money_transfer m "
|
||||
. "LEFT JOIN members me ON me.id=m.member_id "
|
||||
. "LEFT JOIN sendmoney_recipient sr ON sr.id=m.recipientid "
|
||||
. "LEFT JOIN members_payments mp ON mp.what_sendmoney = m.id "
|
||||
. "LEFT JOIN bank_entity_codes be ON be.code=sr.bank_code WHERE m.id=" . $sendmoney_id;
|
||||
switch ($proc) {
|
||||
case 'PROCESS':
|
||||
$mysql = "SELECT m.id,mp.confirmation, m.added,me.firstname||' '||me.lastname||'<br>'||me.email AS Sender,"
|
||||
. "sr.firstname||' '||sr.lastname||'<br>ACC:'||sr.account_no||'-'||be.name AS recipient, m.initiatingamount*0.01 AS Amount,m.fee*0.01 AS Fee, "
|
||||
. "'<input type=submit id=\"accs'||m.id||'\" onclick=\"return smoneyDetail('||m.id||')\" name=\"manage\" class=\"btn btn-info btn-sm\" value=\"Detail\">' As Detail, "
|
||||
. "'<input type=submit id=\"acc'||m.id||'\" onclick=\"return smoneyProcess('||m.id||')\" name=\"manage\" class=\"btn btn-info btn-sm\" value=\"Process\">' As Process, "
|
||||
. "m.initiatingamount AS raw_amount, m.fee AS raw_fee, sr.bank_code, sr.account_no "
|
||||
. "FROM money_transfer m "
|
||||
. "LEFT JOIN members me ON me.id=m.member_id "
|
||||
. "LEFT JOIN sendmoney_recipient sr ON sr.id=m.recipientid "
|
||||
. "LEFT JOIN members_payments mp ON mp.what_sendmoney = m.id "
|
||||
. "LEFT JOIN bank_entity_codes be ON be.code=sr.bank_code WHERE m.id=" . $sendmoney_id;
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
$row = $query->row_array();
|
||||
$query = $this->db->query($mysql);
|
||||
$row = $query->row_array();
|
||||
|
||||
echo $this->sendmoneyProcessPage($row);
|
||||
echo $this->sendmoneyProcessPage($row);
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case 'DETAIL':
|
||||
case 'DETAIL':
|
||||
|
||||
echo 'detail';
|
||||
echo 'detail';
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case 'TRANSMIT':
|
||||
//echo 'complete 1';
|
||||
// url: "/bkotransaction/smprocess?proc=COMPLETE&sendmoney_id="+link_id+'&tcode='+tcode+'&tref='+tref
|
||||
$data["trans_code"] = $this->input->get('tcode');
|
||||
$data["trans_tref"] = $this->input->get('tref');
|
||||
$data["sendmoney_id"] = $sendmoney_id;
|
||||
$data['action'] = WRENCHBOARD_SMONEY_BKOPROC;
|
||||
$data['action_mode'] = SMONEY_PROCC_INTERSWITCH;
|
||||
$this->load->model('backend_model');
|
||||
$out = array();
|
||||
$this->backend_model->wrenchboard_api($data, $out);
|
||||
echo $out['status'];
|
||||
|
||||
|
||||
|
||||
break;
|
||||
case 'TRANSMIT':
|
||||
//echo 'complete 1';
|
||||
// url: "/bkotransaction/smprocess?proc=COMPLETE&sendmoney_id="+link_id+'&tcode='+tcode+'&tref='+tref
|
||||
$data["trans_code"] = $this->input->get('tcode');
|
||||
$data["trans_tref"] = $this->input->get('tref');
|
||||
$data["sendmoney_id"] = $sendmoney_id;
|
||||
$mysql = "SELECT m.id,mp.confirmation, m.added,me.firstname||' '||me.lastname||'<br>'||me.email AS sender,
|
||||
sr.firstname||' '||sr.lastname||'<br>ACC:'||sr.account_no||'-'||be.name AS recipient,
|
||||
m.initiatingamount*0.01 AS amount, m.fee*0.01 AS fee,
|
||||
m.initiatingamount AS raw_amount, m.fee AS raw_fee, sr.bank_code, sr.account_no
|
||||
FROM money_transfer m
|
||||
LEFT JOIN members me ON me.id=m.member_id
|
||||
LEFT JOIN sendmoney_recipient sr ON sr.id=m.recipientid
|
||||
LEFT JOIN members_payments mp ON mp.what_sendmoney = m.id
|
||||
LEFT JOIN bank_entity_codes be ON be.code=sr.bank_code WHERE m.id=" . $sendmoney_id;
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
$row = $query->row_array();
|
||||
|
||||
echo $this->sendmoneyProcessPage($row, $data);
|
||||
/*
|
||||
$data['action'] = WRENCHBOARD_SMONEY_BKOPROC;
|
||||
$data['action_mode'] = SMONEY_PROCC_INTERSWITCH;
|
||||
$this->load->model('backend_model');
|
||||
$out = array();
|
||||
$this->backend_model->wrenchboard_api($data, $out);
|
||||
echo $out['status'];
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function TransmitSendmoneyProcessPage($out) {
|
||||
|
||||
$myTable = "<form id='sendmoneyProcessPage" . $out['id'] . "' name='sendmoneyProcessPage" . $out['id'] . "'><table class='table table-striped table-hover table-bordered table-condensed'>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Confirmation</b></td><td>" . $out['confirmation'] . "</td></tr>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Trx. Date</b></td><td>" . $out['added'] . "</td></tr>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Sender</b></td><td>" . $out['sender'] . "</td></tr>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Recipient</b></td><td>" . $out['recipient'] . "</td></tr>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Amount</b></td><td>" . $out['amount'] . "</td></tr>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Fee</b></td><td>" . $out['fee'] . "</td></tr>";
|
||||
|
||||
$myTable .="<tr><td style='width:100px;'><b></b></td><td></td></tr>";
|
||||
$myTable .="</table></form> ";
|
||||
$myTable = "<form id='sendmoneyProcessPage" . $out['id'] . "' name='sendmoneyProcessPage" . $out['id'] . "'><table class='table table-striped table-hover table-bordered table-condensed'>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Confirmation</b></td><td>" . $out['confirmation'] . "</td></tr>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Trx. Date</b></td><td>" . $out['added'] . "</td></tr>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Sender</b></td><td>" . $out['sender'] . "</td></tr>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Recipient</b></td><td>" . $out['recipient'] . "</td></tr>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Amount</b></td><td>" . $out['amount'] . "</td></tr>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Fee</b></td><td>" . $out['fee'] . "</td></tr>";
|
||||
|
||||
$myTable .="<tr><td style='width:100px;'><b></b></td><td></td></tr>";
|
||||
$myTable .="</table></form> ";
|
||||
|
||||
return $myTable;
|
||||
}
|
||||
return $myTable;
|
||||
}
|
||||
|
||||
private function sendmoneyProcessPage($out) {
|
||||
private function sendmoneyProcessPage($out, $page=array()) {
|
||||
$data = array(
|
||||
"account_bank" => $out['bank_code'],
|
||||
"account_number" => $out['account_no'],
|
||||
"amount" => $out['raw_amount'],
|
||||
"narration" => $out['sender'],
|
||||
"currency" => "NGN",
|
||||
"reference" => $out['id'],
|
||||
"debit_currency" => "NGN"
|
||||
);
|
||||
$url = "http://localhost:3000/create";
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch,CURLOPT_URL, $url);
|
||||
curl_setopt($ch,CURLOPT_POST, count($data));
|
||||
curl_setopt($ch,CURLOPT_POSTFIELDS, json_encode($data));
|
||||
curl_setopt($ch,CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
|
||||
curl_setopt($ch,CURLOPT_RETURNTRANSFER, TRUE);
|
||||
$result = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$myTable = "<form id='sendmoneyProcessPage" . $out['id'] . "' name='sendmoneyProcessPage" . $out['id'] . "'><table class='table table-striped table-hover table-bordered table-condensed'>";
|
||||
$data = json_decode($result, true);
|
||||
// Error
|
||||
// {"status":"failure","message":"Invalid response","details":"Request failed with status code 400","code":400,"data":{"status":"error","code":"UNAUTHORIZED_ACCESS","message":"Unauthorized access. Compliance approval required to use this feature"}}
|
||||
// Success
|
||||
// ???
|
||||
$page["message"] = "";
|
||||
if ($data == null || $data == "" || (array_key_exists("status",$data) && $data["status"]=="failure")) {
|
||||
if ($data == null || $data == "") {
|
||||
// Invalid response, not clear what is going on (non-JSON response from the payment API)
|
||||
$page["message"] = "Invalid payment API respose: ".htmlentities($result);
|
||||
} else if (array_key_exists("data",$data) && array_key_exists("message",$data["data"])) {
|
||||
// Payment processor message
|
||||
$page["message"] = $data["data"]["message"];
|
||||
} else if (array_key_exists("message",$data)) {
|
||||
// Payment API message
|
||||
$page["message"] = $data["message"];
|
||||
} else {
|
||||
// Not clear what is going on (failure with no messages?)
|
||||
$page["message"] = "Invalid payment API respose: ".htmlentities($result);
|
||||
}
|
||||
} else {
|
||||
// TODO: success
|
||||
}
|
||||
// $page['confirmation']
|
||||
// $page['trans_code']
|
||||
// $data['trans_tref']
|
||||
|
||||
$myTable = "<form id='sendmoneyProcessPage" . $out['id'] . "' name='sendmoneyProcessPage" . $out['id'] . "'>";
|
||||
$myTable .="<span style='font-weight:bold;color:red'>".$page["message"]."</span>";
|
||||
$myTable .="<table class='table table-striped table-hover table-bordered table-condensed'>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Confirmation</b></td><td>" . $out['confirmation'] . "</td></tr>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Trx. Date</b></td><td>" . $out['added'] . "</td></tr>";
|
||||
$myTable .="<tr><td style='width:100px;'><b>Sender</b></td><td>" . $out['sender'] . "</td></tr>";
|
||||
|
||||
@@ -87,82 +87,68 @@ class Dash extends Users_Controller {
|
||||
$this->table->set_heading(array('data' => 'Job', 'style' => 'width:180px'), 'Title/Description', array('data' => '', 'style' => 'width:100px; cellpadding:0px;'));
|
||||
|
||||
$data['job_table'] = $this->table->generate($query);
|
||||
|
||||
$data['job_table_result'] = $query->result(); // used in new impl.
|
||||
|
||||
$x = $this->dashTaskMessage();
|
||||
$data['job_message_table'] = $x['job_message_table'];
|
||||
$data['job_message_table_result'] = $x['job_message_table_result'];
|
||||
$data['message_found'] = $x['message_found'];
|
||||
/// End table data ===========================
|
||||
|
||||
|
||||
|
||||
/*
|
||||
$this->load->library('table');
|
||||
$this->table->set_template($this->template);
|
||||
//$this->table->set_heading('Job', 'Client', 'Terms', 'Description', 'Manage', 'Status');
|
||||
$mysql = 'SELECT jo.added::date,jo.member_id,j.title,'
|
||||
. 'CASE WHEN jo.status = 1 THEN \'Pending\' ELSE \'Other\' END AS status'
|
||||
. 'FROM members_jobs_offer jo LEFT JOIN members_jobs j ON j.id = jo.job_id LIMIT 5';
|
||||
// $sqb =" ,'<button type=\"button\" class=\"btn btn-primary btn-xs\">View</button>' As View ";
|
||||
$jbx = "''jobs/viewjob''";
|
||||
$mysql = "SELECT jo.added::date,j.title,"
|
||||
. 'CASE WHEN jo.status = 1 THEN \'Pending\' ELSE \'Other\' END AS status,'
|
||||
. "'<input type=submit onclick=\"return post_nav_find_action($jbx,'''||jo.offer_code||''')\" name=\"manage\" class=\"btn btn-primary btn-xs\" value=\"View\">' AS View "
|
||||
. "FROM members_jobs_offer jo LEFT JOIN members_jobs j ON j.id = jo.job_id "
|
||||
. "WHERE jo.expire > now() AND jo.status = 1 "
|
||||
. "AND jo.client_id = " . $_SESSION['member_id'] . "LIMIT 4";
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
|
||||
$num = $query->num_rows();
|
||||
|
||||
$data["dash_title"] = "Pending Offer(s)";
|
||||
if ($num > 0) {
|
||||
$this->table->set_heading('Added', 'Title', 'Status', '');
|
||||
$data['offer_dash'] = $this->table->generate($query);
|
||||
} else {
|
||||
$data["offer_dash"] = "<div class=\"thumb\"><img src='assets/images/notask.png' alt=\"Active Projects\"></div>";
|
||||
}
|
||||
*/
|
||||
$acp = array();
|
||||
$acp = $this->activeProjects();
|
||||
$data['job_table'] = $acp['job_table'];
|
||||
$data['job_table_result'] = $acp['job_table_result'];
|
||||
|
||||
$ya = array();
|
||||
$ya = $this->dash_title();
|
||||
$data["dash_title"] = $ya["dash_title"];
|
||||
$data["offer_dash"] = $ya["offer_dash"];
|
||||
$data["offer_dash_result"] = $ya["offer_dash_result"];
|
||||
$data["offer_found"] = $ya["offer_found"];
|
||||
|
||||
$_SESSION['secure_data'] = $data; // all data needed for secure page
|
||||
// print_r($_SESSION);
|
||||
//var_dump( $_SESSION);
|
||||
//exit;
|
||||
$data['page_title'] ="Dashboard";
|
||||
$this->renderSecurePage('users/view_dash', $data);
|
||||
|
||||
$this->load->view('users/view_header_user', $data);
|
||||
$this->load->view('users/view_dash', $data);
|
||||
$this->load->view('users/view_footer_user', $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function activeProjects(){
|
||||
|
||||
|
||||
$jbx = "''/proj/thisjob''";
|
||||
$mysql = "SELECT '<b>ID:</b><a href=\"#\" onclick=\"showJobModal('''||mc.contract||''');\" >'||mc.contract||'</a><br><b>Timeline:</b>'||mc.timeline_days||' day(s)<br><b>Price:</b>'||mc.price*0.01 AS Project,"
|
||||
. " '<b>Title: </b>'||mc.title||'<br><b>Description: </b>'||mc.description AS description,'\/proj\/thisjob' AS qpath, mc.id AS offer_id,"
|
||||
. " (CASE WHEN mc.status=4 THEN '<input type=submit onclick=\"return post_nav_find_action($jbx, '||mc.id||')\" name=\"manage\" class=\"btn btn-info btn-xs btn-block\" value=\"Review\">' "
|
||||
. " WHEN mc.status = 1 AND mc.delivery_date > now() THEN '<input type=submit onclick=\"return post_nav_find_action($jbx, '||mc.id||')\" name=\"manage\" class=\"btn btn-success btn-xs btn-block\" value=\"View\">' "
|
||||
. " WHEN mc.status = 1 AND mc.delivery_date <now() THEN '<span class=\"label label-flat border-danger text-danger-600\">PastDue</span>' "
|
||||
. " ELSE '<input type=submit onclick=\"return post_nav_find_action($jbx, '||mc.id||')\" name=\"manage\" class=\"btn btn-info btn-xs btn-block\" value=\"View\">' END) AS manage "
|
||||
. " FROM members_jobs_contract mc LEFT JOIN members m ON m.id=mc.client_id "
|
||||
. " WHERE mc.member_id = " . $_SESSION['member_id'] . " AND mc.status IN (1,2,4) AND mc.delivery_date > now() "
|
||||
. " OR mc.client_id =" . $_SESSION['member_id'] . " AND mc.status IN (1,2,4) AND mc.delivery_date > now() LIMIT 4";
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
|
||||
|
||||
$this->load->library('table');
|
||||
$this->table->set_template($this->template);
|
||||
$this->table->set_heading(array('data' => 'Job', 'style' => 'width:180px'), 'Title/Description', array('data' => '', 'style' => 'width:100px; cellpadding:0px;'));
|
||||
|
||||
$data['job_table'] = $this->table->generate($query);
|
||||
$data['job_table_result'] = $query->result(); // used in new impl.
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
private function dashTaskMessage() {
|
||||
$data = array();
|
||||
/*
|
||||
wrenchboard=> select s.created,j.contract,j.title,j.id,j.status,j.delivery_date,substring(s.message,0,100) FROM members_jobs_contract j RIGHT JOIN jobs_contract_message s ON s.contract=j.contract WHERE j.member_id=3 or j.client_id = 3 AND j.status IN (1,4);
|
||||
created | contract | title | id | status | delivery_date | substring
|
||||
----------------------------+------------+-----------------------------------------------+----+--------+----------------------------+-----------------------------------------------------------------------------------------------------
|
||||
2017-05-18 11:53:20.569399 | 7BW9B9R8BB | five thousand naira | 13 | 1 | 2017-08-02 14:19:38.711257 | This is a test of ajax send message
|
||||
2017-05-18 12:03:30.685328 | 7B27RRBRB7 | 595Job Title Job Title Job Title Job Title932 | 15 | 4 | 2017-05-10 19:23:26.115394 | dldldldldldl
|
||||
2017-05-18 12:03:44.137005 | 7B27RRBRB7 | 595Job Title Job Title Job Title Job Title932 | 15 | 4 | 2017-05-10 19:23:26.115394 | This is an empty list test
|
||||
2017-05-18 12:04:00.228586 | 7B27RRBRB7 | 595Job Title Job Title Job Title Job Title932 | 15 | 4 | 2017-05-10 19:23:26.115394 | List should be populated now
|
||||
2017-05-18 20:49:12.996077 | 7BW9B9R8BB | five thousand naira | 13 | 1 | 2017-08-02 14:19:38.711257 | About PayQuic\r +
|
||||
| | | | | | PayQuic is global payments and airtime top-up company. Open for business 24/7, 365 d
|
||||
2017-06-12 10:28:32.720786 | 601BBWRW48 | 595Job Title Job Title Job Title Job Title932 | 10 | 1 | 2017-08-09 16:08:43.503739 | <table><tbody><tr><td><div><span><br>can you share your controller method and did you tried <c
|
||||
2017-06-12 10:28:41.932836 | 601BBWRW48 | 595Job Title Job Title Job Title Job Title932 | 10 | 1 | 2017-08-09 16:08:43.503739 | <table><tbody><tr><td><div><span><br>can you share your controller method and did you tried <c
|
||||
|
||||
*/
|
||||
$jbx = "''/proj/thisjob''";
|
||||
|
||||
$mysql = " SELECT s.created,j.contract,j.title,j.id,j.status,j.delivery_date,substring(s.message,0,100),"
|
||||
. " '<input type=submit onclick=\"return post_nav_find_action($jbx, '||j.id||')\" name=\"manage\" class=\"btn btn-success btn-xs btn-block\" value=\"View\">' "
|
||||
. " FROM members_jobs_contract j "
|
||||
. " RIGHT JOIN jobs_contract_message s ON s.contract=j.contract "
|
||||
. " WHERE j.member_id=" . $_SESSION['member_id'] . " OR j.client_id = " . $_SESSION['member_id'] . " AND j.status IN (1,4)";
|
||||
|
||||
$mysql = " SELECT s.created::date ||'<br>'||j.contract AS date_contract,'<b>Title:</b>'||j.title||'<br>'||substring(s.message,0,90) as title_message,"
|
||||
$mysql = " SELECT s.created::date ||'<br>'||j.contract AS date_contract,j.title AS title,substring(s.message,0,90) as title_message,'\/proj\/thisjob' AS qpath,j.id AS offer_code,"
|
||||
. " '<input type=submit onclick=\"return post_nav_find_action($jbx, '||j.id||')\" name=\"manage\" class=\"btn btn-success btn-xs btn-block\" value=\"View\">' "
|
||||
. " FROM members_jobs_contract j "
|
||||
. " RIGHT JOIN jobs_contract_message s ON s.contract=j.contract "
|
||||
@@ -170,13 +156,13 @@ class Dash extends Users_Controller {
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
|
||||
|
||||
$this->load->library('table');
|
||||
$this->table->set_template($this->template);
|
||||
$this->table->set_heading(array('data' => 'Date', 'style' => 'width:180px'), 'Title/Message', array('data' => '', 'style' => 'width:100px; cellpadding:0px;'));
|
||||
|
||||
$data['job_message_table'] = $this->table->generate($query);
|
||||
|
||||
$data['job_message_table_result'] = $query->result(); // used in new impl.
|
||||
$data['message_found'] = true;
|
||||
return $data;
|
||||
}
|
||||
|
||||
@@ -185,21 +171,19 @@ class Dash extends Users_Controller {
|
||||
$offer_found = false;
|
||||
|
||||
$data = array();
|
||||
$data['offer_dash'] = '';
|
||||
$data['offer_dash'] = $data['offer_dash_result'] ='';
|
||||
$this->load->library('table');
|
||||
$this->table->set_template($this->template);
|
||||
|
||||
$jbx = "''/jobs/viewjob''";
|
||||
$mysql = "SELECT jo.added::date,j.title,"
|
||||
. "'<input type=submit onclick=\"return post_nav_find_action($jbx,'''||jo.offer_code||''')\" name=\"manage\" class=\"btn btn-primary btn-xs\" value=\"View\">' AS View "
|
||||
$mysql = "SELECT jo.added::date AS pdate,j.title,(CASE WHEN jo.public_view > 0 THEN '-Public View' ELSE jo.email END) AS tRec,'\/jobs\/viewjob' AS qpath,"
|
||||
. 'CASE WHEN jo.status = 1 AND jo.public_view =0 THEN \'Pending\' WHEN jo.status = 1 AND jo.public_view >0 THEN \'Active\' ELSE \'Other\' END AS status,'
|
||||
. "'<input type=submit onclick=\"return post_nav_find_action($jbx,'''||jo.offer_code||''')\" name=\"manage\" class=\"btn btn-primary btn-xs\" value=\"View\">' AS View ,jo.offer_code AS offer_code "
|
||||
. "FROM members_jobs_offer jo LEFT JOIN members_jobs j ON j.id = jo.job_id "
|
||||
. "WHERE jo.expire > now() AND jo.status = 1 "
|
||||
. "AND jo.client_id = " . $_SESSION['member_id'] . " LIMIT 4";
|
||||
// . 'CASE WHEN jo.status = 1 THEN \'Pending\' ELSE \'Other\' END AS status,'
|
||||
$query = $this->db->query($mysql);
|
||||
|
||||
$num = $query->num_rows();
|
||||
|
||||
$data["dash_title"] = "Pending Offer(s)";
|
||||
if ($num > 0) {
|
||||
|
||||
@@ -209,6 +193,7 @@ class Dash extends Users_Controller {
|
||||
|
||||
$this->table->set_heading(array('data' => 'Added', 'style' => 'width:80px'), 'Title', array('data' => '', 'style' => 'width:80px'));
|
||||
$data['offer_dash'] = $this->table->generate($query);
|
||||
$data['offer_dash_result'] = $query->result();
|
||||
$offer_found = true;
|
||||
} else {
|
||||
$data["offer_dash"] = "<div class=\"thumb\"><img src='assets/images/notask.png' alt=\"Active Projects\"></div>";
|
||||
@@ -218,15 +203,14 @@ class Dash extends Users_Controller {
|
||||
if ($offer_found == false) {
|
||||
$data["dash_title"] = "<a href='/jobs/pendingoffer'>My Pending Offer(s)</a>";
|
||||
$jbx = "''/jobs/viewmyjob''";
|
||||
$mysql = "SELECT jo.added::date||'<br>'||jo.expire::date,j.title||'<br><b>To :</b>'||(CASE WHEN jo.public_view > 0 THEN '-Public View' ELSE jo.email END) AS tRec,"
|
||||
$mysql = "SELECT jo.added::date||'<br>'||jo.expire::date AS pdate,j.title, (CASE WHEN jo.public_view > 0 THEN '-Public View' ELSE jo.email END) AS tRec,'\/jobs\/viewmyjob' AS qpath,"
|
||||
. 'CASE WHEN jo.status = 1 AND jo.public_view =0 THEN \'Pending\' WHEN jo.status = 1 AND jo.public_view >0 THEN \'Active\' ELSE \'Other\' END AS status,'
|
||||
. "'<input type=submit onclick=\"return post_nav_find_action($jbx,'''||jo.offer_code||''')\" name=\"manage\" class=\"btn btn-primary btn-xs\" value=\"View\">' AS View "
|
||||
. "'<input type=submit onclick=\"return post_nav_find_action($jbx,'''||jo.offer_code||''')\" name=\"manage\" class=\"btn btn-primary btn-xs\" value=\"View\">' AS View,jo.offer_code AS offer_code "
|
||||
. "FROM members_jobs_offer jo LEFT JOIN members_jobs j ON j.id = jo.job_id "
|
||||
. "WHERE jo.expire > now() AND jo.status = 1 "
|
||||
. "AND jo.member_id = " . $_SESSION['member_id'] . " ORDER BY jo.id DESC LIMIT 4";
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
|
||||
$num = $query->num_rows();
|
||||
|
||||
if ($num > 0) {
|
||||
@@ -236,10 +220,12 @@ class Dash extends Users_Controller {
|
||||
|
||||
$this->table->set_heading(array('data' => 'Added/Expire', 'style' => 'width:120px'), 'Title/Recipient', array('data' => 'Status', 'style' => 'width:100px'), array('data' => '', 'style' => 'width:100px'));
|
||||
$data['offer_dash'] = $this->table->generate($query);
|
||||
$data['offer_dash_result'] = $query->result();
|
||||
$offer_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
$data["offer_found"] = $offer_found;
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,57 @@
|
||||
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
//Include Hybridauth autoloader
|
||||
require APPPATH . '/third_party/hybridauth/autoload.php';
|
||||
|
||||
//Import Hybridauth's namespace
|
||||
use Hybridauth\Hybridauth;
|
||||
|
||||
class Home extends WRB_Controller {
|
||||
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
//Load URL helper
|
||||
$this->load->helper('url');
|
||||
|
||||
//Load session library
|
||||
$this->load->library('session');
|
||||
}
|
||||
|
||||
//Displays social login links
|
||||
public function index() {
|
||||
|
||||
$this->home1('');
|
||||
//Instantiate Hybridauth's classes
|
||||
$hybrid = new Hybridauth($this->getHybridConfig());
|
||||
|
||||
//Get enabled providers array
|
||||
$providers = $hybrid->getProviders();
|
||||
|
||||
$login_links = "";
|
||||
|
||||
$provider_icons = array(
|
||||
'Apple' => '/site3/assets/media/svg/brand-logos/apple-black.svg',
|
||||
'Facebook' => '/site3/assets/media/svg/brand-logos/facebook-4.svg',
|
||||
'Google' => '/site3/assets/media/svg/brand-logos/google-icon.svg'
|
||||
);
|
||||
|
||||
//List a link to login
|
||||
foreach ($providers as $provider)
|
||||
{
|
||||
$href = sprintf(base_url('%s/auth/%s/') , strtolower($this->router->fetch_class()) , $provider);
|
||||
$login_links .= '<a href="' . $href . '" class="btn btn-flex flex-center btn-light btn-lg w-100 mb-5">';
|
||||
if (array_key_exists($provider, $provider_icons)) {
|
||||
$login_links .= '<img alt="Logo" src="' . $provider_icons[$provider] . '" class="h-20px me-3">';
|
||||
}
|
||||
$login_links .= 'Continue with ' . $provider . '</a>';
|
||||
}
|
||||
|
||||
$data['login_links'] =''; // $login_links;
|
||||
|
||||
//$this->home1('');
|
||||
$this->load->view('site3/external/view_home', $data);
|
||||
}
|
||||
|
||||
public function about() {
|
||||
@@ -14,4 +60,118 @@ class Home extends WRB_Controller {
|
||||
$this->home2('home2/about');
|
||||
}
|
||||
|
||||
//Processes social login
|
||||
function auth($provider = NULL)
|
||||
{
|
||||
$service = NULL;
|
||||
|
||||
try
|
||||
{
|
||||
//Instantiate Hybridauth's classes
|
||||
$hybrid = new Hybridauth($this->getHybridConfig());
|
||||
|
||||
//Check if given provider is enabled
|
||||
if ((isset($provider)) && in_array($provider, $hybrid->getProviders()))
|
||||
{
|
||||
$this->session->set_userdata('provider', $provider);
|
||||
}
|
||||
|
||||
//Update variable with the valid provider
|
||||
$provider = $this->session->userdata('provider');
|
||||
|
||||
if ($provider)
|
||||
{
|
||||
$service = $hybrid->authenticate($provider);
|
||||
if ($service->isConnected())
|
||||
{
|
||||
//Get user profile
|
||||
$profile = $service->getUserProfile();
|
||||
|
||||
//Get user contacts
|
||||
$contacts = $service->getUserContacts();
|
||||
|
||||
/*
|
||||
Disconnect the service else HA would reuse stored session data
|
||||
rather making a fresh request in case the user has denied permissions
|
||||
in the previous authorization request
|
||||
*/
|
||||
$service->disconnect();
|
||||
|
||||
$this->session->unset_userdata('provider');
|
||||
|
||||
//Display the profile data
|
||||
echo 'Name: ' . $profile->displayName;
|
||||
print_r($profile);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set_flashdata('showmsg', array('msg' => 'Sorry! We couldn\'t authenticate your identity.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
if (isset($service) && $service->isConnected())
|
||||
$service->disconnect();
|
||||
|
||||
$error = 'Sorry! We couldn\'t authenticate you.';
|
||||
$this->session->set_flashdata('showmsg', array('msg' => $error));
|
||||
$error .= '\nError Code: ' . $e->getCode();
|
||||
$error .= '\nError Message: ' . $e->getMessage();
|
||||
|
||||
log_message('error', $error);
|
||||
}
|
||||
|
||||
//redirect();
|
||||
}
|
||||
|
||||
//Hybridauth configuration
|
||||
private function getHybridConfig()
|
||||
{
|
||||
$config = array(
|
||||
|
||||
'callback' => site_url('social/auth/') ,
|
||||
|
||||
'providers' => array(
|
||||
'Google' => array(
|
||||
'enabled' => true,
|
||||
'keys' => array(
|
||||
'id' => 'YOUR_CLIENT_ID',
|
||||
'secret' => 'YOUR_CLIENT_SECRET'
|
||||
) ,
|
||||
'scope' => 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile'
|
||||
) ,
|
||||
|
||||
'Facebook' => array(
|
||||
'enabled' => true,
|
||||
'keys' => array(
|
||||
'id' => (ENVIRONMENT == 'development') ? '390204307987009' : '390204307987009',
|
||||
'secret' => (ENVIRONMENT == 'development') ? '19f778e312f2ab96d147bacb612910c2' : '19f778e312f2ab96d147bacb612910c2'
|
||||
) ,
|
||||
'scope' => 'email, public_profile'
|
||||
) ,
|
||||
|
||||
'Apple' => array(
|
||||
"enabled" => true,
|
||||
"keys" => [
|
||||
"id" => "Your Apple ID",
|
||||
"team_id" => "Your Apple team id",
|
||||
"key_id" => "Your Apple key id",
|
||||
"key_content" => "Your Apple key (content including BEGIN and END lines)",
|
||||
"key_file" => "Full path to your Apple key file (alternative to key_content)"
|
||||
],
|
||||
"scope" => "name email",
|
||||
"verifyTokenSignature" => true
|
||||
)
|
||||
) ,
|
||||
|
||||
'hybrid_debug' => array(
|
||||
'debug_mode' => 'info', /* none, debug, info, error */
|
||||
'debug_file' => APPPATH . '/logs/log-' . date('Y-m-d') . '.php'
|
||||
)
|
||||
);
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -500,8 +500,8 @@ class Jobs extends Users_Controller {
|
||||
. ' AND expire> now() AND public_view > 0';
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
|
||||
$num = $query->num_rows();
|
||||
$data['market_table_result'] = $query->result(); // used in new impl.
|
||||
|
||||
if ($num > 0) {
|
||||
$myTable = "<table class='table table-striped table-hover table-bordered table-condensed'>";
|
||||
@@ -520,9 +520,13 @@ class Jobs extends Users_Controller {
|
||||
|
||||
$_SESSION['secure_data'] = $data; // all data needed for secure page
|
||||
$data['page_title'] = "Available Jobs & Tasks";
|
||||
$this->load->view('users/view_header_user', $data);
|
||||
/* $this->load->view('users/view_header_user', $data);
|
||||
$this->load->view('jobs/view_market', $data);
|
||||
$this->load->view('users/view_footer_user', $data);
|
||||
*/
|
||||
// var_dump( $data['market_table_result']);
|
||||
// exit;
|
||||
$this->renderSecurePage('jobs/view_market', $data);
|
||||
}
|
||||
|
||||
private function makeMarketTableRow($row) {
|
||||
@@ -606,9 +610,9 @@ echo $this->getMarketInterestMessage( $data['offer_code'], $out['client_id'] )
|
||||
|
||||
if ($num > 0) {
|
||||
$row = $query->row_array();
|
||||
$myTable = "<table class='table table-sm table-hover table-bordered table-condensed' style=' background-color: #ebf1e8;'>";
|
||||
$myTable = " <div class='card card-xl-stretch mb-5 mb-xl-8'>";
|
||||
$myTable .= $this->makeMarketDetailTableRow($row);
|
||||
$myTable .="</table>";
|
||||
$myTable .="</div>";
|
||||
}
|
||||
|
||||
echo $myTable;
|
||||
@@ -625,19 +629,19 @@ echo $this->getMarketInterestMessage( $data['offer_code'], $out['client_id'] )
|
||||
|
||||
|
||||
|
||||
return "<tr><td colspan='2' ><b>" . $row['offer_code'] . "</b> Timeline:" . $row['timeline_days'] . " day(s) - <b>Budget: </b> " . $row['price'] * 0.01 . " Naira</td></tr>"
|
||||
. "<tr><td style='width:100px;'><b>Title</b></td><td>" . $row['title'] . "</td></tr>"
|
||||
. "<tr><td><b>Description</b></td><td>" . $row['description'] . "</td></tr>"
|
||||
. "<tr><td><b>Detail</b></td><td>" . $row['job_description'] . "</td></tr>"
|
||||
. "<tr><td colspan='2' >Interests : <b>" . $data['interest'] . "</b> Expire:<b> " . $row['expire']."</b> </td></tr>"
|
||||
. "<tr><td><b></b></td><td style='text-align:right;'><input type=submit id='submit_interest_" . $row['offer_code'] . "' name=\"mview\" onclick=\"return SInterest('" . $row['offer_code'] . "');\" class=\"btn btn-success btn-xs\" value=\"Send Interest Request
|
||||
\"></td></tr>"
|
||||
. "<tr><td colspan='2'>If you have any questions about this task :"
|
||||
. "<div id='msg_result_" . $row['offer_code'] . "'><form name=\"job_message\"><table class='table table-striped table-hover table-bordered table-condensed'>"
|
||||
. "<tr><td><textarea name='yourmessage' cols=\"5\" rows=\"3\" class=\"textarea form-control\" class=\"btn btn-success btn-xs\" placeholder=\"Enter message here ...\"></textarea></td></tr>"
|
||||
. "<tr><td style='text-align:right;'><button id='submit_yourmessage_" . $row['offer_code'] . "' onclick=\"return OMessage('" . $row['offer_code'] . "');\" class=\"btn btn-info btn-xs\">Send Message</button></td></tr></table></form></div>"
|
||||
. "</td></tr>"
|
||||
. " ";
|
||||
return "<div class='card-body'><table class='table table-sm table-hover table-bordered table-condensed' style='background-color: #ffffff;'><tr><td colspan='2' ><b>" . $row['offer_code'] . "</b> Timeline:" . $row['timeline_days'] . " day(s) - <b>Budget: </b> " . $row['price'] * 0.01 . " Naira</td></tr>"
|
||||
. "<tr><td style='width:100px;'><b>Title</b></td><td>" . $row['title'] . "</td></tr>"
|
||||
. "<tr><td><b>Description</b></td><td>" . $row['description'] . "</td></tr>"
|
||||
. "<tr><td><b>Detail</b></td><td>" . $row['job_description'] . "</td></tr>"
|
||||
. "<tr><td colspan='2' >Interests : <b>" . $data['interest'] . "</b> Expire:<b> " . $row['expire']."</b> </td></tr>"
|
||||
. "<tr><td><b></b></td><td style='text-align:right;'><input type=submit id='submit_interest_" . $row['offer_code'] . "' name=\"mview\" onclick=\"return SInterest('" . $row['offer_code'] . "');\" class=\"btn btn-success btn-xs\" value=\"Send Interest Request
|
||||
\"></td></tr>"
|
||||
. "<tr><td colspan='2'>If you have any questions about this task :"
|
||||
. "<div id='msg_result_" . $row['offer_code'] . "'><form name=\"job_message\"><table class='table table-striped table-hover table-bordered table-condensed'>"
|
||||
. "<tr><td><textarea name='yourmessage' cols=\"5\" rows=\"3\" class=\"textarea form-control\" class=\"btn btn-success btn-xs\" placeholder=\"Enter message here ...\"></textarea></td></tr>"
|
||||
. "<tr><td style='text-align:right;'><button id='submit_yourmessage_" . $row['offer_code'] . "' onclick=\"return OMessage('" . $row['offer_code'] . "');\" class=\"btn btn-info btn-xs\">Send Message</button></td></tr></table></form></div>"
|
||||
. "</td></tr>"
|
||||
. " </table></div>";
|
||||
}
|
||||
|
||||
public function viewmyjob() {
|
||||
@@ -667,9 +671,11 @@ echo $this->getMarketInterestMessage( $data['offer_code'], $out['client_id'] )
|
||||
|
||||
$data['job_link'] = 'https://'.$_SERVER['HTTP_HOST']."/plb/viewjob/".$out['offer_code'];
|
||||
|
||||
$this->load->view('users/view_header_user', $data);
|
||||
/* $this->load->view('users/view_header_user', $data);
|
||||
$this->load->view('jobs/view_viewmyjoboffer', $data);
|
||||
$this->load->view('users/view_footer_user', $data);
|
||||
$this->load->view('users/view_footer_user', $data);*/
|
||||
|
||||
$this->RenderUserPage('jobs/view_viewmyjoboffer', $data);
|
||||
} else {
|
||||
redirect('dash'); // go back to dash if not valid
|
||||
}
|
||||
|
||||
@@ -10,6 +10,26 @@ class Login extends WRB_Controller {
|
||||
$this->load->library(array('session', 'lib_login'));
|
||||
}
|
||||
|
||||
private function excudedEmails(){
|
||||
$ecData= [
|
||||
'ses66181+1@gmail.com',
|
||||
'tokslawus@gmail.com',
|
||||
'ses6681+3@gmail.com',
|
||||
'ameye@chiefsoft.com',
|
||||
'ses66181@gmail.com',
|
||||
];
|
||||
|
||||
if (in_array($_SESSION['username'], $ecData))
|
||||
{
|
||||
$_SESSION['allow_payment_features'] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION['allow_payment_features'] = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$data["login_message"] = "";
|
||||
$this->load->library('form_validation');
|
||||
@@ -59,6 +79,7 @@ class Login extends WRB_Controller {
|
||||
$this->logUser('Account login');
|
||||
$this->refreshAccountDetail($_SESSION['member_id']);
|
||||
$this->getSessionArray();
|
||||
$this->excudedEmails();
|
||||
redirect('dash');
|
||||
}
|
||||
} else {
|
||||
@@ -127,6 +148,9 @@ class Login extends WRB_Controller {
|
||||
$this->logUser('Account login');
|
||||
$this->refreshAccountDetail($_SESSION['member_id']);
|
||||
$this->getSessionArray();
|
||||
|
||||
$this->excudedEmails();
|
||||
|
||||
redirect('dash');
|
||||
}
|
||||
}
|
||||
@@ -138,26 +162,31 @@ class Login extends WRB_Controller {
|
||||
|
||||
if( strlen( $data["login_message"]) > 0 )
|
||||
{
|
||||
$data["login_message"] = "<div class=\"text-left\"><div class=\"alert alert-danger no-border\">" . $data["login_message"] . "</div></div>";
|
||||
$data["login_message"] = "<div class=\"text-left\"><div class=\"alert alert-danger no-border\">" . $data["login_message"] . "-<a href=\"/password_recovery\">Forgot Password ?</a></div></div>";
|
||||
}
|
||||
$data['title'] = "Login"; // Capitalize the first letter
|
||||
$data['page_title'] = "Login WrenchBoard";
|
||||
//$this->load->view('templates/header_boxed', $data);
|
||||
$this->load->view('users/view_login', $data);
|
||||
$this->load->view('users/view_external_footer');
|
||||
//----- long out $this->load->view('templates/header_boxed', $data);
|
||||
//$this->load->view('users/view_login', $data);
|
||||
//$this->load->view('users/view_external_footer');
|
||||
$this->load->view('site3/external/view_home',$data);
|
||||
}
|
||||
|
||||
|
||||
//<a href="/password_recovery">Forgot Password ?</a>
|
||||
|
||||
public function refreshAccountDetail($member_id) {
|
||||
$this->load->model('account_model');
|
||||
$qr = $this->account_model->loadAccountData($member_id);
|
||||
// print_r($qr);
|
||||
$_SESSION['current_balance'] = $qr[0]['balance'];
|
||||
$this->load->model('account_model');
|
||||
|
||||
$_SESSION['current_balance'] = $this->account_model->getUserWallet($member_id,$currency='NAIRA'); // $out['current_balance'];
|
||||
// $_SESSION['current_balance'] = $qr[0]['balance'];
|
||||
$_SESSION['active_task'] = $this->account_model->loadActiveTaskCount($member_id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function logout() {
|
||||
$this->lib_login->destroy_session();
|
||||
|
||||
@@ -26,7 +26,25 @@ class Member extends Users_Controller {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Schedule account delete in the backend
|
||||
*/
|
||||
public function deleteacc(){
|
||||
// echo "Please log out of your account, and you will not be able to log in anymore. ";
|
||||
$data = $this->getSessionArray();
|
||||
$in = [];
|
||||
|
||||
$in['member_id'] = $_SESSION['member_id'];
|
||||
$in['reason'] = "Not accepted in this version";
|
||||
$in['action'] = WRENCHBOARD_USER_DELETEACC;
|
||||
if ($this->wrenchboard_api($in, $outx) == PHP_API_OK) {
|
||||
$data['delete_message'] = "<div class=\"text-left\"><div class=\"alert alert-info no-border\">Your Account and Information Deleted.</div></div>";
|
||||
redirect('/logout');
|
||||
} else {
|
||||
$data['delete_message'] = "<div class=\"text-left\"><div class=\"alert alert-danger no-border\">Unable to complete account delete at this time. </div></div>";
|
||||
}
|
||||
echo $data['delete_message'];
|
||||
}
|
||||
|
||||
public function addreccipient() {
|
||||
|
||||
@@ -250,9 +268,12 @@ class Member extends Users_Controller {
|
||||
//stdClass Object ( [id] => 146 [code] => NG [country] => Nigeria [phone_code] => 234 [allow] => 2017-01-08 10:30:42.259079-05 [status] => 1 [created] => 2017-01-08 10:30:15.087696 [updated] => 2017-01-08 10:30:15.087696 )
|
||||
|
||||
|
||||
$this->load->view('users/view_header_user', $data);
|
||||
/* $this->load->view('users/view_header_user', $data);
|
||||
$this->load->view('users/view_profile', $data);
|
||||
$this->load->view('users/view_footer_user', $data);
|
||||
$this->load->view('users/view_footer_user', $data);*/
|
||||
|
||||
$this->RenderUserPage('users/view_profile', $data);
|
||||
|
||||
}
|
||||
|
||||
public function picture() {
|
||||
@@ -438,9 +459,12 @@ class Member extends Users_Controller {
|
||||
|
||||
$data['galery_list'] = $this->getGaleryList($_SESSION['member_id']);
|
||||
|
||||
$this->load->view('users/view_header_user', $data);
|
||||
/* $this->load->view('users/view_header_user', $data);
|
||||
$this->load->view('users/view_yourpage', $data);
|
||||
$this->load->view('users/view_footer_user', $data);
|
||||
*/
|
||||
$data['page_title'] ="My Page";
|
||||
$this->renderSecurePage('users/view_yourpage', $data);
|
||||
}
|
||||
|
||||
|
||||
@@ -583,6 +607,25 @@ class Member extends Users_Controller {
|
||||
|
||||
public function addfund() {
|
||||
$data = $this->getSessionArray();
|
||||
|
||||
|
||||
$this->load->library('table');
|
||||
$this->table->set_template($this->template);
|
||||
$mysql = "SELECT m.added::date AS date,m.terminatingamount*0.01 AS amount,m.fee*0.01 as fee, "
|
||||
. "r.firstname||' '||r.lastname||'<br><b>Acc:</b>'||r.account_no||'-'||b.name AS Recitient,mp.confirmation,"
|
||||
. "CASE WHEN m.status=1 THEN 'Pending' WHEN m.status=3 THEN 'Cancelled' WHEN m.status=5 THEN 'Completed' ELSE '' END AS Status "
|
||||
. "FROM money_transfer m "
|
||||
. "LEFT JOIN sendmoney_recipient r ON r.id = m.recipientid "
|
||||
. "LEFT JOIN bank_entity_codes b ON b.code = r.bank_code "
|
||||
. "LEFT JOIN members_payments mp ON mp.what_sendmoney = m.id "
|
||||
. "WHERE m.member_id =" . $_SESSION['member_id'] . " AND mp.confirmation IS NOT NULL ORDER BY m.id DESC LIMIT 4";
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
$this->table->set_heading('Date', 'Amount','Fee','Recipient','Confirmation', 'Status');
|
||||
$data['sendmoney_table'] = $this->table->generate($query);
|
||||
$data['sendmoney_table_result'] = $query->result();
|
||||
|
||||
|
||||
$data['page_key'] = 'WRB_FUND_ACCOUNT';
|
||||
$data['txt_detail'] = $this->readFixedText($data['page_key']);
|
||||
$data['txt_detail'] = str_replace("[how-it-worked-image-1]", "<img src='/assets/images/howitworks/howitworks-1.jpg' alt=''>", $data['txt_detail']);
|
||||
@@ -632,6 +675,27 @@ class Member extends Users_Controller {
|
||||
$data['comment'] = '';
|
||||
// $data['fee'] = 0;
|
||||
//$data['escrow_balance'] = 0;
|
||||
$this->load->model('report_model');
|
||||
$this->load->model('account_model');
|
||||
$this->load->library('table');
|
||||
$this->table->set_template($this->template);
|
||||
$mysql = "SELECT m.added::date AS date,m.terminatingamount*0.01 AS amount,m.fee*0.01 as fee, "
|
||||
. "r.firstname||' '||r.lastname||'<br><b>Acc:</b>'||r.account_no||'-'||b.name AS Recitient,mp.confirmation,"
|
||||
. "CASE WHEN m.status=1 THEN 'Pending' WHEN m.status=3 THEN 'Cancelled' WHEN m.status=5 THEN 'Completed' ELSE '' END AS Status "
|
||||
. "FROM money_transfer m "
|
||||
. "LEFT JOIN sendmoney_recipient r ON r.id = m.recipientid "
|
||||
. "LEFT JOIN bank_entity_codes b ON b.code = r.bank_code "
|
||||
. "LEFT JOIN members_payments mp ON mp.what_sendmoney = m.id "
|
||||
. "WHERE m.member_id =" . $_SESSION['member_id'] . " AND mp.confirmation IS NOT NULL ORDER BY m.id DESC LIMIT 4";
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
$this->table->set_heading('Date', 'Amount','Fee','Recipient','Confirmation', 'Status');
|
||||
$data['sendmoney_table'] = $this->table->generate($query);
|
||||
$data['sendmoney_table_result'] = $query->result();
|
||||
|
||||
$data['card_payment_data_result'] = $this->report_model->getCardPurchase(6)['card_payment_data_result'];
|
||||
$data['wallet'] = $this->account_model->getUserWallet( $_SESSION['member_id']);
|
||||
|
||||
|
||||
if ($_POST) {
|
||||
$data['comment'] = $this->input->post('comment');
|
||||
@@ -664,24 +728,84 @@ class Member extends Users_Controller {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$data['page_title'] ="Wallet";
|
||||
$this->RenderUserPage('users/view_balance', $data);
|
||||
}
|
||||
|
||||
|
||||
public function smoney() {
|
||||
$data = $this->getSessionArray();
|
||||
//var_dump($data);
|
||||
//exit();
|
||||
|
||||
$data['add_error'] = '';
|
||||
$data['amount'] = 0;
|
||||
$this->load->model('combo_model');
|
||||
$data['recipient_account'] = $this->input->post('recipient_account');
|
||||
$data['recipient_account_combo'] = $this->combo_model->getUserRecipientCombo('recipient_account', $_SESSION['member_id'], $data['recipient_account']);
|
||||
$data['fee'] = $data['total'] =0;
|
||||
$data['comment'] = '';
|
||||
// $data['fee'] = 0;
|
||||
//$data['escrow_balance'] = 0;
|
||||
$this->load->model('account_model');
|
||||
$data['wallet'] = $this->account_model->getUserWallet($_SESSION['member_id'],$currency='NAIRA'); // $out['current_balance'];
|
||||
$data['current_balance'] = $data['wallet'][0]['current_balance'];
|
||||
|
||||
if ($_POST) {
|
||||
$data['comment'] = $this->input->post('comment');
|
||||
$data['amount'] = $this->input->post('amount') + 0; // must be number [still in full will be cents to go to backend latter]
|
||||
|
||||
if ($data['amount'] == 0 || $data['amount'] < 0 || $data['amount'] == '' || $data['recipient_account'] == '') {
|
||||
$out['error'] = 'Amount & Recipient Account Required';
|
||||
$data['add_error'] = "<div class=\"text-left\"><div class=\"alert alert-danger no-border\">" . $out['error'] . "</div></div>";
|
||||
if ($data['amount'] > 0) {
|
||||
$outx = $this->transactionFee($data['amount'], $_SESSION['member_id']);
|
||||
$data['total'] = $outx['total_amount'];
|
||||
$data['fee'] = $outx['processing_fee'];
|
||||
}
|
||||
} else {
|
||||
|
||||
$outx = $this->transactionFee($data['amount'], $_SESSION['member_id']);
|
||||
$data['total'] = $outx['total_amount'];
|
||||
$data['fee'] = $outx['processing_fee'];
|
||||
|
||||
$TotalAmount = $data['total'];
|
||||
|
||||
// now let us do initial check if you have enough money
|
||||
if ($data['current_balance'] < $TotalAmount) {
|
||||
$out['error'] = 'You do not have enough balance for this transfer';
|
||||
$data['add_error'] = "<div class=\"text-left\"><div class=\"alert alert-danger no-border\">" . $out['error'] . "</div></div>";
|
||||
} else {
|
||||
$this->session->set_flashdata('pending_sendmoney', $data);
|
||||
redirect('member/confirmwithdraw');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->load->library('table');
|
||||
$this->table->set_template($this->template);
|
||||
$mysql = "SELECT m.added::date AS date,m.terminatingamount*0.01 AS amount,m.fee*0.01 as fee, "
|
||||
. "r.firstname||' '||r.lastname||'<br><b>Acc:</b>'||r.account_no||'-'||b.name AS Recitient,mp.confirmation,"
|
||||
. "CASE WHEN m.status=1 THEN 'Pending' WHEN m.status=3 THEN 'Cancelled' WHEN m.status=5 THEN 'Completed' ELSE '' END AS Status "
|
||||
. "FROM money_transfer m "
|
||||
. "LEFT JOIN sendmoney_recipient r ON r.id = m.recipientid "
|
||||
. "LEFT JOIN bank_entity_codes b ON b.code = r.bank_code "
|
||||
. "LEFT JOIN members_payments mp ON mp.what_sendmoney = m.id "
|
||||
. "WHERE m.member_id =" . $_SESSION['member_id'] . " AND mp.confirmation IS NOT NULL ORDER BY m.id DESC LIMIT 4";
|
||||
. "r.firstname||' '||r.lastname||'<br><b>Acc:</b>'||r.account_no||'-'||b.name AS Recitient,mp.confirmation,"
|
||||
. "CASE WHEN m.status=1 THEN 'Pending' WHEN m.status=3 THEN 'Cancelled' WHEN m.status=5 THEN 'Completed' ELSE '' END AS Status "
|
||||
. "FROM money_transfer m "
|
||||
. "LEFT JOIN sendmoney_recipient r ON r.id = m.recipientid "
|
||||
. "LEFT JOIN bank_entity_codes b ON b.code = r.bank_code "
|
||||
. "LEFT JOIN members_payments mp ON mp.what_sendmoney = m.id "
|
||||
. "WHERE m.member_id =" . $_SESSION['member_id'] . " AND mp.confirmation IS NOT NULL ORDER BY m.id DESC LIMIT 4";
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
$this->table->set_heading('Date', 'Amount','Fee','Recipient','Confirmation', 'Status');
|
||||
$data['sendmoney_table'] = $this->table->generate($query);
|
||||
$data['sendmoney_table_result'] = $query->result();
|
||||
$data['page_title'] ="Wallet";
|
||||
|
||||
$this->RenderUserPage('users/view_balance', $data);
|
||||
|
||||
|
||||
$this->RenderUserPage('users/view_smoney', $data);
|
||||
}
|
||||
|
||||
|
||||
public function fee() {
|
||||
$amount = $this->input->get('amount') + 0;
|
||||
$res = $this->transactionFee($amount, $_SESSION['member_id']);
|
||||
@@ -705,41 +829,41 @@ class Member extends Users_Controller {
|
||||
public function confirmwithdraw() {
|
||||
$final_page = false;
|
||||
$data = $this->getSessionArray();
|
||||
|
||||
//$data = $this->getSessionArray();
|
||||
|
||||
if ($_POST) {
|
||||
$smIn =[];
|
||||
$smIn['member_id'] = $_SESSION['member_id'];
|
||||
$smIn['action'] = WRENCHBOARD_SMONEY_MEMBER;
|
||||
$smIn["senderid"] = $_SESSION['member_id'];
|
||||
$smIn["InitiatingEntityCode"] = "MBA";
|
||||
|
||||
//$data = array();
|
||||
$data['member_id'] = $_SESSION['member_id'];
|
||||
$data['action'] = WRENCHBOARD_SMONEY_MEMBER;
|
||||
$data["senderid"] = $_SESSION['member_id'];
|
||||
$data["InitiatingEntityCode"] = "MBA";
|
||||
$smIn['InitiatingAmount'] = $this->input->post('amount') * 100;
|
||||
$smIn['Fee'] = $this->input->post('fee') * 100;
|
||||
|
||||
$data['InitiatingAmount'] = $this->input->post('amount') * 100;
|
||||
$data['Fee'] = $this->input->post('fee') * 100;
|
||||
$smIn["InitiatingChannel"] = 7;
|
||||
$smIn["InitiatingPaymentMethodCode"] = "CA";
|
||||
$smIn["InitiatingCurrencyCode"] = '566'; // 566 - NRN - Naira
|
||||
//$smIn["recipientid"] = $this->input->post('recipient_account');
|
||||
$smIn['recipientid'] = $this->input->post('recipientid');
|
||||
$smIn["transaction_id"] = "T" . rand(120000, 999999);
|
||||
$smIn["TerminatingPaymentMethodCode"] = "AC";
|
||||
$smIn["TerminatingAmount"] = $smIn["InitiatingAmount"];
|
||||
$smIn["TerminatingCurrencyCode"] = '566'; // 566 - NRN - Naira
|
||||
$smIn["TerminatingCountryCode"] = 'NG'; // NG - Nigeria
|
||||
|
||||
$data["InitiatingChannel"] = 7;
|
||||
$data["InitiatingPaymentMethodCode"] = "CA";
|
||||
$data["InitiatingCurrencyCode"] = '566'; // 566 - NRN - Naira
|
||||
//$data["recipientid"] = $this->input->post('recipient_account');
|
||||
$data['recipientid'] = $this->input->post('recipientid');
|
||||
$data["transaction_id"] = "T" . rand(120000, 999999);
|
||||
$data["TerminatingPaymentMethodCode"] = "AC";
|
||||
$data["TerminatingAmount"] = $data["InitiatingAmount"];
|
||||
$data["TerminatingCurrencyCode"] = '566'; // 566 - NRN - Naira
|
||||
$data["TerminatingCountryCode"] = 'NG'; // NG - Nigeria
|
||||
$final_page = true;
|
||||
if ($data['recipientid'] != '' && $data['recipientid'] > 0 && $data['InitiatingAmount'] > 0 && $data['Fee'] >= 0) {
|
||||
if ($smIn['recipientid'] != '' && $smIn['recipientid'] > 0 && $smIn['InitiatingAmount'] > 0 && $smIn['Fee'] >= 0) {
|
||||
$this->load->model('backend_model');
|
||||
$out = array();
|
||||
$res = $this->backend_model->wrenchboard_api($data, $out);
|
||||
$res = $this->backend_model->wrenchboard_api($smIn, $out);
|
||||
// print_r($out);
|
||||
// exit;
|
||||
$data = $this->getSessionArray(); // you will need this for new balace
|
||||
$data["fee"] = $out["Fee"];
|
||||
$data["amount"] = $out["InitiatingAmount"];
|
||||
$data["total"] = $data["fee"] + $data["amount"];
|
||||
$data["recipient_account_detail"] = "Recipient Account Here";
|
||||
$data["comment"] = "Coment Here";
|
||||
$data["comment"] = "Comment Here";
|
||||
|
||||
$data["rec_firstname"] = $out["firstname"];
|
||||
$data["rec_lastname"] = $out["lastname"];
|
||||
@@ -770,7 +894,10 @@ class Member extends Users_Controller {
|
||||
*/
|
||||
} else {
|
||||
$pending_sendmoney = $this->session->flashdata('pending_sendmoney');
|
||||
$data['amount'] = 0;
|
||||
// var_dump($pending_sendmoney);
|
||||
if (!isset($pending_sendmoney)){
|
||||
redirect('member/balance');
|
||||
}
|
||||
$data['amount'] = $pending_sendmoney['amount'];
|
||||
$data['total'] = $pending_sendmoney['total'];
|
||||
$data['fee'] = $pending_sendmoney['fee'];
|
||||
@@ -782,18 +909,45 @@ class Member extends Users_Controller {
|
||||
$this->load->model('combo_model');
|
||||
$this->combo_model->setReadOnly(true);
|
||||
$data['recipient_account_combo'] = $this->combo_model->getUserRecipientCombo('recipient_account', $_SESSION['member_id'], $data['recipient_account']);
|
||||
|
||||
// $this->load->view('users/view_header_user', $data);
|
||||
$this->RenderUserPage('users/view_confirmwithdraw', $data);
|
||||
// $this->load->view('users/view_footer_user', $data);
|
||||
$data['sendmoney_table_result'] = $this->getSendMoneyRecent();
|
||||
$this->RenderUserPage('users/view_confirmwithdraw', $data);
|
||||
} else {
|
||||
|
||||
//$this->load->view('users/view_header_user', $data);
|
||||
$this->RenderUserPage('users/view_finalwithdraw', $data);
|
||||
// $this->load->view('users/view_footer_user', $data);
|
||||
$data['sendmoney_table_result'] = $this->getSendMoneyRecent();
|
||||
$this->session->set_flashdata('reciept_sendmoney', $data);
|
||||
redirect('member/sendMoneyReciepts');
|
||||
|
||||
// $data['sendmoney_table_result'] = $this->getSendMoneyRecent();
|
||||
// $this->RenderUserPage('users/view_finalwithdraw', $data);
|
||||
}
|
||||
}
|
||||
|
||||
public function sendMoneyReciepts(){
|
||||
|
||||
$data = $this->session->flashdata('reciept_sendmoney');
|
||||
// var_dump($pending_sendmoney);
|
||||
if (!isset($data)){
|
||||
redirect('member/balance');
|
||||
}
|
||||
|
||||
$data['sendmoney_table_result'] = $this->getSendMoneyRecent();
|
||||
$this->RenderUserPage('users/view_finalwithdraw', $data);
|
||||
}
|
||||
|
||||
private function getSendMoneyRecent(){
|
||||
|
||||
$mysql = "SELECT m.added::date AS date,m.terminatingamount*0.01 AS amount,m.fee*0.01 as fee, "
|
||||
. "r.firstname||' '||r.lastname||'<br><b>Acc:</b>'||r.account_no||'-'||b.name AS Recitient,mp.confirmation,"
|
||||
. "CASE WHEN m.status=1 THEN 'Pending' WHEN m.status=3 THEN 'Cancelled' WHEN m.status=5 THEN 'Completed' ELSE '' END AS Status "
|
||||
. "FROM money_transfer m "
|
||||
. "LEFT JOIN sendmoney_recipient r ON r.id = m.recipientid "
|
||||
. "LEFT JOIN bank_entity_codes b ON b.code = r.bank_code "
|
||||
. "LEFT JOIN members_payments mp ON mp.what_sendmoney = m.id "
|
||||
. "WHERE m.member_id =" . $_SESSION['member_id'] . " AND mp.confirmation IS NOT NULL ORDER BY m.id DESC LIMIT 4";
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
return $query->result();
|
||||
|
||||
}
|
||||
public function completewithdraw() {
|
||||
|
||||
echo 'Not attached - backend implemented already';
|
||||
@@ -817,7 +971,7 @@ class Member extends Users_Controller {
|
||||
|
||||
$myTable .="</table>";
|
||||
|
||||
|
||||
$data['page_title'] ="Messages";
|
||||
//$this->table->set_heading(array('data' => 'Date', 'style' => 'width:110px'), 'Message');
|
||||
$data['message_table'] = $myTable; //$this->table->generate($query);
|
||||
$this->RenderUserPage('users/view_message', $data);
|
||||
@@ -894,7 +1048,11 @@ class Member extends Users_Controller {
|
||||
|
||||
$this->load->library('pagination');
|
||||
$config = array();
|
||||
|
||||
/*
|
||||
*
|
||||
* 7 | MEMBER_NEWCARD_PAYM | MNCCD | 0
|
||||
8 | MEMBER_RETCARD_PAYM | MRCCD | 0
|
||||
*/
|
||||
|
||||
$this->load->library('table');
|
||||
$this->table->set_template($this->template);
|
||||
@@ -902,7 +1060,10 @@ class Member extends Users_Controller {
|
||||
. "WHEN code ='OFRFD' THEN 'Job Offer Refund' WHEN code='MDEPT' THEN 'Account Depoist' "
|
||||
. "WHEN code ='SMPAY' THEN 'Account Withdraw' "
|
||||
. "WHEN code ='COCNL' THEN 'Cancellation Refund' "
|
||||
. "WHEN code ='COPAY' THEN 'Completed Task Payment' ELSE '' END) AS Description,amount*0.01 AS amount,fee*0.01 as fee,confirmation "
|
||||
. "WHEN code ='COPAY' THEN 'Completed Task Payment' "
|
||||
. "WHEN code ='MNCCD' THEN 'New Card Payment' "
|
||||
. "WHEN code ='MRCCD' THEN 'Repeat Card Payment' "
|
||||
. "ELSE '' END) AS Description,amount*0.01 AS amount,fee*0.01 as fee,confirmation "
|
||||
. "FROM members_payments "
|
||||
. "WHERE member_id = " . $_SESSION['member_id'] . " AND status = 1 ORDER BY id DESC";
|
||||
$query = $this->db->query($mysql);
|
||||
@@ -935,20 +1096,25 @@ class Member extends Users_Controller {
|
||||
$page = is_numeric($page) ? $page : 0;
|
||||
|
||||
$mysql = "SELECT added::date,(CASE WHEN code = 'OFDPS' THEN 'Job Offer Deposit' "
|
||||
. "WHEN code ='OFRFD' THEN 'Job Offer Refund' WHEN code='MDEPT' THEN 'Account Depoist' "
|
||||
. "WHEN code ='SMPAY' THEN 'Account Withdraw' "
|
||||
. "WHEN code ='COCNL' THEN 'Cancellation Refund' "
|
||||
. "WHEN code ='COPAY' THEN 'Completed Task Payment' ELSE '' END) AS Description,amount*0.01 AS amount,fee*0.01 as fee,confirmation "
|
||||
. "FROM members_payments "
|
||||
. "WHERE member_id = " . $_SESSION['member_id'] . " AND status = 1 ORDER BY id DESC LIMIT " . $config["per_page"] . " OFFSET " . $page;
|
||||
. "WHEN code ='OFRFD' THEN 'Job Offer Refund' WHEN code='MDEPT' THEN 'Account Depoist' "
|
||||
. "WHEN code ='SMPAY' THEN 'Account Withdraw' "
|
||||
. "WHEN code ='COCNL' THEN 'Cancellation Refund' "
|
||||
. "WHEN code ='COPAY' THEN 'Completed Task Payment' "
|
||||
. "WHEN code ='MNCCD' THEN 'New Card Payment' "
|
||||
. "WHEN code ='MRCCD' THEN 'Repeat Card Payment' "
|
||||
. "ELSE '' END) AS Description,amount*0.01 AS amount,fee*0.01 as fee,confirmation "
|
||||
. "FROM members_payments "
|
||||
. "WHERE member_id = " . $_SESSION['member_id'] . " AND status = 1 ORDER BY id DESC LIMIT " . $config["per_page"] . " OFFSET " . $page;
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
|
||||
$this->table->set_heading(array('data' => 'Date', 'style' => 'width:110px'), 'Description', array('data' => 'Amount', 'style' => 'width:100px'), array('data' => 'Fee', 'style' => 'width:70px'), array('data' => 'Confirmation', 'style' => 'width:100px'));
|
||||
$data['payment_result'] = $this->table->generate($query);
|
||||
$data['payment_data_result'] = $query->result();
|
||||
$data["links"] = $this->pagination->create_links();
|
||||
|
||||
// $this->load->view('users/view_header_user', $data);
|
||||
$data['page_title'] ="Payments Report";
|
||||
$this->RenderUserPage('users/view_payment', $data);
|
||||
// $this->load->view('users/view_footer_user', $data);
|
||||
}
|
||||
@@ -1079,9 +1245,11 @@ class Member extends Users_Controller {
|
||||
public function settings() {
|
||||
|
||||
$data = $this->getSessionArray();
|
||||
$this->load->view('users/view_header_user', $data);
|
||||
/* $this->load->view('users/view_header_user', $data);
|
||||
$this->load->view('users/view_settings', $data);
|
||||
$this->load->view('users/view_footer_user', $data);
|
||||
$this->load->view('users/view_footer_user', $data);*/
|
||||
|
||||
$this->RenderUserPage('users/view_settings', $data);
|
||||
}
|
||||
|
||||
private function AgetSessionArray() {
|
||||
|
||||
@@ -7,9 +7,10 @@ class Outmessage extends CI_Controller {
|
||||
$data['account_email'] = ''; //$data['username'];
|
||||
$data['title'] = "Message"; //ucfirst($page); // Capitalize the first letter
|
||||
$data['page_title'] = "Verify Email.";
|
||||
$this->load->view('templates/header_boxed', $data);
|
||||
$this->load->view('users/view_outmessage', $data);
|
||||
$this->load->view('templates/footer_boxed', $data);
|
||||
//$this->load->view('templates/header_boxed', $data);
|
||||
//$this->load->view('users/view_outmessage', $data);
|
||||
//$this->load->view('templates/footer_boxed', $data);
|
||||
$this->load->view('site3/external/view_signup_started',$data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,29 +5,25 @@ defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
class Password_recovery extends CI_Controller {
|
||||
|
||||
public function index() {
|
||||
//echo "ameye kvkgkg";
|
||||
$data['action_message'] = "";
|
||||
|
||||
|
||||
if ($_POST) {
|
||||
|
||||
$data['email'] = $this->input->post('email');
|
||||
if ($data['email'] == '') {
|
||||
$out['error'] = 'Please specify valid emal to continue';
|
||||
$data['action_message'] = "<div class=\"text-left\"><div class=\"alert alert-danger no-border\">" . $out['error'] . "</div></div>";
|
||||
} else {
|
||||
//WRENCHBOARD_ACCOUNT_RESETPASS
|
||||
|
||||
$this->resetMemberPass($data['email']);
|
||||
|
||||
$out['error'] = "If we find your email, you will receive a link to reset your password. Please use or <a href='/contact'>contact form</a> if you did not get our message after few minutes. ";
|
||||
$out['error'] = " If we find your email, you will receive a link to reset your password. Please use or <a
|
||||
href='https://www.wrenchboard.com/contact'>contact form</a> if you did not get our message after few minutes. ";
|
||||
$data['action_message'] = "<div class=\"text-left\"><div class=\"alert alert-info no-border\">" . $out['error'] . "</div></div>";
|
||||
}
|
||||
}
|
||||
$data["message"] = "Enter your account username, Email.<br> We will send you an email to reset your password";
|
||||
$this->load->view('users/view_external_header');
|
||||
$this->load->view('users/view_password_recovery', $data);
|
||||
$this->load->view('users/view_external_footer');
|
||||
// $this->load->view('users/view_external_header');
|
||||
// $this->load->view('users/view_password_recovery', $data);
|
||||
// $this->load->view('users/view_external_footer');
|
||||
$this->load->view('site3/external/view_resetpass',$data);
|
||||
//
|
||||
}
|
||||
|
||||
var $actionMessage = '';
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
class Paymnt extends Users_Controller {
|
||||
|
||||
public function index() {
|
||||
|
||||
$data = $this->getSessionArray();
|
||||
if (!isset($_SESSION['username']) or $_SESSION['username'] == '') {
|
||||
redirect(home);
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function paymus() {
|
||||
|
||||
$data = $this->getSessionArray();
|
||||
$data['card_table_result'] = $this->cardListData(4)['card_table_result'];
|
||||
$this->RenderUserPage('users/view_startpaymus', $data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function cardListData($limit){
|
||||
$data = array();
|
||||
$mysql = "SELECT * FROM creditcard WHERE member_id = " . $_SESSION['member_id'] . " AND status =3 AND active =1 ORDER BY id DESC limit ".$limit;
|
||||
$query = $this->db->query($mysql);
|
||||
$data['card_table_result'] = $query->result();
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function newcc(){
|
||||
$data = $this->getSessionArray();
|
||||
if ($_POST) {
|
||||
$this->load->model('cardpay_model');
|
||||
$cd = array();
|
||||
$cd['cardnumber'] = $this->input->post('cardnumber');
|
||||
$cd['exp_month'] = $this->input->post('exp_month');
|
||||
$cd['exp_year'] = $this->input->post('exp_year');
|
||||
$cd['cvc'] = $this->input->post('cvc');
|
||||
$cd['description']= $this->input->post('description');
|
||||
$amount = rand(5555,9999);
|
||||
|
||||
$cardTestResult= $this->cardpay_model->verifyCardData($cd);
|
||||
|
||||
//var_dump($cardTestResult);
|
||||
//var_dump($cd);
|
||||
|
||||
|
||||
if ( $cardTestResult['error_status'] == false) // no error
|
||||
{
|
||||
$member_id = $_SESSION['member_id'];
|
||||
$email ="support@wrenchboard.com";
|
||||
$cardData=array(
|
||||
"action" => WRENCHBOARD_USER_ADNEWCC,
|
||||
"cardnumber" => $cd['cardnumber'],
|
||||
"exp_month" => $cd['exp_month'],
|
||||
"exp_year" => $cd['exp_year'],
|
||||
"cvc" => $cd['cvc'],
|
||||
"amount" => $amount ,
|
||||
"email" => $email,
|
||||
"description" => $cd['description'],
|
||||
"member_id" => $member_id,
|
||||
"paymenttype" => 100
|
||||
);
|
||||
$out=array();
|
||||
$this->load->model('backend_model');
|
||||
$res = $this->backend_model->wrenchboard_api($cardData, $out);
|
||||
|
||||
// var_dump($res);
|
||||
// exit();
|
||||
$out['order_id'] = $res;
|
||||
if ($res > 0 && isset($out) && isset($out['confirmation']) && $out['confirmation']!='') {
|
||||
// we are good
|
||||
$this->session->set_flashdata('reciept_data', $out);
|
||||
redirect("paymnt/cardreciepts");
|
||||
|
||||
} else {
|
||||
// not good
|
||||
$this->session->set_flashdata('reciept_data', $out);
|
||||
redirect("paymnt/cardreciepts");
|
||||
}
|
||||
|
||||
} // no error(s) from card test PHP model
|
||||
else{
|
||||
$data['card_test_result'] = $cardTestResult;
|
||||
$data['card_table_result'] = $this->cardListData(4)['card_table_result'];
|
||||
$this->RenderUserPage('users/view_startpaymus', $data); // return back to card page
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->paymus();
|
||||
}
|
||||
}
|
||||
|
||||
public function cardreciepts(){
|
||||
|
||||
$data = array_merge($this->getSessionArray(), $this->session->flashdata('reciept_data'));
|
||||
if (!isset($data['confirmation'])){
|
||||
redirect("dash");
|
||||
}
|
||||
$this->RenderUserPage('users/view_payreciepts', $data); // return back to card page
|
||||
}
|
||||
}
|
||||
@@ -14,17 +14,7 @@ class Plb extends WRB_Controller {
|
||||
}
|
||||
|
||||
private function jobViewPage($offerCode) {
|
||||
/* $data['sitename'] = 'home';
|
||||
$this->load->view('templates/header_boxed', $data);
|
||||
$this->load->view('users/view_index');
|
||||
$this->load->view('users/view_external_footer');
|
||||
* */
|
||||
// $this->load->view('users/view_index');
|
||||
// $this->load->view('users/view_external_footer');
|
||||
|
||||
$data = array();
|
||||
|
||||
|
||||
$mysql = "SELECT jo.expire,jo.id AS offer_id, jo.offer_code,mj.title,mj.description,mj.timeline_days,mj.price,jo.job_description FROM members_jobs_offer jo "
|
||||
. " LEFT JOIN members_jobs mj ON mj.id=jo.job_id "
|
||||
. " WHERE mj.status=1 AND jo.status=1 "
|
||||
@@ -55,25 +45,9 @@ class Plb extends WRB_Controller {
|
||||
. " WHERE o.public_view =1 AND o.offer_code<>'" . $offerCode . "' AND o.expire> now() AND o.status=1 ORDER BY o.id DESC LIMIT 50";
|
||||
$query = $this->db->query($mysql2);
|
||||
$data["numof_other_jobs"] = $query->num_rows();
|
||||
$data["job_data"] = $query->result();
|
||||
$data["job_data"] = $query->result()[0];
|
||||
|
||||
|
||||
|
||||
/*
|
||||
$mysql2 = " SELECT o.*,j.title,j.description,j.timeline_days,j.price,j FROM members_jobs_offer o "
|
||||
. " LEFT JOIN members_jobs j ON j.id =o.job_id "
|
||||
. " WHERE o.public_view =1 AND o.offer_code<>'" . $offerCode . "' AND o.expire> now() ORDER BY o.id DESC LIMIT 50";
|
||||
|
||||
|
||||
$query = $this->db->query($mysql2);
|
||||
$data["numof_other_jobs"] = $query->num_rows();
|
||||
$data["job_data"] = $query->result();
|
||||
*/
|
||||
|
||||
|
||||
$this->load->view('templates/view_header_market', $data);
|
||||
$this->load->view('site/view_market', $data);
|
||||
$this->load->view('templates/view_footer_market', $data);
|
||||
$this->load->view('site3/external/view_market',$data);
|
||||
}
|
||||
|
||||
private function makeMarketTableRow($row) {
|
||||
@@ -92,13 +66,13 @@ class Plb extends WRB_Controller {
|
||||
|
||||
|
||||
|
||||
return "<table class='table table-striped table-hover table-bordered table-condensed'><tr><td colspan='2' ><b> Timeline:</b>" . $row['timeline_days'] . " day(s) - <b>Budget: </b> " . $row['price'] * 0.01 . " Naira</td></tr>"
|
||||
return "<table class='table table align-middle gs-0 gy-5'><tr><td colspan='2' ><b> Timeline:</b>" . $row['timeline_days'] . " day(s) - <b>Budget: </b> " . $row['price'] * 0.01 . " Naira</td></tr>"
|
||||
. "<tr><td style='width:100px;'><b>Title</b></td><td>" . $row['title'] . "</td></tr>"
|
||||
. "<tr><td><b>Description</b></td><td>" . $row['description'] . "</td></tr>"
|
||||
. "<tr><td><b>Detail</b></td><td>" . $row['job_description'] . "</td></tr>"
|
||||
. "<tr><td colspan='2' >Interests : <b>" . $data['interest'] . "</b> Expire:<b> " . $row['expire'] . "</b> </td></tr>"
|
||||
. "<tr><td><b></b></td><td style='text-align:right;'><input type=submit id='submit_interest_" . $row['offer_code'] . "' name=\"mview\" onclick=\"return LoginInterest('" . $row['offer_code'] . "');\" class=\"btn btn-success btn-xs\" value=\"see more ?
|
||||
\"></td></tr>"
|
||||
|
||||
. "<tr><td><b></b></td><td style='text-align:right;'><a class=\"btn btn-primary btn-xs\" href='/login'>See More</a></td></tr>tr>"
|
||||
. "</table> ";
|
||||
}
|
||||
|
||||
|
||||
@@ -232,9 +232,13 @@ class Proj extends Users_Controller {
|
||||
$data['current_balance'] = $out['current_balance'];
|
||||
$data['new_message'] = $out['new_message'];
|
||||
|
||||
$this->load->view('users/view_header_user', $data);
|
||||
/* $this->load->view('users/view_header_user', $data);
|
||||
$this->load->view('jobs/view_activejob', $data);
|
||||
$this->load->view('users/view_footer_user', $data);
|
||||
$this->load->view('users/view_footer_user', $data);*/
|
||||
|
||||
$data['page_title'] = "Active Task";
|
||||
$this->RenderUserPage('jobs/view_activejob', $data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1010,10 +1014,13 @@ $data = $this->getSessionArray();
|
||||
$data['new_message'] = $out['new_message'];
|
||||
|
||||
|
||||
|
||||
/*
|
||||
$this->load->view('users/view_header_user', $data);
|
||||
$this->load->view('jobs/view_mycompletejob', $data);
|
||||
$this->load->view('users/view_footer_user', $data);
|
||||
*/
|
||||
$data['page_title'] ="Previous Tasks";
|
||||
$this->renderSecurePage('jobs/view_mycompletejob', $data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,13 +95,15 @@ class Refer extends Users_Controller {
|
||||
$this->table->set_heading(array('data' => 'Added/Name', 'style' => 'width:170px'), 'Email', array('data' => 'Status', 'style' => 'width:80px'));
|
||||
|
||||
$data['refer_table'] = $this->table->generate($query);
|
||||
|
||||
$data['refer_table_result'] =$query->result();
|
||||
|
||||
$data['page_title'] ="Refer a Friend";
|
||||
|
||||
/*
|
||||
$this->load->view('users/view_header_user', $data);
|
||||
$this->load->view('users/view_refer', $data);
|
||||
$this->load->view('users/view_footer_user', $data);
|
||||
*/
|
||||
$this->RenderUserPage('users/view_refer', $data);
|
||||
}
|
||||
|
||||
public function refagree() {
|
||||
|
||||
@@ -18,6 +18,7 @@ class Signup extends CI_Controller {
|
||||
$submit = NULL;
|
||||
|
||||
extract($_POST);
|
||||
//var_dump($_POST);
|
||||
|
||||
$data['firstname'] = $firstname;
|
||||
$data['lastname'] = $lastname;
|
||||
@@ -39,7 +40,8 @@ class Signup extends CI_Controller {
|
||||
$data['signup_error'] = '';
|
||||
|
||||
if ($_POST) { // post
|
||||
if ($data['terms'] == 'on') {
|
||||
if ($data['terms'] == 'on' || $data['terms'] == '1') {
|
||||
$data['terms'] == 'on';
|
||||
$terms_checked = 'checked';
|
||||
}
|
||||
|
||||
@@ -73,6 +75,7 @@ class Signup extends CI_Controller {
|
||||
} else {
|
||||
$data['signup_error'] = "Enter all required fields";
|
||||
}
|
||||
//exit;
|
||||
} // if post
|
||||
$data['signup_error_style'] = '';
|
||||
if (strlen($data['signup_error']) > 0) {
|
||||
@@ -81,10 +84,7 @@ class Signup extends CI_Controller {
|
||||
|
||||
|
||||
$data['terms'] = $terms_checked;
|
||||
|
||||
|
||||
$this->load->view('users/view_registration', $data);
|
||||
$this->load->view('users/view_external_footer', $data);
|
||||
$this->load->view('site3/external/view_signup',$data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,9 @@ class Site extends WRB_Controller {
|
||||
$this->load->view('users/view_external_footer');
|
||||
* */
|
||||
|
||||
$this->home1();
|
||||
// $this->home1();
|
||||
$this->load->view('site3/external/view_home');
|
||||
///home/oameye/wrenchboard/www/application/views/site3/external
|
||||
}
|
||||
|
||||
public function registration() {
|
||||
|
||||
@@ -74,17 +74,22 @@ class WRB_Controller extends CI_Controller {
|
||||
$out = $this->dash_model->getDashData($data);
|
||||
$data['active_task'] = $out['active_task'];
|
||||
$data['active_pass_due'] = $out['active_pass_due'];
|
||||
$data['current_balance'] = $out['current_balance'];
|
||||
$data['new_message'] = $out['new_message'];
|
||||
$_SESSION["active_offers_count"] = $out['active_offers_count'];
|
||||
|
||||
$data = $_SESSION['secure_data'];
|
||||
$this->load->model('account_model');
|
||||
$data['wallet'] = $this->account_model->getUserWallet($_SESSION['member_id'],$currency='NAIRA'); // $out['current_balance'];
|
||||
$data['current_balance'] = $data['wallet'][0]['current_balance'];
|
||||
|
||||
|
||||
$data = $_SESSION['secure_data'];
|
||||
$data['member_id'] = $_SESSION['member_id']; // = $ret->email;
|
||||
|
||||
$this->refreshAccountDetail($_SESSION['member_id']);
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
protected function logUser($mlog) {
|
||||
//
|
||||
$data['action'] = WRENCHBOARD_LOG_MEMBER;
|
||||
|
||||
@@ -39,11 +39,15 @@ class Users_Controller extends WRB_Controller {
|
||||
$out = $this->dash_model->getDashData($data);
|
||||
$data['active_task'] = $out['active_task'];
|
||||
$data['active_pass_due'] = $out['active_pass_due'];
|
||||
$data['current_balance'] = $out['current_balance'];
|
||||
//$data['current_balance'] = $out['current_balance'];
|
||||
$data['new_message'] = $out['new_message'];
|
||||
$data['escrow_balance'] = $out['escrow_balance'];
|
||||
$data['description'] = $out["description"];
|
||||
|
||||
$this->load->model('account_model');
|
||||
$data['wallet'] = $this->account_model->getUserWallet($_SESSION['member_id'],$currency='NAIRA'); // $out['current_balance'];
|
||||
$data['current_balance'] = $data['wallet'][0]['current_balance'];
|
||||
|
||||
//$data = $_SESSION['secure_data'];
|
||||
$data['member_id'] = $_SESSION['member_id']; // = $ret->email;
|
||||
$_SESSION["active_offers_count"] = $out['active_offers_count'];
|
||||
@@ -58,7 +62,12 @@ class Users_Controller extends WRB_Controller {
|
||||
$this->load->model('account_model');
|
||||
$qr = $this->account_model->loadAccountData($member_id);
|
||||
// print_r($qr);
|
||||
$_SESSION['current_balance'] = $qr[0]['balance'];
|
||||
// $_SESSION['current_balance'] = $qr[0]['balance'];
|
||||
|
||||
$this->load->model('account_model');
|
||||
$data['wallet'] = $this->account_model->getUserWallet($member_id,$currency='NAIRA'); // $out['current_balance'];
|
||||
$_SESSION['current_balance'] = $data['wallet'][0]['current_balance'];
|
||||
|
||||
$_SESSION['active_task'] = $this->account_model->loadActiveTaskCount($member_id);
|
||||
$_SESSION['state'] = $qr[0]['state'];
|
||||
$_SESSION['city'] = $qr[0]['city'];
|
||||
@@ -77,11 +86,20 @@ class Users_Controller extends WRB_Controller {
|
||||
redirect(home);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function renderSecurePage($page_path_name, $data) {
|
||||
$this->load->view('site3/internal/template/view_securehead', $data);
|
||||
$this->load->view( $page_path_name, $data);
|
||||
$this->load->view('site3/internal/template/view_securefooter', $data);
|
||||
}
|
||||
|
||||
protected function RenderUserPage($page_name, $data) {
|
||||
return $this->renderSecurePage($page_name, $data);
|
||||
/*
|
||||
$this->load->view('users/view_header_user', $data);
|
||||
$this->load->view($page_name, $data);
|
||||
$this->load->view('users/view_footer_user', $data);
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,18 @@ class Account_model extends CI_Model {
|
||||
|
||||
}
|
||||
|
||||
public function getUserWallet($member_id,$currency='') {
|
||||
$num = 0;
|
||||
//$mysql = "SELECT * FROM members_wallet WHERE member_id = $member_id AND currency='".$currency."' ";
|
||||
$and_part = '';
|
||||
if ($currency =''){
|
||||
$and_part = " AND w.currency='$currency' ";
|
||||
}
|
||||
$mysql = "SELECT w.amount,c.*,w.amount AS current_balance FROM members_wallet w LEFT JOIN currency c ON c.code=w.currency WHERE w.member_id = $member_id ".$and_part." ORDER BY c.lorder DESC";
|
||||
$query = $this->db->query($mysql);
|
||||
return $query->result_array();
|
||||
}
|
||||
|
||||
public function verify_link($data) {
|
||||
$q = $this
|
||||
->db
|
||||
|
||||
@@ -20,9 +20,21 @@ class Backend_model extends CI_Model {
|
||||
public function wrenchboard_api($in, $out = array()) {
|
||||
$this->wrenchboard_load();
|
||||
$ret = $this->wrenchboard->wrenchboard_api($in, $out);
|
||||
|
||||
// var_dump($ret);
|
||||
// echo "-----";
|
||||
// var_dump($out);
|
||||
// exit();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wrenchboard_api2($in, $out) {
|
||||
$this->wrenchboard_load();
|
||||
$ret = $this->wrenchboard->wrenchboard_api($in, $out);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
public function cfgReadChar($str) {
|
||||
$this->wrenchboard_load();
|
||||
$ret = $this->wrenchboard->cfgReadChar($str);
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
class Cardpay_model extends CI_Model {
|
||||
|
||||
function __construct() {
|
||||
|
||||
}
|
||||
|
||||
public function verifyCardData($data){
|
||||
$error_status = false;
|
||||
$errorArray = array ();
|
||||
/*
|
||||
$cd['cardnumber'] = $this->input->post('cardnumber');
|
||||
$cd['exp_month'] = $this->input->post('exp_month');
|
||||
$cd['exp_year'] = $this->input->post('exp_year');
|
||||
$cd['cvc'] = $this->input->post('cvc');
|
||||
$cd['description']= $this->input->post('description');
|
||||
*/
|
||||
|
||||
if ( strlen( $data['cvc'] ) == 0 ){
|
||||
$error_status = true;
|
||||
$errorArray[]="Enter valid card CVV";
|
||||
}
|
||||
|
||||
if ( strlen( $data['cardnumber'] ) == 0 || $this->luhn_check( $data['cardnumber'] ) == false){
|
||||
$error_status = true;
|
||||
$errorArray[]="Enter valid card number";
|
||||
}
|
||||
|
||||
if ( strlen( $data['exp_year'] ) == 0 || $data['exp_year'] < date('Y') ){
|
||||
$error_status = true;
|
||||
$errorArray[]="Enter valid card expiration date";
|
||||
}
|
||||
else{
|
||||
|
||||
// let us test the month now
|
||||
}
|
||||
|
||||
if ( strlen( $data['description'] ) == 0 ){
|
||||
$error_status = true;
|
||||
$errorArray[]="Enter name on card";
|
||||
}
|
||||
|
||||
return [
|
||||
"error_status" => $error_status,
|
||||
"error_message" => $errorArray
|
||||
];
|
||||
}
|
||||
|
||||
public function verifyCCNumber($cardNumber) {
|
||||
|
||||
return $this->luhn_check($cardNumber);
|
||||
}
|
||||
|
||||
/* Luhn algorithm number checker - (c) 2005-2008 shaman - www.planzero.org *
|
||||
* This code has been released into the public domain, however please *
|
||||
* give credit to the original author where possible. */
|
||||
|
||||
private function luhn_check($number) {
|
||||
|
||||
// Strip any non-digits (useful for credit card numbers with spaces and hyphens)
|
||||
$number=preg_replace('/\D/', '', $number);
|
||||
|
||||
// Set the string length and parity
|
||||
$number_length=strlen($number);
|
||||
$parity=$number_length % 2;
|
||||
|
||||
// Loop through each digit and do the maths
|
||||
$total=0;
|
||||
for ($i=0; $i<$number_length; $i++) {
|
||||
$digit=$number[$i];
|
||||
// Multiply alternate digits by two
|
||||
if ($i % 2 == $parity) {
|
||||
$digit*=2;
|
||||
// If the sum is two digits, add them together (in effect)
|
||||
if ($digit > 9) {
|
||||
$digit-=9;
|
||||
}
|
||||
}
|
||||
// Total up the digits
|
||||
$total+=$digit;
|
||||
}
|
||||
|
||||
// If the total mod 10 equals 0, the number is valid
|
||||
return ($total % 10 == 0) ? TRUE : FALSE;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -54,6 +54,7 @@ class Dash_model extends CI_Model {
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
||||
public function getNewMessageCount($member_id) {
|
||||
$out = array();
|
||||
$out['new_message'] =0;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
class Report_model extends CI_Model {
|
||||
|
||||
function __construct() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getCardPurchase($limit){
|
||||
$data = array();
|
||||
$mysql = "SELECT added::date,"
|
||||
." (CASE WHEN code ='MNCCD' THEN 'New Card Payment' "
|
||||
. "WHEN code ='MRCCD' THEN 'Repeat Card Payment' "
|
||||
. "ELSE '' END) AS Description,amount*0.01 AS amount,fee*0.01 as fee,confirmation "
|
||||
. "FROM members_payments "
|
||||
. "WHERE member_id = " . $_SESSION['member_id'] . " AND status = 1 ORDER BY id DESC LIMIT ". $limit; // OFFSET " . $page;
|
||||
|
||||
$query = $this->db->query($mysql);
|
||||
$data['card_payment_data_result'] = $query->result();
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Adapter;
|
||||
|
||||
use Hybridauth\Exception\NotImplementedException;
|
||||
use Hybridauth\Exception\InvalidArgumentException;
|
||||
use Hybridauth\Exception\HttpClientFailureException;
|
||||
use Hybridauth\Exception\HttpRequestFailedException;
|
||||
use Hybridauth\Storage\StorageInterface;
|
||||
use Hybridauth\Storage\Session;
|
||||
use Hybridauth\Logger\LoggerInterface;
|
||||
use Hybridauth\Logger\Logger;
|
||||
use Hybridauth\HttpClient\HttpClientInterface;
|
||||
use Hybridauth\HttpClient\Curl as HttpClient;
|
||||
use Hybridauth\Data;
|
||||
|
||||
/**
|
||||
* Class AbstractAdapter
|
||||
*/
|
||||
abstract class AbstractAdapter implements AdapterInterface
|
||||
{
|
||||
use DataStoreTrait;
|
||||
|
||||
/**
|
||||
* Provider ID (unique name).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $providerId = '';
|
||||
|
||||
/**
|
||||
* Specific Provider config.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $config = [];
|
||||
|
||||
/**
|
||||
* Extra Provider parameters.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
/**
|
||||
* Callback url
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $callback = '';
|
||||
|
||||
/**
|
||||
* Storage.
|
||||
*
|
||||
* @var StorageInterface
|
||||
*/
|
||||
public $storage;
|
||||
|
||||
/**
|
||||
* HttpClient.
|
||||
*
|
||||
* @var HttpClientInterface
|
||||
*/
|
||||
public $httpClient;
|
||||
|
||||
/**
|
||||
* Logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
public $logger;
|
||||
|
||||
/**
|
||||
* Whether to validate API status codes of http responses
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $validateApiResponseHttpCode = true;
|
||||
|
||||
/**
|
||||
* Common adapters constructor.
|
||||
*
|
||||
* @param array $config
|
||||
* @param HttpClientInterface $httpClient
|
||||
* @param StorageInterface $storage
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function __construct(
|
||||
$config = [],
|
||||
HttpClientInterface $httpClient = null,
|
||||
StorageInterface $storage = null,
|
||||
LoggerInterface $logger = null
|
||||
) {
|
||||
$this->providerId = (new \ReflectionClass($this))->getShortName();
|
||||
|
||||
$this->config = new Data\Collection($config);
|
||||
|
||||
$this->setHttpClient($httpClient);
|
||||
|
||||
$this->setStorage($storage);
|
||||
|
||||
$this->setLogger($logger);
|
||||
|
||||
$this->configure();
|
||||
|
||||
$this->logger->debug(sprintf('Initialize %s, config: ', get_class($this)), $config);
|
||||
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load adapter's configuration
|
||||
*/
|
||||
abstract protected function configure();
|
||||
|
||||
/**
|
||||
* Adapter initializer
|
||||
*/
|
||||
abstract protected function initialize();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
abstract public function isConnected();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
|
||||
{
|
||||
throw new NotImplementedException('Provider does not support this feature.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function maintainToken()
|
||||
{
|
||||
// Nothing needed for most providers
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUserProfile()
|
||||
{
|
||||
throw new NotImplementedException('Provider does not support this feature.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUserContacts()
|
||||
{
|
||||
throw new NotImplementedException('Provider does not support this feature.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUserPages()
|
||||
{
|
||||
throw new NotImplementedException('Provider does not support this feature.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUserActivity($stream)
|
||||
{
|
||||
throw new NotImplementedException('Provider does not support this feature.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUserStatus($status)
|
||||
{
|
||||
throw new NotImplementedException('Provider does not support this feature.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setPageStatus($status, $pageId)
|
||||
{
|
||||
throw new NotImplementedException('Provider does not support this feature.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
$this->clearStoredData();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAccessToken()
|
||||
{
|
||||
$tokenNames = [
|
||||
'access_token',
|
||||
'access_token_secret',
|
||||
'token_type',
|
||||
'refresh_token',
|
||||
'expires_in',
|
||||
'expires_at',
|
||||
];
|
||||
|
||||
$tokens = [];
|
||||
|
||||
foreach ($tokenNames as $name) {
|
||||
if ($this->getStoredData($name)) {
|
||||
$tokens[$name] = $this->getStoredData($name);
|
||||
}
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAccessToken($tokens = [])
|
||||
{
|
||||
$this->clearStoredData();
|
||||
|
||||
foreach ($tokens as $token => $value) {
|
||||
$this->storeData($token, $value);
|
||||
}
|
||||
|
||||
// Re-initialize token parameters.
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setHttpClient(HttpClientInterface $httpClient = null)
|
||||
{
|
||||
$this->httpClient = $httpClient ?: new HttpClient();
|
||||
|
||||
if ($this->config->exists('curl_options') && method_exists($this->httpClient, 'setCurlOptions')) {
|
||||
$this->httpClient->setCurlOptions($this->config->get('curl_options'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHttpClient()
|
||||
{
|
||||
return $this->httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setStorage(StorageInterface $storage = null)
|
||||
{
|
||||
$this->storage = $storage ?: new Session();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getStorage()
|
||||
{
|
||||
return $this->storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger = null)
|
||||
{
|
||||
$this->logger = $logger ?: new Logger(
|
||||
$this->config->get('debug_mode'),
|
||||
$this->config->get('debug_file')
|
||||
);
|
||||
|
||||
if (method_exists($this->httpClient, 'setLogger')) {
|
||||
$this->httpClient->setLogger($this->logger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLogger()
|
||||
{
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Adapter's API callback url
|
||||
*
|
||||
* @param string $callback
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function setCallback($callback)
|
||||
{
|
||||
if (!filter_var($callback, FILTER_VALIDATE_URL)) {
|
||||
throw new InvalidArgumentException('A valid callback url is required.');
|
||||
}
|
||||
|
||||
$this->callback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite Adapter's API endpoints
|
||||
*
|
||||
* @param array|Data\Collection $endpoints
|
||||
*/
|
||||
protected function setApiEndpoints($endpoints = null)
|
||||
{
|
||||
if (empty($endpoints)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$collection = is_array($endpoints) ? new Data\Collection($endpoints) : $endpoints;
|
||||
|
||||
$this->apiBaseUrl = $collection->get('api_base_url') ?: $this->apiBaseUrl;
|
||||
$this->authorizeUrl = $collection->get('authorize_url') ?: $this->authorizeUrl;
|
||||
$this->accessTokenUrl = $collection->get('access_token_url') ?: $this->accessTokenUrl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate signed API responses Http status code.
|
||||
*
|
||||
* Since the specifics of error responses is beyond the scope of RFC6749 and OAuth Core specifications,
|
||||
* Hybridauth will consider any HTTP status code that is different than '200 OK' as an ERROR.
|
||||
*
|
||||
* @param string $error String to pre append to message thrown in exception
|
||||
*
|
||||
* @throws HttpClientFailureException
|
||||
* @throws HttpRequestFailedException
|
||||
*/
|
||||
protected function validateApiResponse($error = '')
|
||||
{
|
||||
$error .= !empty($error) ? '. ' : '';
|
||||
|
||||
if ($this->httpClient->getResponseClientError()) {
|
||||
throw new HttpClientFailureException(
|
||||
$error . 'HTTP client error: ' . $this->httpClient->getResponseClientError() . '.'
|
||||
);
|
||||
}
|
||||
|
||||
// if validateApiResponseHttpCode is set to false, we by pass verification of http status code
|
||||
if (!$this->validateApiResponseHttpCode) {
|
||||
return;
|
||||
}
|
||||
|
||||
$status = $this->httpClient->getResponseHttpCode();
|
||||
|
||||
if ($status < 200 || $status > 299) {
|
||||
throw new HttpRequestFailedException(
|
||||
$error . 'HTTP error ' . $this->httpClient->getResponseHttpCode() .
|
||||
'. Raw Provider API response: ' . $this->httpClient->getResponseBody() . '.'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Adapter;
|
||||
|
||||
use Hybridauth\HttpClient\HttpClientInterface;
|
||||
use Hybridauth\Storage\StorageInterface;
|
||||
use Hybridauth\Logger\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Interface AdapterInterface
|
||||
*/
|
||||
interface AdapterInterface
|
||||
{
|
||||
/**
|
||||
* Initiate the appropriate protocol and process/automate the authentication or authorization flow.
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function authenticate();
|
||||
|
||||
/**
|
||||
* Returns TRUE if the user is connected
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isConnected();
|
||||
|
||||
/**
|
||||
* Clear all access token in storage
|
||||
*/
|
||||
public function disconnect();
|
||||
|
||||
/**
|
||||
* Retrieve the connected user profile
|
||||
*
|
||||
* @return \Hybridauth\User\Profile
|
||||
*/
|
||||
public function getUserProfile();
|
||||
|
||||
/**
|
||||
* Retrieve the connected user contacts list
|
||||
*
|
||||
* @return \Hybridauth\User\Contact[]
|
||||
*/
|
||||
public function getUserContacts();
|
||||
|
||||
/**
|
||||
* Retrieve the connected user pages|companies|groups list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getUserPages();
|
||||
|
||||
/**
|
||||
* Retrieve the user activity stream
|
||||
*
|
||||
* @param string $stream
|
||||
*
|
||||
* @return \Hybridauth\User\Activity[]
|
||||
*/
|
||||
public function getUserActivity($stream);
|
||||
|
||||
/**
|
||||
* Post a status on user wall|timeline|blog|website|etc.
|
||||
*
|
||||
* @param string|array $status
|
||||
*
|
||||
* @return mixed API response
|
||||
*/
|
||||
public function setUserStatus($status);
|
||||
|
||||
/**
|
||||
* Post a status on page|company|group wall.
|
||||
*
|
||||
* @param string|array $status
|
||||
* @param string $pageId
|
||||
*
|
||||
* @return mixed API response
|
||||
*/
|
||||
public function setPageStatus($status, $pageId);
|
||||
|
||||
/**
|
||||
* Send a signed request to provider API
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param array $headers
|
||||
* @param bool $multipart
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false);
|
||||
|
||||
/**
|
||||
* Do whatever may be necessary to make sure tokens do not expire.
|
||||
* Intended to be be called frequently, e.g. via Cron.
|
||||
*/
|
||||
public function maintainToken();
|
||||
|
||||
/**
|
||||
* Return oauth access tokens.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAccessToken();
|
||||
|
||||
/**
|
||||
* Set oauth access tokens.
|
||||
*
|
||||
* @param array $tokens
|
||||
*/
|
||||
public function setAccessToken($tokens = []);
|
||||
|
||||
/**
|
||||
* Set http client instance.
|
||||
*
|
||||
* @param HttpClientInterface $httpClient
|
||||
*/
|
||||
public function setHttpClient(HttpClientInterface $httpClient = null);
|
||||
|
||||
/**
|
||||
* Return http client instance.
|
||||
*/
|
||||
public function getHttpClient();
|
||||
|
||||
/**
|
||||
* Set storage instance.
|
||||
*
|
||||
* @param StorageInterface $storage
|
||||
*/
|
||||
public function setStorage(StorageInterface $storage = null);
|
||||
|
||||
/**
|
||||
* Return storage instance.
|
||||
*/
|
||||
public function getStorage();
|
||||
|
||||
/**
|
||||
* Set Logger instance.
|
||||
*
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger = null);
|
||||
|
||||
/**
|
||||
* Return logger instance.
|
||||
*/
|
||||
public function getLogger();
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Adapter;
|
||||
|
||||
/**
|
||||
* Trait DataStoreTrait
|
||||
*/
|
||||
trait DataStoreTrait
|
||||
{
|
||||
/**
|
||||
* Returns storage instance
|
||||
*
|
||||
* @return \Hybridauth\Storage\StorageInterface
|
||||
*/
|
||||
abstract public function getStorage();
|
||||
|
||||
/**
|
||||
* Store a piece of data in storage.
|
||||
*
|
||||
* This method is mainly used for OAuth tokens (access, secret, refresh, and whatnot), but it
|
||||
* can be also used by providers to store any other useful data (i.g., user_id, auth_nonce, etc.)
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
protected function storeData($name, $value = null)
|
||||
{
|
||||
// if empty, we simply delete the thing as we'd want to only store necessary data
|
||||
if (empty($value)) {
|
||||
$this->deleteStoredData($name);
|
||||
}
|
||||
|
||||
$this->getStorage()->set($this->providerId . '.' . $name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a piece of data from storage.
|
||||
*
|
||||
* This method is mainly used for OAuth tokens (access, secret, refresh, and whatnot), but it
|
||||
* can be also used by providers to retrieve from store any other useful data (i.g., user_id,
|
||||
* auth_nonce, etc.)
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getStoredData($name)
|
||||
{
|
||||
return $this->getStorage()->get($this->providerId . '.' . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a stored piece of data.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
protected function deleteStoredData($name)
|
||||
{
|
||||
$this->getStorage()->delete($this->providerId . '.' . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all stored data of the instantiated adapter
|
||||
*/
|
||||
protected function clearStoredData()
|
||||
{
|
||||
$this->getStorage()->deleteMatch($this->providerId . '.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,616 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Adapter;
|
||||
|
||||
use Hybridauth\Exception\Exception;
|
||||
use Hybridauth\Exception\InvalidApplicationCredentialsException;
|
||||
use Hybridauth\Exception\AuthorizationDeniedException;
|
||||
use Hybridauth\Exception\InvalidOauthTokenException;
|
||||
use Hybridauth\Exception\InvalidAccessTokenException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\HttpClient;
|
||||
use Hybridauth\Thirdparty\OAuth\OAuthConsumer;
|
||||
use Hybridauth\Thirdparty\OAuth\OAuthRequest;
|
||||
use Hybridauth\Thirdparty\OAuth\OAuthSignatureMethodHMACSHA1;
|
||||
use Hybridauth\Thirdparty\OAuth\OAuthUtil;
|
||||
|
||||
/**
|
||||
* This class can be used to simplify the authorization flow of OAuth 1 based service providers.
|
||||
*
|
||||
* Subclasses (i.e., providers adapters) can either use the already provided methods or override
|
||||
* them when necessary.
|
||||
*/
|
||||
abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
|
||||
{
|
||||
/**
|
||||
* Base URL to provider API
|
||||
*
|
||||
* This var will be used to build urls when sending signed requests
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $apiBaseUrl = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $authorizeUrl = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $requestTokenUrl = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $accessTokenUrl = '';
|
||||
|
||||
/**
|
||||
* IPD API Documentation
|
||||
*
|
||||
* OPTIONAL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $apiDocumentation = '';
|
||||
|
||||
/**
|
||||
* OAuth Version
|
||||
*
|
||||
* '1.0' OAuth Core 1.0
|
||||
* '1.0a' OAuth Core 1.0 Revision A
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $oauth1Version = '1.0a';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $consumerKey = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $consumerSecret = null;
|
||||
|
||||
/**
|
||||
* @var object
|
||||
*/
|
||||
protected $OAuthConsumer = null;
|
||||
|
||||
/**
|
||||
* @var object
|
||||
*/
|
||||
protected $sha1Method = null;
|
||||
|
||||
/**
|
||||
* @var object
|
||||
*/
|
||||
protected $consumerToken = null;
|
||||
|
||||
/**
|
||||
* Authorization Url Parameters
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $AuthorizeUrlParameters = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $requestTokenMethod = 'POST';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $requestTokenParameters = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $requestTokenHeaders = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tokenExchangeMethod = 'POST';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $tokenExchangeParameters = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $tokenExchangeHeaders = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $apiRequestParameters = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $apiRequestHeaders = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->consumerKey = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
|
||||
$this->consumerSecret = $this->config->filter('keys')->get('secret');
|
||||
|
||||
if (!$this->consumerKey || !$this->consumerSecret) {
|
||||
throw new InvalidApplicationCredentialsException(
|
||||
'Your application id is required in order to connect to ' . $this->providerId
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->config->exists('tokens')) {
|
||||
$this->setAccessToken($this->config->get('tokens'));
|
||||
}
|
||||
|
||||
$this->setCallback($this->config->get('callback'));
|
||||
$this->setApiEndpoints($this->config->get('endpoints'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
/**
|
||||
* Set up OAuth Signature and Consumer
|
||||
*
|
||||
* OAuth Core: All Token requests and Protected Resources requests MUST be signed
|
||||
* by the Consumer and verified by the Service Provider.
|
||||
*
|
||||
* The protocol defines three signature methods: HMAC-SHA1, RSA-SHA1, and PLAINTEXT..
|
||||
*
|
||||
* The Consumer declares a signature method in the oauth_signature_method parameter..
|
||||
*
|
||||
* http://oauth.net/core/1.0a/#signing_process
|
||||
*/
|
||||
$this->sha1Method = new OAuthSignatureMethodHMACSHA1();
|
||||
|
||||
$this->OAuthConsumer = new OAuthConsumer(
|
||||
$this->consumerKey,
|
||||
$this->consumerSecret
|
||||
);
|
||||
|
||||
if ($this->getStoredData('request_token')) {
|
||||
$this->consumerToken = new OAuthConsumer(
|
||||
$this->getStoredData('request_token'),
|
||||
$this->getStoredData('request_token_secret')
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->getStoredData('access_token')) {
|
||||
$this->consumerToken = new OAuthConsumer(
|
||||
$this->getStoredData('access_token'),
|
||||
$this->getStoredData('access_token_secret')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
$this->logger->info(sprintf('%s::authenticate()', get_class($this)));
|
||||
|
||||
if ($this->isConnected()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!$this->getStoredData('request_token')) {
|
||||
// Start a new flow.
|
||||
$this->authenticateBegin();
|
||||
} elseif (empty($_GET['oauth_token']) && empty($_GET['denied'])) {
|
||||
// A previous authentication was not finished, and this request is not finishing it.
|
||||
$this->authenticateBegin();
|
||||
} else {
|
||||
// Finish a flow.
|
||||
$this->authenticateFinish();
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
$this->clearStoredData();
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return (bool)$this->getStoredData('access_token');
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate the authorization protocol
|
||||
*
|
||||
* 1. Obtaining an Unauthorized Request Token
|
||||
* 2. Build Authorization URL for Authorization Request and redirect the user-agent to the
|
||||
* Authorization Server.
|
||||
*/
|
||||
protected function authenticateBegin()
|
||||
{
|
||||
$response = $this->requestAuthToken();
|
||||
|
||||
$this->validateAuthTokenRequest($response);
|
||||
|
||||
$authUrl = $this->getAuthorizeUrl();
|
||||
|
||||
$this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]);
|
||||
|
||||
HttpClient\Util::redirect($authUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize the authorization process
|
||||
*
|
||||
* @throws AuthorizationDeniedException
|
||||
* @throws \Hybridauth\Exception\HttpClientFailureException
|
||||
* @throws \Hybridauth\Exception\HttpRequestFailedException
|
||||
* @throws InvalidAccessTokenException
|
||||
* @throws InvalidOauthTokenException
|
||||
*/
|
||||
protected function authenticateFinish()
|
||||
{
|
||||
$this->logger->debug(
|
||||
sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
|
||||
[HttpClient\Util::getCurrentUrl(true)]
|
||||
);
|
||||
|
||||
$denied = filter_input(INPUT_GET, 'denied');
|
||||
$oauth_problem = filter_input(INPUT_GET, 'oauth_problem');
|
||||
$oauth_token = filter_input(INPUT_GET, 'oauth_token');
|
||||
$oauth_verifier = filter_input(INPUT_GET, 'oauth_verifier');
|
||||
|
||||
if ($denied) {
|
||||
throw new AuthorizationDeniedException(
|
||||
'User denied access request. Provider returned a denied token: ' . htmlentities($denied)
|
||||
);
|
||||
}
|
||||
|
||||
if ($oauth_problem) {
|
||||
throw new InvalidOauthTokenException(
|
||||
'Provider returned an error. oauth_problem: ' . htmlentities($oauth_problem)
|
||||
);
|
||||
}
|
||||
|
||||
if (!$oauth_token) {
|
||||
throw new InvalidOauthTokenException(
|
||||
'Expecting a non-null oauth_token to continue the authorization flow.'
|
||||
);
|
||||
}
|
||||
|
||||
$response = $this->exchangeAuthTokenForAccessToken($oauth_token, $oauth_verifier);
|
||||
|
||||
$this->validateAccessTokenExchange($response);
|
||||
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Authorization URL for Authorization Request
|
||||
*
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getAuthorizeUrl($parameters = [])
|
||||
{
|
||||
$this->AuthorizeUrlParameters = !empty($parameters)
|
||||
? $parameters
|
||||
: array_replace(
|
||||
(array)$this->AuthorizeUrlParameters,
|
||||
(array)$this->config->get('authorize_url_parameters')
|
||||
);
|
||||
|
||||
$this->AuthorizeUrlParameters['oauth_token'] = $this->getStoredData('request_token');
|
||||
|
||||
return $this->authorizeUrl . '?' . http_build_query($this->AuthorizeUrlParameters, '', '&');
|
||||
}
|
||||
|
||||
/**
|
||||
* Unauthorized Request Token
|
||||
*
|
||||
* OAuth Core: The Consumer obtains an unauthorized Request Token by asking the Service Provider
|
||||
* to issue a Token. The Request Token's sole purpose is to receive User approval and can only
|
||||
* be used to obtain an Access Token.
|
||||
*
|
||||
* http://oauth.net/core/1.0/#auth_step1
|
||||
* 6.1.1. Consumer Obtains a Request Token
|
||||
*
|
||||
* @return string Raw Provider API response
|
||||
* @throws \Hybridauth\Exception\HttpClientFailureException
|
||||
* @throws \Hybridauth\Exception\HttpRequestFailedException
|
||||
*/
|
||||
protected function requestAuthToken()
|
||||
{
|
||||
/**
|
||||
* OAuth Core 1.0 Revision A: oauth_callback: An absolute URL to which the Service Provider will redirect
|
||||
* the User back when the Obtaining User Authorization step is completed.
|
||||
*
|
||||
* http://oauth.net/core/1.0a/#auth_step1
|
||||
*/
|
||||
if ('1.0a' == $this->oauth1Version) {
|
||||
$this->requestTokenParameters['oauth_callback'] = $this->callback;
|
||||
}
|
||||
|
||||
$response = $this->oauthRequest(
|
||||
$this->requestTokenUrl,
|
||||
$this->requestTokenMethod,
|
||||
$this->requestTokenParameters,
|
||||
$this->requestTokenHeaders
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Unauthorized Request Token Response
|
||||
*
|
||||
* OAuth Core: The Service Provider verifies the signature and Consumer Key. If successful,
|
||||
* it generates a Request Token and Token Secret and returns them to the Consumer in the HTTP
|
||||
* response body.
|
||||
*
|
||||
* http://oauth.net/core/1.0/#auth_step1
|
||||
* 6.1.2. Service Provider Issues an Unauthorized Request Token
|
||||
*
|
||||
* @param string $response
|
||||
*
|
||||
* @return \Hybridauth\Data\Collection
|
||||
* @throws InvalidOauthTokenException
|
||||
*/
|
||||
protected function validateAuthTokenRequest($response)
|
||||
{
|
||||
/**
|
||||
* The response contains the following parameters:
|
||||
*
|
||||
* - oauth_token The Request Token.
|
||||
* - oauth_token_secret The Token Secret.
|
||||
* - oauth_callback_confirmed MUST be present and set to true.
|
||||
*
|
||||
* http://oauth.net/core/1.0/#auth_step1
|
||||
* 6.1.2. Service Provider Issues an Unauthorized Request Token
|
||||
*
|
||||
* Example of a successful response:
|
||||
*
|
||||
* HTTP/1.1 200 OK
|
||||
* Content-Type: text/html; charset=utf-8
|
||||
* Cache-Control: no-store
|
||||
* Pragma: no-cache
|
||||
*
|
||||
* oauth_token=80359084-clg1DEtxQF3wstTcyUdHF3wsdHM&oauth_token_secret=OIF07hPmJB:P
|
||||
* 6qiHTi1znz6qiH3tTcyUdHnz6qiH3tTcyUdH3xW3wsDvV08e&example_parameter=example_value
|
||||
*
|
||||
* OAuthUtil::parse_parameters will attempt to decode the raw response into an array.
|
||||
*/
|
||||
$tokens = OAuthUtil::parse_parameters($response);
|
||||
|
||||
$collection = new Data\Collection($tokens);
|
||||
|
||||
if (!$collection->exists('oauth_token')) {
|
||||
throw new InvalidOauthTokenException(
|
||||
'Provider returned no oauth_token: ' . htmlentities($response)
|
||||
);
|
||||
}
|
||||
|
||||
$this->consumerToken = new OAuthConsumer(
|
||||
$tokens['oauth_token'],
|
||||
$tokens['oauth_token_secret']
|
||||
);
|
||||
|
||||
$this->storeData('request_token', $tokens['oauth_token']);
|
||||
$this->storeData('request_token_secret', $tokens['oauth_token_secret']);
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests an Access Token
|
||||
*
|
||||
* OAuth Core: The Request Token and Token Secret MUST be exchanged for an Access Token and Token Secret.
|
||||
*
|
||||
* http://oauth.net/core/1.0a/#auth_step3
|
||||
* 6.3.1. Consumer Requests an Access Token
|
||||
*
|
||||
* @param string $oauth_token
|
||||
* @param string $oauth_verifier
|
||||
*
|
||||
* @return string Raw Provider API response
|
||||
* @throws \Hybridauth\Exception\HttpClientFailureException
|
||||
* @throws \Hybridauth\Exception\HttpRequestFailedException
|
||||
*/
|
||||
protected function exchangeAuthTokenForAccessToken($oauth_token, $oauth_verifier = '')
|
||||
{
|
||||
$this->tokenExchangeParameters['oauth_token'] = $oauth_token;
|
||||
|
||||
/**
|
||||
* OAuth Core 1.0 Revision A: oauth_verifier: The verification code received from the Service Provider
|
||||
* in the "Service Provider Directs the User Back to the Consumer" step.
|
||||
*
|
||||
* http://oauth.net/core/1.0a/#auth_step3
|
||||
*/
|
||||
if ('1.0a' == $this->oauth1Version) {
|
||||
$this->tokenExchangeParameters['oauth_verifier'] = $oauth_verifier;
|
||||
}
|
||||
|
||||
$response = $this->oauthRequest(
|
||||
$this->accessTokenUrl,
|
||||
$this->tokenExchangeMethod,
|
||||
$this->tokenExchangeParameters,
|
||||
$this->tokenExchangeHeaders
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Access Token Response
|
||||
*
|
||||
* OAuth Core: If successful, the Service Provider generates an Access Token and Token Secret and returns
|
||||
* them in the HTTP response body.
|
||||
*
|
||||
* The Access Token and Token Secret are stored by the Consumer and used when signing Protected Resources requests.
|
||||
*
|
||||
* http://oauth.net/core/1.0a/#auth_step3
|
||||
* 6.3.2. Service Provider Grants an Access Token
|
||||
*
|
||||
* @param string $response
|
||||
*
|
||||
* @return \Hybridauth\Data\Collection
|
||||
* @throws InvalidAccessTokenException
|
||||
*/
|
||||
protected function validateAccessTokenExchange($response)
|
||||
{
|
||||
/**
|
||||
* The response contains the following parameters:
|
||||
*
|
||||
* - oauth_token The Access Token.
|
||||
* - oauth_token_secret The Token Secret.
|
||||
*
|
||||
* http://oauth.net/core/1.0/#auth_step3
|
||||
* 6.3.2. Service Provider Grants an Access Token
|
||||
*
|
||||
* Example of a successful response:
|
||||
*
|
||||
* HTTP/1.1 200 OK
|
||||
* Content-Type: text/html; charset=utf-8
|
||||
* Cache-Control: no-store
|
||||
* Pragma: no-cache
|
||||
*
|
||||
* oauth_token=sHeLU7Far428zj8PzlWR75&oauth_token_secret=fXb30rzoG&oauth_callback_confirmed=true
|
||||
*
|
||||
* OAuthUtil::parse_parameters will attempt to decode the raw response into an array.
|
||||
*/
|
||||
$tokens = OAuthUtil::parse_parameters($response);
|
||||
|
||||
$collection = new Data\Collection($tokens);
|
||||
|
||||
if (!$collection->exists('oauth_token')) {
|
||||
throw new InvalidAccessTokenException(
|
||||
'Provider returned no access_token: ' . htmlentities($response)
|
||||
);
|
||||
}
|
||||
|
||||
$this->consumerToken = new OAuthConsumer(
|
||||
$collection->get('oauth_token'),
|
||||
$collection->get('oauth_token_secret')
|
||||
);
|
||||
|
||||
$this->storeData('access_token', $collection->get('oauth_token'));
|
||||
$this->storeData('access_token_secret', $collection->get('oauth_token_secret'));
|
||||
|
||||
$this->deleteStoredData('request_token');
|
||||
$this->deleteStoredData('request_token_secret');
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a signed request to provider API
|
||||
*
|
||||
* Note: Since the specifics of error responses is beyond the scope of RFC6749 and OAuth specifications,
|
||||
* Hybridauth will consider any HTTP status code that is different than '200 OK' as an ERROR.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param array $headers
|
||||
* @param bool $multipart
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \Hybridauth\Exception\HttpClientFailureException
|
||||
* @throws \Hybridauth\Exception\HttpRequestFailedException
|
||||
*/
|
||||
public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
|
||||
{
|
||||
// refresh tokens if needed
|
||||
$this->maintainToken();
|
||||
|
||||
if (strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0) {
|
||||
$url = rtrim($this->apiBaseUrl, '/') . '/' . ltrim($url, '/');
|
||||
}
|
||||
|
||||
$parameters = array_replace($this->apiRequestParameters, (array)$parameters);
|
||||
|
||||
$headers = array_replace($this->apiRequestHeaders, (array)$headers);
|
||||
|
||||
$response = $this->oauthRequest($url, $method, $parameters, $headers, $multipart);
|
||||
|
||||
$response = (new Data\Parser())->parse($response);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup and Send a Signed Oauth Request
|
||||
*
|
||||
* This method uses OAuth Library.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param array $headers
|
||||
* @param bool $multipart
|
||||
*
|
||||
* @return string Raw Provider API response
|
||||
* @throws \Hybridauth\Exception\HttpClientFailureException
|
||||
* @throws \Hybridauth\Exception\HttpRequestFailedException
|
||||
*/
|
||||
protected function oauthRequest($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
|
||||
{
|
||||
$signing_parameters = $parameters;
|
||||
if ($multipart) {
|
||||
$signing_parameters = [];
|
||||
}
|
||||
|
||||
$request = OAuthRequest::from_consumer_and_token(
|
||||
$this->OAuthConsumer,
|
||||
$this->consumerToken,
|
||||
$method,
|
||||
$uri,
|
||||
$signing_parameters
|
||||
);
|
||||
|
||||
$request->sign_request(
|
||||
$this->sha1Method,
|
||||
$this->OAuthConsumer,
|
||||
$this->consumerToken
|
||||
);
|
||||
|
||||
$uri = $request->get_normalized_http_url();
|
||||
$headers = array_replace($request->to_header(), (array)$headers);
|
||||
|
||||
$response = $this->httpClient->request(
|
||||
$uri,
|
||||
$method,
|
||||
$parameters,
|
||||
$headers,
|
||||
$multipart
|
||||
);
|
||||
|
||||
$this->validateApiResponse('Signed API request to ' . $uri . ' has returned an error');
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,739 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Adapter;
|
||||
|
||||
use Hybridauth\Exception\Exception;
|
||||
use Hybridauth\Exception\InvalidApplicationCredentialsException;
|
||||
use Hybridauth\Exception\InvalidAuthorizationStateException;
|
||||
use Hybridauth\Exception\InvalidAuthorizationCodeException;
|
||||
use Hybridauth\Exception\AuthorizationDeniedException;
|
||||
use Hybridauth\Exception\InvalidAccessTokenException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\HttpClient;
|
||||
|
||||
/**
|
||||
* This class can be used to simplify the authorization flow of OAuth 2 based service providers.
|
||||
*
|
||||
* Subclasses (i.e., providers adapters) can either use the already provided methods or override
|
||||
* them when necessary.
|
||||
*/
|
||||
abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
|
||||
{
|
||||
/**
|
||||
* Client Identifier
|
||||
*
|
||||
* RFC6749: client_id REQUIRED. The client identifier issued to the client during
|
||||
* the registration process described by Section 2.2.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-2.2
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $clientId = '';
|
||||
|
||||
/**
|
||||
* Client Secret
|
||||
*
|
||||
* RFC6749: client_secret REQUIRED. The client secret. The client MAY omit the
|
||||
* parameter if the client secret is an empty string.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-2.2
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $clientSecret = '';
|
||||
|
||||
/**
|
||||
* Access Token Scope
|
||||
*
|
||||
* RFC6749: The authorization and token endpoints allow the client to specify the
|
||||
* scope of the access request using the "scope" request parameter.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-3.3
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $scope = '';
|
||||
|
||||
/**
|
||||
* Base URL to provider API
|
||||
*
|
||||
* This var will be used to build urls when sending signed requests
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $apiBaseUrl = '';
|
||||
|
||||
/**
|
||||
* Authorization Endpoint
|
||||
*
|
||||
* RFC6749: The authorization endpoint is used to interact with the resource
|
||||
* owner and obtain an authorization grant.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-3.1
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $authorizeUrl = '';
|
||||
|
||||
/**
|
||||
* Access Token Endpoint
|
||||
*
|
||||
* RFC6749: The token endpoint is used by the client to obtain an access token by
|
||||
* presenting its authorization grant or refresh token.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-3.2
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $accessTokenUrl = '';
|
||||
|
||||
/**
|
||||
* TokenInfo endpoint
|
||||
*
|
||||
* Access token validation. OPTIONAL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $accessTokenInfoUrl = '';
|
||||
|
||||
/**
|
||||
* IPD API Documentation
|
||||
*
|
||||
* OPTIONAL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $apiDocumentation = '';
|
||||
|
||||
/**
|
||||
* Redirection Endpoint or Callback
|
||||
*
|
||||
* RFC6749: After completing its interaction with the resource owner, the
|
||||
* authorization server directs the resource owner's user-agent back to
|
||||
* the client.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-3.1.2
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $callback = '';
|
||||
|
||||
/**
|
||||
* Authorization Url Parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $AuthorizeUrlParameters = [];
|
||||
|
||||
|
||||
/**
|
||||
* Authorization Url Parameter encoding type
|
||||
* @see https://www.php.net/manual/de/function.http-build-query.php
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $AuthorizeUrlParametersEncType = PHP_QUERY_RFC1738;
|
||||
|
||||
/**
|
||||
* Authorization Request State
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $supportRequestState = true;
|
||||
|
||||
/**
|
||||
* Access Token name
|
||||
*
|
||||
* While most providers will use 'access_token' as name for the Access Token attribute, other do not.
|
||||
* On the latter case, this should be set by sub classes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $accessTokenName = 'access_token';
|
||||
|
||||
/**
|
||||
* Authorization Request HTTP method.
|
||||
*
|
||||
* @see exchangeCodeForAccessToken()
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tokenExchangeMethod = 'POST';
|
||||
|
||||
/**
|
||||
* Authorization Request URL parameters.
|
||||
*
|
||||
* Sub classes may change add any additional parameter when necessary.
|
||||
*
|
||||
* @see exchangeCodeForAccessToken()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tokenExchangeParameters = [];
|
||||
|
||||
/**
|
||||
* Authorization Request HTTP headers.
|
||||
*
|
||||
* Sub classes may add any additional header when necessary.
|
||||
*
|
||||
* @see exchangeCodeForAccessToken()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tokenExchangeHeaders = [];
|
||||
|
||||
/**
|
||||
* Refresh Token Request HTTP method.
|
||||
*
|
||||
* @see refreshAccessToken()
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tokenRefreshMethod = 'POST';
|
||||
|
||||
/**
|
||||
* Refresh Token Request URL parameters.
|
||||
*
|
||||
* Sub classes may change add any additional parameter when necessary.
|
||||
*
|
||||
* @see refreshAccessToken()
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
protected $tokenRefreshParameters = null;
|
||||
|
||||
/**
|
||||
* Refresh Token Request HTTP headers.
|
||||
*
|
||||
* Sub classes may add any additional header when necessary.
|
||||
*
|
||||
* @see refreshAccessToken()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tokenRefreshHeaders = [];
|
||||
|
||||
/**
|
||||
* Authorization Request URL parameters.
|
||||
*
|
||||
* Sub classes may change add any additional parameter when necessary.
|
||||
*
|
||||
* @see apiRequest()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $apiRequestParameters = [];
|
||||
|
||||
/**
|
||||
* Authorization Request HTTP headers.
|
||||
*
|
||||
* Sub classes may add any additional header when necessary.
|
||||
*
|
||||
* @see apiRequest()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $apiRequestHeaders = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->clientId = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
|
||||
$this->clientSecret = $this->config->filter('keys')->get('secret');
|
||||
|
||||
if (!$this->clientId || !$this->clientSecret) {
|
||||
throw new InvalidApplicationCredentialsException(
|
||||
'Your application id is required in order to connect to ' . $this->providerId
|
||||
);
|
||||
}
|
||||
|
||||
$this->scope = $this->config->exists('scope') ? $this->config->get('scope') : $this->scope;
|
||||
|
||||
if ($this->config->exists('tokens')) {
|
||||
$this->setAccessToken($this->config->get('tokens'));
|
||||
}
|
||||
|
||||
$this->setCallback($this->config->get('callback'));
|
||||
$this->setApiEndpoints($this->config->get('endpoints'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
$this->AuthorizeUrlParameters = [
|
||||
'response_type' => 'code',
|
||||
'client_id' => $this->clientId,
|
||||
'redirect_uri' => $this->callback,
|
||||
'scope' => $this->scope,
|
||||
];
|
||||
|
||||
$this->tokenExchangeParameters = [
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
'grant_type' => 'authorization_code',
|
||||
'redirect_uri' => $this->callback
|
||||
];
|
||||
|
||||
$refreshToken = $this->getStoredData('refresh_token');
|
||||
if (!empty($refreshToken)) {
|
||||
$this->tokenRefreshParameters = [
|
||||
'grant_type' => 'refresh_token',
|
||||
'refresh_token' => $refreshToken,
|
||||
];
|
||||
}
|
||||
|
||||
$this->apiRequestHeaders = [
|
||||
'Authorization' => 'Bearer ' . $this->getStoredData('access_token')
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
$this->logger->info(sprintf('%s::authenticate()', get_class($this)));
|
||||
|
||||
if ($this->isConnected()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->authenticateCheckError();
|
||||
|
||||
$code = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'code');
|
||||
|
||||
if (empty($code)) {
|
||||
$this->authenticateBegin();
|
||||
} else {
|
||||
$this->authenticateFinish();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->clearStoredData();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
if ((bool)$this->getStoredData('access_token')) {
|
||||
return (!$this->hasAccessTokenExpired() || $this->isRefreshTokenAvailable());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we can use a refresh token, then an expired token does not stop us being connected.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isRefreshTokenAvailable()
|
||||
{
|
||||
return is_array($this->tokenRefreshParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorization Request Error Response
|
||||
*
|
||||
* RFC6749: If the request fails due to a missing, invalid, or mismatching
|
||||
* redirection URI, or if the client identifier is missing or invalid,
|
||||
* the authorization server SHOULD inform the resource owner of the error.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*
|
||||
* @throws \Hybridauth\Exception\InvalidAuthorizationCodeException
|
||||
* @throws \Hybridauth\Exception\AuthorizationDeniedException
|
||||
*/
|
||||
protected function authenticateCheckError()
|
||||
{
|
||||
$error = filter_input(INPUT_GET, 'error', FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
|
||||
if (!empty($error)) {
|
||||
$error_description = filter_input(INPUT_GET, 'error_description', FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
$error_uri = filter_input(INPUT_GET, 'error_uri', FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
|
||||
$collated_error = sprintf('Provider returned an error: %s %s %s', $error, $error_description, $error_uri);
|
||||
|
||||
if ($error == 'access_denied') {
|
||||
throw new AuthorizationDeniedException($collated_error);
|
||||
}
|
||||
|
||||
throw new InvalidAuthorizationCodeException($collated_error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate the authorization protocol
|
||||
*
|
||||
* Build Authorization URL for Authorization Request and redirect the user-agent to the
|
||||
* Authorization Server.
|
||||
*/
|
||||
protected function authenticateBegin()
|
||||
{
|
||||
$authUrl = $this->getAuthorizeUrl();
|
||||
|
||||
$this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]);
|
||||
|
||||
HttpClient\Util::redirect($authUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize the authorization process
|
||||
*
|
||||
* @throws \Hybridauth\Exception\HttpClientFailureException
|
||||
* @throws \Hybridauth\Exception\HttpRequestFailedException
|
||||
* @throws InvalidAccessTokenException
|
||||
* @throws InvalidAuthorizationStateException
|
||||
*/
|
||||
protected function authenticateFinish()
|
||||
{
|
||||
$this->logger->debug(
|
||||
sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
|
||||
[HttpClient\Util::getCurrentUrl(true)]
|
||||
);
|
||||
|
||||
$state = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'state');
|
||||
$code = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'code');
|
||||
|
||||
/**
|
||||
* Authorization Request State
|
||||
*
|
||||
* RFC6749: state : RECOMMENDED. An opaque value used by the client to maintain
|
||||
* state between the request and callback. The authorization server includes
|
||||
* this value when redirecting the user-agent back to the client.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-4.1.1
|
||||
*/
|
||||
if ($this->supportRequestState
|
||||
&& $this->getStoredData('authorization_state') != $state
|
||||
) {
|
||||
throw new InvalidAuthorizationStateException(
|
||||
'The authorization state [state=' . substr(htmlentities($state), 0, 100) . '] '
|
||||
. 'of this page is either invalid or has already been consumed.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorization Request Code
|
||||
*
|
||||
* RFC6749: If the resource owner grants the access request, the authorization
|
||||
* server issues an authorization code and delivers it to the client:
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-4.1.2
|
||||
*/
|
||||
$response = $this->exchangeCodeForAccessToken($code);
|
||||
|
||||
$this->validateAccessTokenExchange($response);
|
||||
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Authorization URL for Authorization Request
|
||||
*
|
||||
* RFC6749: The client constructs the request URI by adding the following
|
||||
* $parameters to the query component of the authorization endpoint URI:
|
||||
*
|
||||
* - response_type REQUIRED. Value MUST be set to "code".
|
||||
* - client_id REQUIRED.
|
||||
* - redirect_uri OPTIONAL.
|
||||
* - scope OPTIONAL.
|
||||
* - state RECOMMENDED.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-4.1.1
|
||||
*
|
||||
* Sub classes may redefine this method when necessary.
|
||||
*
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return string Authorization URL
|
||||
*/
|
||||
protected function getAuthorizeUrl($parameters = [])
|
||||
{
|
||||
$this->AuthorizeUrlParameters = !empty($parameters)
|
||||
? $parameters
|
||||
: array_replace(
|
||||
(array)$this->AuthorizeUrlParameters,
|
||||
(array)$this->config->get('authorize_url_parameters')
|
||||
);
|
||||
|
||||
if ($this->supportRequestState) {
|
||||
if (!isset($this->AuthorizeUrlParameters['state'])) {
|
||||
$this->AuthorizeUrlParameters['state'] = 'HA-' . str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890');
|
||||
}
|
||||
|
||||
$this->storeData('authorization_state', $this->AuthorizeUrlParameters['state']);
|
||||
}
|
||||
|
||||
$queryParams = http_build_query($this->AuthorizeUrlParameters, '', '&', $this->AuthorizeUrlParametersEncType);
|
||||
return $this->authorizeUrl . '?' . $queryParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access Token Request
|
||||
*
|
||||
* This method will exchange the received $code in loginFinish() with an Access Token.
|
||||
*
|
||||
* RFC6749: The client makes a request to the token endpoint by sending the
|
||||
* following parameters using the "application/x-www-form-urlencoded"
|
||||
* with a character encoding of UTF-8 in the HTTP request entity-body:
|
||||
*
|
||||
* - grant_type REQUIRED. Value MUST be set to "authorization_code".
|
||||
* - code REQUIRED. The authorization code received from the authorization server.
|
||||
* - redirect_uri REQUIRED.
|
||||
* - client_id REQUIRED.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
*
|
||||
* @param string $code
|
||||
*
|
||||
* @return string Raw Provider API response
|
||||
* @throws \Hybridauth\Exception\HttpClientFailureException
|
||||
* @throws \Hybridauth\Exception\HttpRequestFailedException
|
||||
*/
|
||||
protected function exchangeCodeForAccessToken($code)
|
||||
{
|
||||
$this->tokenExchangeParameters['code'] = $code;
|
||||
|
||||
$response = $this->httpClient->request(
|
||||
$this->accessTokenUrl,
|
||||
$this->tokenExchangeMethod,
|
||||
$this->tokenExchangeParameters,
|
||||
$this->tokenExchangeHeaders
|
||||
);
|
||||
|
||||
$this->validateApiResponse('Unable to exchange code for API access token');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Access Token Response
|
||||
*
|
||||
* RFC6749: If the access token request is valid and authorized, the
|
||||
* authorization server issues an access token and optional refresh token.
|
||||
* If the request client authentication failed or is invalid, the authorization
|
||||
* server returns an error response as described in Section 5.2.
|
||||
*
|
||||
* Example of a successful response:
|
||||
*
|
||||
* HTTP/1.1 200 OK
|
||||
* Content-Type: application/json;charset=UTF-8
|
||||
* Cache-Control: no-store
|
||||
* Pragma: no-cache
|
||||
*
|
||||
* {
|
||||
* "access_token":"2YotnFZFEjr1zCsicMWpAA",
|
||||
* "token_type":"example",
|
||||
* "expires_in":3600,
|
||||
* "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
|
||||
* "example_parameter":"example_value"
|
||||
* }
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-4.1.4
|
||||
*
|
||||
* This method uses Data_Parser to attempt to decodes the raw $response (usually JSON)
|
||||
* into a data collection.
|
||||
*
|
||||
* @param string $response
|
||||
*
|
||||
* @return \Hybridauth\Data\Collection
|
||||
* @throws InvalidAccessTokenException
|
||||
*/
|
||||
protected function validateAccessTokenExchange($response)
|
||||
{
|
||||
$data = (new Data\Parser())->parse($response);
|
||||
|
||||
$collection = new Data\Collection($data);
|
||||
|
||||
if (!$collection->exists('access_token')) {
|
||||
throw new InvalidAccessTokenException(
|
||||
'Provider returned no access_token: ' . htmlentities($response)
|
||||
);
|
||||
}
|
||||
|
||||
$this->storeData('access_token', $collection->get('access_token'));
|
||||
$this->storeData('token_type', $collection->get('token_type'));
|
||||
|
||||
if ($collection->get('refresh_token')) {
|
||||
$this->storeData('refresh_token', $collection->get('refresh_token'));
|
||||
}
|
||||
|
||||
// calculate when the access token expire
|
||||
if ($collection->exists('expires_in')) {
|
||||
$expires_at = time() + (int)$collection->get('expires_in');
|
||||
|
||||
$this->storeData('expires_in', $collection->get('expires_in'));
|
||||
$this->storeData('expires_at', $expires_at);
|
||||
}
|
||||
|
||||
$this->deleteStoredData('authorization_state');
|
||||
|
||||
$this->initialize();
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshing an Access Token
|
||||
*
|
||||
* RFC6749: If the authorization server issued a refresh token to the
|
||||
* client, the client makes a refresh request to the token endpoint by
|
||||
* adding the following parameters ... in the HTTP request entity-body:
|
||||
*
|
||||
* - grant_type REQUIRED. Value MUST be set to "refresh_token".
|
||||
* - refresh_token REQUIRED. The refresh token issued to the client.
|
||||
* - scope OPTIONAL.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-6
|
||||
*
|
||||
* This method is similar to exchangeCodeForAccessToken(). The only
|
||||
* difference is here we exchange refresh_token for a new access_token.
|
||||
*
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return string|null Raw Provider API response, or null if we cannot refresh
|
||||
* @throws \Hybridauth\Exception\HttpClientFailureException
|
||||
* @throws \Hybridauth\Exception\HttpRequestFailedException
|
||||
* @throws InvalidAccessTokenException
|
||||
*/
|
||||
public function refreshAccessToken($parameters = [])
|
||||
{
|
||||
$this->tokenRefreshParameters = !empty($parameters)
|
||||
? $parameters
|
||||
: $this->tokenRefreshParameters;
|
||||
|
||||
if (!$this->isRefreshTokenAvailable()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$response = $this->httpClient->request(
|
||||
$this->accessTokenUrl,
|
||||
$this->tokenRefreshMethod,
|
||||
$this->tokenRefreshParameters,
|
||||
$this->tokenRefreshHeaders
|
||||
);
|
||||
|
||||
$this->validateApiResponse('Unable to refresh the access token');
|
||||
|
||||
$this->validateRefreshAccessToken($response);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether access token has expired
|
||||
*
|
||||
* @param int|null $time
|
||||
* @return bool|null
|
||||
*/
|
||||
public function hasAccessTokenExpired($time = null)
|
||||
{
|
||||
if ($time === null) {
|
||||
$time = time();
|
||||
}
|
||||
|
||||
$expires_at = $this->getStoredData('expires_at');
|
||||
if (!$expires_at) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $expires_at <= $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Refresh Access Token Request
|
||||
*
|
||||
* RFC6749: If valid and authorized, the authorization server issues an
|
||||
* access token as described in Section 5.1. If the request failed
|
||||
* verification or is invalid, the authorization server returns an error
|
||||
* response as described in Section 5.2.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-6
|
||||
* http://tools.ietf.org/html/rfc6749#section-5.1
|
||||
* http://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*
|
||||
* This method simply use validateAccessTokenExchange(), however sub
|
||||
* classes may redefine it when necessary.
|
||||
*
|
||||
* @param $response
|
||||
*
|
||||
* @return \Hybridauth\Data\Collection
|
||||
* @throws InvalidAccessTokenException
|
||||
*/
|
||||
protected function validateRefreshAccessToken($response)
|
||||
{
|
||||
return $this->validateAccessTokenExchange($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a signed request to provider API
|
||||
*
|
||||
* RFC6749: Accessing Protected Resources: The client accesses protected
|
||||
* resources by presenting the access token to the resource server. The
|
||||
* resource server MUST validate the access token and ensure that it has
|
||||
* not expired and that its scope covers the requested resource.
|
||||
*
|
||||
* Note: Since the specifics of error responses is beyond the scope of
|
||||
* RFC6749 and OAuth specifications, Hybridauth will consider any HTTP
|
||||
* status code that is different than '200 OK' as an ERROR.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc6749#section-7
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param array $headers
|
||||
* @param bool $multipart
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \Hybridauth\Exception\HttpClientFailureException
|
||||
* @throws \Hybridauth\Exception\HttpRequestFailedException
|
||||
* @throws InvalidAccessTokenException
|
||||
*/
|
||||
public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
|
||||
{
|
||||
// refresh tokens if needed
|
||||
$this->maintainToken();
|
||||
if ($this->hasAccessTokenExpired() === true) {
|
||||
$this->refreshAccessToken();
|
||||
}
|
||||
|
||||
if (strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0) {
|
||||
$url = rtrim($this->apiBaseUrl, '/') . '/' . ltrim($url, '/');
|
||||
}
|
||||
|
||||
$parameters = array_replace($this->apiRequestParameters, (array)$parameters);
|
||||
$headers = array_replace($this->apiRequestHeaders, (array)$headers);
|
||||
|
||||
$response = $this->httpClient->request(
|
||||
$url,
|
||||
$method, // HTTP Request Method. Defaults to GET.
|
||||
$parameters, // Request Parameters
|
||||
$headers, // Request Headers
|
||||
$multipart // Is request multipart
|
||||
);
|
||||
|
||||
$this->validateApiResponse('Signed API request to ' . $url . ' has returned an error');
|
||||
|
||||
$response = (new Data\Parser())->parse($response);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Adapter;
|
||||
|
||||
use Hybridauth\Exception\InvalidOpenidIdentifierException;
|
||||
use Hybridauth\Exception\AuthorizationDeniedException;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\HttpClient;
|
||||
use Hybridauth\User;
|
||||
use Hybridauth\Thirdparty\OpenID\LightOpenID;
|
||||
|
||||
/**
|
||||
* This class can be used to simplify the authentication flow of OpenID based service providers.
|
||||
*
|
||||
* Subclasses (i.e., providers adapters) can either use the already provided methods or override
|
||||
* them when necessary.
|
||||
*/
|
||||
abstract class OpenID extends AbstractAdapter implements AdapterInterface
|
||||
{
|
||||
/**
|
||||
* LightOpenID instance
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $openIdClient = null;
|
||||
|
||||
/**
|
||||
* Openid provider identifier
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $openidIdentifier = '';
|
||||
|
||||
/**
|
||||
* IPD API Documentation
|
||||
*
|
||||
* OPTIONAL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $apiDocumentation = '';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
if ($this->config->exists('openid_identifier')) {
|
||||
$this->openidIdentifier = $this->config->get('openid_identifier');
|
||||
}
|
||||
|
||||
if (empty($this->openidIdentifier)) {
|
||||
throw new InvalidOpenidIdentifierException('OpenID adapter requires an openid_identifier.', 4);
|
||||
}
|
||||
|
||||
$this->setCallback($this->config->get('callback'));
|
||||
$this->setApiEndpoints($this->config->get('endpoints'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
$hostPort = parse_url($this->callback, PHP_URL_PORT);
|
||||
$hostUrl = parse_url($this->callback, PHP_URL_HOST);
|
||||
|
||||
if ($hostPort) {
|
||||
$hostUrl .= ':' . $hostPort;
|
||||
}
|
||||
|
||||
// @fixme: add proxy
|
||||
$this->openIdClient = new LightOpenID($hostUrl, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
$this->logger->info(sprintf('%s::authenticate()', get_class($this)));
|
||||
|
||||
if ($this->isConnected()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (empty($_REQUEST['openid_mode'])) {
|
||||
$this->authenticateBegin();
|
||||
} else {
|
||||
return $this->authenticateFinish();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return (bool)$this->storage->get($this->providerId . '.user');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
$this->storage->delete($this->providerId . '.user');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate the authorization protocol
|
||||
*
|
||||
* Include and instantiate LightOpenID
|
||||
*/
|
||||
protected function authenticateBegin()
|
||||
{
|
||||
$this->openIdClient->identity = $this->openidIdentifier;
|
||||
$this->openIdClient->returnUrl = $this->callback;
|
||||
$this->openIdClient->required = [
|
||||
'namePerson/first',
|
||||
'namePerson/last',
|
||||
'namePerson/friendly',
|
||||
'namePerson',
|
||||
'contact/email',
|
||||
'birthDate',
|
||||
'birthDate/birthDay',
|
||||
'birthDate/birthMonth',
|
||||
'birthDate/birthYear',
|
||||
'person/gender',
|
||||
'pref/language',
|
||||
'contact/postalCode/home',
|
||||
'contact/city/home',
|
||||
'contact/country/home',
|
||||
|
||||
'media/image/default',
|
||||
];
|
||||
|
||||
$authUrl = $this->openIdClient->authUrl();
|
||||
|
||||
$this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]);
|
||||
|
||||
HttpClient\Util::redirect($authUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize the authorization process.
|
||||
*
|
||||
* @throws AuthorizationDeniedException
|
||||
* @throws UnexpectedApiResponseException
|
||||
*/
|
||||
protected function authenticateFinish()
|
||||
{
|
||||
$this->logger->debug(
|
||||
sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
|
||||
[HttpClient\Util::getCurrentUrl(true)]
|
||||
);
|
||||
|
||||
if ($this->openIdClient->mode == 'cancel') {
|
||||
throw new AuthorizationDeniedException('User has cancelled the authentication.');
|
||||
}
|
||||
|
||||
if (!$this->openIdClient->validate()) {
|
||||
throw new UnexpectedApiResponseException('Invalid response received.');
|
||||
}
|
||||
|
||||
$openidAttributes = $this->openIdClient->getAttributes();
|
||||
|
||||
if (!$this->openIdClient->identity) {
|
||||
throw new UnexpectedApiResponseException('Provider returned an unexpected response.');
|
||||
}
|
||||
|
||||
$userProfile = $this->fetchUserProfile($openidAttributes);
|
||||
|
||||
/* with openid providers we only get user profiles once, so we store it */
|
||||
$this->storage->set($this->providerId . '.user', $userProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch user profile from received openid attributes
|
||||
*
|
||||
* @param array $openidAttributes
|
||||
*
|
||||
* @return User\Profile
|
||||
*/
|
||||
protected function fetchUserProfile($openidAttributes)
|
||||
{
|
||||
$data = new Data\Collection($openidAttributes);
|
||||
|
||||
$userProfile = new User\Profile();
|
||||
|
||||
$userProfile->identifier = $this->openIdClient->identity;
|
||||
|
||||
$userProfile->firstName = $data->get('namePerson/first');
|
||||
$userProfile->lastName = $data->get('namePerson/last');
|
||||
$userProfile->email = $data->get('contact/email');
|
||||
$userProfile->language = $data->get('pref/language');
|
||||
$userProfile->country = $data->get('contact/country/home');
|
||||
$userProfile->zip = $data->get('contact/postalCode/home');
|
||||
$userProfile->gender = $data->get('person/gender');
|
||||
$userProfile->photoURL = $data->get('media/image/default');
|
||||
$userProfile->birthDay = $data->get('birthDate/birthDay');
|
||||
$userProfile->birthMonth = $data->get('birthDate/birthMonth');
|
||||
$userProfile->birthYear = $data->get('birthDate/birthDate');
|
||||
|
||||
$userProfile = $this->fetchUserGender($userProfile, $data->get('person/gender'));
|
||||
|
||||
$userProfile = $this->fetchUserDisplayName($userProfile, $data);
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract users display names
|
||||
*
|
||||
* @param User\Profile $userProfile
|
||||
* @param Data\Collection $data
|
||||
*
|
||||
* @return User\Profile
|
||||
*/
|
||||
protected function fetchUserDisplayName(User\Profile $userProfile, Data\Collection $data)
|
||||
{
|
||||
$userProfile->displayName = $data->get('namePerson');
|
||||
|
||||
$userProfile->displayName = $userProfile->displayName
|
||||
? $userProfile->displayName
|
||||
: $data->get('namePerson/friendly');
|
||||
|
||||
$userProfile->displayName = $userProfile->displayName
|
||||
? $userProfile->displayName
|
||||
: trim($userProfile->firstName . ' ' . $userProfile->lastName);
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract users gender
|
||||
*
|
||||
* @param User\Profile $userProfile
|
||||
* @param string $gender
|
||||
*
|
||||
* @return User\Profile
|
||||
*/
|
||||
protected function fetchUserGender(User\Profile $userProfile, $gender)
|
||||
{
|
||||
$gender = strtolower($gender);
|
||||
|
||||
if ('f' == $gender) {
|
||||
$gender = 'female';
|
||||
}
|
||||
|
||||
if ('m' == $gender) {
|
||||
$gender = 'male';
|
||||
}
|
||||
|
||||
$userProfile->gender = $gender;
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenID only provide the user profile one. This method will attempt to retrieve the profile from storage.
|
||||
*/
|
||||
public function getUserProfile()
|
||||
{
|
||||
$userProfile = $this->storage->get($this->providerId . '.user');
|
||||
|
||||
if (!is_object($userProfile)) {
|
||||
throw new UnexpectedApiResponseException('Provider returned an unexpected response.');
|
||||
}
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Data;
|
||||
|
||||
/**
|
||||
* A very basic Data collection.
|
||||
*/
|
||||
final class Collection
|
||||
{
|
||||
/**
|
||||
* Data collection
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $collection = null;
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function __construct($data = null)
|
||||
{
|
||||
$this->collection = (object)$data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the whole collection as array
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return (array)$this->collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an item
|
||||
*
|
||||
* @param $property
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($property)
|
||||
{
|
||||
if ($this->exists($property)) {
|
||||
return $this->collection->$property;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or update an item
|
||||
*
|
||||
* @param $property
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set($property, $value)
|
||||
{
|
||||
if ($property) {
|
||||
$this->collection->$property = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* .. until I come with a better name..
|
||||
*
|
||||
* @param $property
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function filter($property)
|
||||
{
|
||||
if ($this->exists($property)) {
|
||||
$data = $this->get($property);
|
||||
|
||||
if (!is_a($data, 'Collection')) {
|
||||
$data = new Collection($data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return new Collection([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether an item within the collection
|
||||
*
|
||||
* @param $property
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists($property)
|
||||
{
|
||||
return property_exists($this->collection, $property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds whether the collection is empty
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return !(bool)$this->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count all items in collection
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->properties());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all items properties names
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function properties()
|
||||
{
|
||||
$properties = [];
|
||||
|
||||
foreach ($this->collection as $key => $value) {
|
||||
$properties[] = $key;
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all items values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function values()
|
||||
{
|
||||
$values = [];
|
||||
|
||||
foreach ($this->collection as $value) {
|
||||
$values[] = $value;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Data;
|
||||
|
||||
/**
|
||||
* Parser
|
||||
*
|
||||
* This class is used to parse plain text into objects. It's used by hybriauth adapters to converts
|
||||
* providers api responses to a more 'manageable' format.
|
||||
*/
|
||||
final class Parser
|
||||
{
|
||||
/**
|
||||
* Decodes a string into an object.
|
||||
*
|
||||
* This method will first attempt to parse data as a JSON string (since most providers use this format)
|
||||
* then XML and parse_str.
|
||||
*
|
||||
* @param string $raw
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function parse($raw = null)
|
||||
{
|
||||
$data = $this->parseJson($raw);
|
||||
|
||||
if (!$data) {
|
||||
$data = $this->parseXml($raw);
|
||||
|
||||
if (!$data) {
|
||||
$data = $this->parseQueryString($raw);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a JSON string
|
||||
*
|
||||
* @param $result
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function parseJson($result)
|
||||
{
|
||||
return json_decode($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a XML string
|
||||
*
|
||||
* @param $result
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function parseXml($result)
|
||||
{
|
||||
libxml_use_internal_errors(true);
|
||||
|
||||
$result = preg_replace('/([<\/])([a-z0-9-]+):/i', '$1', $result);
|
||||
$xml = simplexml_load_string($result);
|
||||
|
||||
libxml_use_internal_errors(false);
|
||||
|
||||
if (!$xml) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$arr = json_decode(json_encode((array)$xml), true);
|
||||
$arr = array($xml->getName() => $arr);
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string into variables
|
||||
*
|
||||
* @param $result
|
||||
*
|
||||
* @return \StdClass
|
||||
*/
|
||||
public function parseQueryString($result)
|
||||
{
|
||||
parse_str($result, $output);
|
||||
|
||||
if (!is_array($output)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = new \StdClass();
|
||||
|
||||
foreach ($output as $k => $v) {
|
||||
$result->$k = $v;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* needs to be improved
|
||||
*
|
||||
* @param $birthday
|
||||
* @param $seperator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function parseBirthday($birthday, $seperator)
|
||||
{
|
||||
$birthday = date_parse($birthday);
|
||||
|
||||
return [$birthday['year'], $birthday['month'], $birthday['day']];
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class AuthorizationDeniedException extends UnexpectedValueException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
* BadMethodCallException
|
||||
*
|
||||
* Exception thrown if a callback refers to an undefined method or if some arguments are missing.
|
||||
*/
|
||||
class BadMethodCallException extends RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
* Hybridauth Base Exception
|
||||
*/
|
||||
class Exception extends \Exception implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* Shamelessly Borrowed from Slimframework
|
||||
*
|
||||
* @param $object
|
||||
*/
|
||||
public function debug($object)
|
||||
{
|
||||
$title = 'Hybridauth Exception';
|
||||
$code = $this->getCode();
|
||||
$message = $this->getMessage();
|
||||
$file = $this->getFile();
|
||||
$line = $this->getLine();
|
||||
$trace = $this->getTraceAsString();
|
||||
|
||||
$html = sprintf('<h1>%s</h1>', $title);
|
||||
$html .= '<p>Hybridauth has encountered the following error:</p>';
|
||||
$html .= '<h2>Details</h2>';
|
||||
|
||||
$html .= sprintf('<div><strong>Exception:</strong> %s</div>', get_class($this));
|
||||
|
||||
$html .= sprintf('<div><strong>Message:</strong> <font color="#cc0000">%s</font></div>', $message);
|
||||
|
||||
$html .= sprintf('<div><strong>File:</strong> %s</div>', $file);
|
||||
|
||||
$html .= sprintf('<div><strong>Line:</strong> %s</div>', $line);
|
||||
|
||||
$html .= sprintf('<div><strong>Code:</strong> %s</div>', $code);
|
||||
|
||||
$html .= '<h2>Trace</h2>';
|
||||
$html .= sprintf('<pre>%s</pre>', $trace);
|
||||
|
||||
if ($object) {
|
||||
$html .= '<h2>Debug</h2>';
|
||||
|
||||
$obj_dump = print_r($object, true);
|
||||
|
||||
// phpcs:ignore
|
||||
$html .= sprintf('<b>' . get_class($object) . '</b> extends <b>' . get_parent_class($object) . '</b><pre>%s</pre>', $obj_dump);
|
||||
}
|
||||
|
||||
$html .= '<h2>Session</h2>';
|
||||
|
||||
$session_dump = print_r($_SESSION, true);
|
||||
|
||||
$html .= sprintf('<pre>%s</pre>', $session_dump);
|
||||
|
||||
// phpcs:ignore
|
||||
echo sprintf("<html><head><title>%s</title><style>body{margin:0;padding:30px;font:12px/1.5 Helvetica,Arial,Verdana,sans-serif;}h1{margin:0;font-size:48px;font-weight:normal;line-height:48px;}strong{display:inline-block;width:75px;}</style></head><body>%s</body></html>", $title, $html);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
* Hybridauth Exceptions Interface
|
||||
*/
|
||||
interface ExceptionInterface
|
||||
{
|
||||
/*
|
||||
ExceptionInterface
|
||||
Exception extends \Exception implements ExceptionInterface
|
||||
| RuntimeException extends Exception
|
||||
| | UnexpectedValueException extends RuntimeException
|
||||
| | | AuthorizationDeniedException extends UnexpectedValueException
|
||||
| | | HttpClientFailureException extends UnexpectedValueException
|
||||
| | | HttpRequestFailedException extends UnexpectedValueException
|
||||
| | | InvalidAuthorizationCodeException extends UnexpectedValueException
|
||||
| | | InvalidAuthorizationStateException extends UnexpectedValueException
|
||||
| | | InvalidOauthTokenException extends UnexpectedValueException
|
||||
| | | InvalidAccessTokenException extends UnexpectedValueException
|
||||
| | | UnexpectedApiResponseException extends UnexpectedValueException
|
||||
| |
|
||||
| | BadMethodCallException extends RuntimeException
|
||||
| | | NotImplementedException extends BadMethodCallException
|
||||
| |
|
||||
| | InvalidArgumentException extends RuntimeException
|
||||
| | | InvalidApplicationCredentialsException extends InvalidArgumentException
|
||||
| | | InvalidOpenidIdentifierException extends InvalidArgumentException
|
||||
*/
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class HttpClientFailureException extends UnexpectedValueException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class HttpRequestFailedException extends UnexpectedValueException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class InvalidAccessTokenException extends InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class InvalidApplicationCredentialsException extends InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
* InvalidArgumentException
|
||||
*
|
||||
* Exception thrown if an argument is not of the expected type.
|
||||
*/
|
||||
class InvalidArgumentException extends RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class InvalidAuthorizationCodeException extends InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class InvalidAuthorizationStateException extends InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class InvalidOauthTokenException extends InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class InvalidOpenidIdentifierException extends InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class NotImplementedException extends BadMethodCallException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
* RuntimeException
|
||||
*
|
||||
* Exception thrown if an error which can only be found on runtime occurs.
|
||||
*/
|
||||
class RuntimeException extends Exception implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class UnexpectedApiResponseException extends UnexpectedValueException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Exception;
|
||||
|
||||
/**
|
||||
* UnexpectedValueException
|
||||
*
|
||||
* Exception thrown if a value does not match with a set of values. Typically this happens when a function calls
|
||||
* another function and expects the return value to be of a certain type or value not including arithmetic or
|
||||
* buffer related errors.
|
||||
*/
|
||||
class UnexpectedValueException extends RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,316 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\HttpClient;
|
||||
|
||||
/**
|
||||
* Hybridauth default Http client
|
||||
*/
|
||||
class Curl implements HttpClientInterface
|
||||
{
|
||||
/**
|
||||
* Default curl options
|
||||
*
|
||||
* These defaults options can be overwritten when sending requests.
|
||||
*
|
||||
* See setCurlOptions()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $curlOptions = [
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_CONNECTTIMEOUT => 30,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_SSL_VERIFYHOST => false,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_MAXREDIRS => 5,
|
||||
CURLINFO_HEADER_OUT => true,
|
||||
CURLOPT_ENCODING => 'identity',
|
||||
// phpcs:ignore
|
||||
CURLOPT_USERAGENT => 'Hybridauth, PHP Social Authentication Library (https://github.com/hybridauth/hybridauth)',
|
||||
];
|
||||
|
||||
/**
|
||||
* Method request() arguments
|
||||
*
|
||||
* This is used for debugging.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $requestArguments = [];
|
||||
|
||||
/**
|
||||
* Default request headers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $requestHeader = [
|
||||
'Accept' => '*/*',
|
||||
'Cache-Control' => 'max-age=0',
|
||||
'Connection' => 'keep-alive',
|
||||
'Expect' => '',
|
||||
'Pragma' => '',
|
||||
];
|
||||
|
||||
/**
|
||||
* Raw response returned by server
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $responseBody = '';
|
||||
|
||||
/**
|
||||
* Headers returned in the response
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $responseHeader = [];
|
||||
|
||||
/**
|
||||
* Response HTTP status code
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $responseHttpCode = 0;
|
||||
|
||||
/**
|
||||
* Last curl error number
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $responseClientError = null;
|
||||
|
||||
/**
|
||||
* Information about the last transfer
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $responseClientInfo = [];
|
||||
|
||||
/**
|
||||
* Hybridauth logger instance
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $logger = null;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function request($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
|
||||
{
|
||||
$this->requestHeader = array_replace($this->requestHeader, (array)$headers);
|
||||
|
||||
$this->requestArguments = [
|
||||
'uri' => $uri,
|
||||
'method' => $method,
|
||||
'parameters' => $parameters,
|
||||
'headers' => $this->requestHeader,
|
||||
];
|
||||
|
||||
$curl = curl_init();
|
||||
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
case 'DELETE':
|
||||
unset($this->curlOptions[CURLOPT_POST]);
|
||||
unset($this->curlOptions[CURLOPT_POSTFIELDS]);
|
||||
|
||||
$uri = $uri . (strpos($uri, '?') ? '&' : '?') . http_build_query($parameters);
|
||||
if ($method === 'DELETE') {
|
||||
$this->curlOptions[CURLOPT_CUSTOMREQUEST] = 'DELETE';
|
||||
}
|
||||
break;
|
||||
case 'PUT':
|
||||
case 'POST':
|
||||
case 'PATCH':
|
||||
$body_content = $multipart ? $parameters : http_build_query($parameters);
|
||||
if (isset($this->requestHeader['Content-Type'])
|
||||
&& $this->requestHeader['Content-Type'] == 'application/json'
|
||||
) {
|
||||
$body_content = json_encode($parameters);
|
||||
}
|
||||
|
||||
if ($method === 'POST') {
|
||||
$this->curlOptions[CURLOPT_POST] = true;
|
||||
} else {
|
||||
$this->curlOptions[CURLOPT_CUSTOMREQUEST] = $method;
|
||||
}
|
||||
$this->curlOptions[CURLOPT_POSTFIELDS] = $body_content;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->curlOptions[CURLOPT_URL] = $uri;
|
||||
$this->curlOptions[CURLOPT_HTTPHEADER] = $this->prepareRequestHeaders();
|
||||
$this->curlOptions[CURLOPT_HEADERFUNCTION] = [$this, 'fetchResponseHeader'];
|
||||
|
||||
foreach ($this->curlOptions as $opt => $value) {
|
||||
curl_setopt($curl, $opt, $value);
|
||||
}
|
||||
|
||||
$response = curl_exec($curl);
|
||||
|
||||
$this->responseBody = $response;
|
||||
$this->responseHttpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
$this->responseClientError = curl_error($curl);
|
||||
$this->responseClientInfo = curl_getinfo($curl);
|
||||
|
||||
if ($this->logger) {
|
||||
// phpcs:ignore
|
||||
$this->logger->debug(sprintf('%s::request( %s, %s ), response:', get_class($this), $uri, $method), $this->getResponse());
|
||||
|
||||
if (false === $response) {
|
||||
// phpcs:ignore
|
||||
$this->logger->error(sprintf('%s::request( %s, %s ), error:', get_class($this), $uri, $method), [$this->responseClientError]);
|
||||
}
|
||||
}
|
||||
|
||||
curl_close($curl);
|
||||
|
||||
return $this->responseBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get response details
|
||||
*
|
||||
* @return array Map structure of details
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
$curlOptions = $this->curlOptions;
|
||||
|
||||
$curlOptions[CURLOPT_HEADERFUNCTION] = '*omitted';
|
||||
|
||||
return [
|
||||
'request' => $this->getRequestArguments(),
|
||||
'response' => [
|
||||
'code' => $this->getResponseHttpCode(),
|
||||
'headers' => $this->getResponseHeader(),
|
||||
'body' => $this->getResponseBody(),
|
||||
],
|
||||
'client' => [
|
||||
'error' => $this->getResponseClientError(),
|
||||
'info' => $this->getResponseClientInfo(),
|
||||
'opts' => $curlOptions,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset curl options
|
||||
*
|
||||
* @param array $curlOptions
|
||||
*/
|
||||
public function setCurlOptions($curlOptions)
|
||||
{
|
||||
foreach ($curlOptions as $opt => $value) {
|
||||
$this->curlOptions[$opt] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set logger instance
|
||||
*
|
||||
* @param object $logger
|
||||
*/
|
||||
public function setLogger($logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResponseBody()
|
||||
{
|
||||
return $this->responseBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResponseHeader()
|
||||
{
|
||||
return $this->responseHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResponseHttpCode()
|
||||
{
|
||||
return $this->responseHttpCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResponseClientError()
|
||||
{
|
||||
return $this->responseClientError;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getResponseClientInfo()
|
||||
{
|
||||
return $this->responseClientInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns method request() arguments
|
||||
*
|
||||
* This is used for debugging.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getRequestArguments()
|
||||
{
|
||||
return $this->requestArguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch server response headers
|
||||
*
|
||||
* @param mixed $curl
|
||||
* @param string $header
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function fetchResponseHeader($curl, $header)
|
||||
{
|
||||
$pos = strpos($header, ':');
|
||||
|
||||
if (!empty($pos)) {
|
||||
$key = str_replace('-', '_', strtolower(substr($header, 0, $pos)));
|
||||
|
||||
$value = trim(substr($header, $pos + 2));
|
||||
|
||||
$this->responseHeader[$key] = $value;
|
||||
}
|
||||
|
||||
return strlen($header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert request headers to the expect curl format
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareRequestHeaders()
|
||||
{
|
||||
$headers = [];
|
||||
|
||||
foreach ($this->requestHeader as $header => $value) {
|
||||
$headers[] = trim($header) . ': ' . trim($value);
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\HttpClient;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Exception\ServerException;
|
||||
use GuzzleHttp\Exception\TransferException;
|
||||
|
||||
/**
|
||||
* Hybridauth Guzzle Http client
|
||||
*
|
||||
* Note: This is just a proof of concept. Feel free to improve it.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* <code>
|
||||
* $guzzle = new Hybridauth\HttpClient\Guzzle(new GuzzleHttp\Client(), [
|
||||
* 'verify' => '/path/to/your/certificate.crt',
|
||||
* 'headers' => ['User-Agent' => '..']
|
||||
* // 'proxy' => ...
|
||||
* ]);
|
||||
*
|
||||
* $adapter = new Hybridauth\Provider\Github($config, $guzzle);
|
||||
*
|
||||
* $adapter->authenticate();
|
||||
* </code>
|
||||
*/
|
||||
class Guzzle implements HttpClientInterface
|
||||
{
|
||||
/**
|
||||
* Method request() arguments
|
||||
*
|
||||
* This is used for debugging.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $requestArguments = [];
|
||||
|
||||
/**
|
||||
* Default request headers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $requestHeader = [];
|
||||
|
||||
/**
|
||||
* Raw response returned by server
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $responseBody = '';
|
||||
|
||||
/**
|
||||
* Headers returned in the response
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $responseHeader = [];
|
||||
|
||||
/**
|
||||
* Response HTTP status code
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $responseHttpCode = 0;
|
||||
|
||||
/**
|
||||
* Last curl error number
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $responseClientError = null;
|
||||
|
||||
/**
|
||||
* Information about the last transfer
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $responseClientInfo = [];
|
||||
|
||||
/**
|
||||
* Hybridauth logger instance
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $logger = null;
|
||||
|
||||
/**
|
||||
* GuzzleHttp client
|
||||
*
|
||||
* @var \GuzzleHttp\Client
|
||||
*/
|
||||
protected $client = null;
|
||||
|
||||
/**
|
||||
* ..
|
||||
* @param null $client
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct($client = null, $config = [])
|
||||
{
|
||||
$this->client = $client ? $client : new Client($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function request($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
|
||||
{
|
||||
$this->requestHeader = array_replace($this->requestHeader, (array)$headers);
|
||||
|
||||
$this->requestArguments = [
|
||||
'uri' => $uri,
|
||||
'method' => $method,
|
||||
'parameters' => $parameters,
|
||||
'headers' => $this->requestHeader,
|
||||
];
|
||||
|
||||
$response = null;
|
||||
|
||||
try {
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
case 'DELETE':
|
||||
$response = $this->client->request($method, $uri, [
|
||||
'query' => $parameters,
|
||||
'headers' => $this->requestHeader,
|
||||
]);
|
||||
break;
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
case 'POST':
|
||||
$body_type = $multipart ? 'multipart' : 'form_params';
|
||||
|
||||
if (isset($this->requestHeader['Content-Type'])
|
||||
&& $this->requestHeader['Content-Type'] === 'application/json'
|
||||
) {
|
||||
$body_type = 'json';
|
||||
}
|
||||
|
||||
$body_content = $parameters;
|
||||
if ($multipart) {
|
||||
$body_content = [];
|
||||
foreach ($parameters as $key => $val) {
|
||||
if ($val instanceof \CURLFile) {
|
||||
$val = fopen($val->getFilename(), 'r');
|
||||
}
|
||||
|
||||
$body_content[] = [
|
||||
'name' => $key,
|
||||
'contents' => $val,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$response = $this->client->request($method, $uri, [
|
||||
$body_type => $body_content,
|
||||
'headers' => $this->requestHeader,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$response = $e->getResponse();
|
||||
|
||||
$this->responseClientError = $e->getMessage();
|
||||
}
|
||||
|
||||
if (!$this->responseClientError) {
|
||||
$this->responseBody = $response->getBody();
|
||||
$this->responseHttpCode = $response->getStatusCode();
|
||||
$this->responseHeader = $response->getHeaders();
|
||||
}
|
||||
|
||||
if ($this->logger) {
|
||||
// phpcs:ignore
|
||||
$this->logger->debug(sprintf('%s::request( %s, %s ), response:', get_class($this), $uri, $method), $this->getResponse());
|
||||
|
||||
if ($this->responseClientError) {
|
||||
// phpcs:ignore
|
||||
$this->logger->error(sprintf('%s::request( %s, %s ), error:', get_class($this), $uri, $method), [$this->responseClientError]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->responseBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get response details
|
||||
*
|
||||
* @return array Map structure of details
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return [
|
||||
'request' => $this->getRequestArguments(),
|
||||
'response' => [
|
||||
'code' => $this->getResponseHttpCode(),
|
||||
'headers' => $this->getResponseHeader(),
|
||||
'body' => $this->getResponseBody(),
|
||||
],
|
||||
'client' => [
|
||||
'error' => $this->getResponseClientError(),
|
||||
'info' => $this->getResponseClientInfo(),
|
||||
'opts' => null,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set logger instance
|
||||
*
|
||||
* @param object $logger
|
||||
*/
|
||||
public function setLogger($logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResponseBody()
|
||||
{
|
||||
return $this->responseBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResponseHeader()
|
||||
{
|
||||
return $this->responseHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResponseHttpCode()
|
||||
{
|
||||
return $this->responseHttpCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResponseClientError()
|
||||
{
|
||||
return $this->responseClientError;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getResponseClientInfo()
|
||||
{
|
||||
return $this->responseClientInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns method request() arguments
|
||||
*
|
||||
* This is used for debugging.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getRequestArguments()
|
||||
{
|
||||
return $this->requestArguments;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\HttpClient;
|
||||
|
||||
/**
|
||||
* Hybridauth Http clients interface
|
||||
*/
|
||||
interface HttpClientInterface
|
||||
{
|
||||
/**
|
||||
* Send request to the remote server
|
||||
*
|
||||
* Returns the result (Raw response from the server) on success, FALSE on failure
|
||||
*
|
||||
* @param string $uri
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param array $headers
|
||||
* @param bool $multipart
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function request($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false);
|
||||
|
||||
/**
|
||||
* Returns raw response from the server on success, FALSE on failure
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResponseBody();
|
||||
|
||||
/**
|
||||
* Retriever the headers returned in the response
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getResponseHeader();
|
||||
|
||||
/**
|
||||
* Returns latest request HTTP status code
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getResponseHttpCode();
|
||||
|
||||
/**
|
||||
* Returns latest error encountered by the client
|
||||
* This can be either a code or error message
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResponseClientError();
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\HttpClient;
|
||||
|
||||
use Hybridauth\Data;
|
||||
|
||||
/**
|
||||
* HttpClient\Util home to a number of utility functions.
|
||||
*/
|
||||
class Util
|
||||
{
|
||||
/**
|
||||
* Redirect handler.
|
||||
*
|
||||
* @var callable|null
|
||||
*/
|
||||
protected static $redirectHandler;
|
||||
|
||||
/**
|
||||
* Exit handler.
|
||||
*
|
||||
* @var callable|null
|
||||
*/
|
||||
protected static $exitHandler;
|
||||
|
||||
/**
|
||||
* Redirect to a given URL.
|
||||
*
|
||||
* In case your application need to perform certain required actions before Hybridauth redirect users
|
||||
* to IDPs websites, the default behaviour can be altered in one of two ways:
|
||||
* If callable $redirectHandler is defined, it will be called instead.
|
||||
* If callable $exitHandler is defined, it will be called instead of exit().
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function redirect($url)
|
||||
{
|
||||
if (static::$redirectHandler) {
|
||||
return call_user_func(static::$redirectHandler, $url);
|
||||
}
|
||||
|
||||
header(sprintf('Location: %s', $url));
|
||||
|
||||
if (static::$exitHandler) {
|
||||
return call_user_func(static::$exitHandler);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect handler to which the regular redirect() will yield the action of redirecting users.
|
||||
*
|
||||
* @param callable $callback
|
||||
*/
|
||||
public static function setRedirectHandler($callback)
|
||||
{
|
||||
self::$redirectHandler = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit handler will be called instead of regular exit() when calling Util::redirect() method.
|
||||
*
|
||||
* @param callable $callback
|
||||
*/
|
||||
public static function setExitHandler($callback)
|
||||
{
|
||||
self::$exitHandler = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Current URL.
|
||||
*
|
||||
* @param bool $requestUri TRUE to use $_SERVER['REQUEST_URI'], FALSE for $_SERVER['PHP_SELF']
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getCurrentUrl($requestUri = false)
|
||||
{
|
||||
$collection = new Data\Collection($_SERVER);
|
||||
|
||||
$protocol = 'http://';
|
||||
|
||||
if (($collection->get('HTTPS') && $collection->get('HTTPS') !== 'off') ||
|
||||
$collection->get('HTTP_X_FORWARDED_PROTO') === 'https') {
|
||||
$protocol = 'https://';
|
||||
}
|
||||
|
||||
return $protocol .
|
||||
$collection->get('HTTP_HOST') .
|
||||
$collection->get($requestUri ? 'REQUEST_URI' : 'PHP_SELF');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth;
|
||||
|
||||
use Hybridauth\Exception\InvalidArgumentException;
|
||||
use Hybridauth\Exception\UnexpectedValueException;
|
||||
use Hybridauth\Storage\StorageInterface;
|
||||
use Hybridauth\Logger\LoggerInterface;
|
||||
use Hybridauth\Logger\Logger;
|
||||
use Hybridauth\HttpClient\HttpClientInterface;
|
||||
|
||||
/**
|
||||
* Hybridauth\Hybridauth
|
||||
*
|
||||
* For ease of use of multiple providers, Hybridauth implements the class Hybridauth\Hybridauth,
|
||||
* a sort of factory/façade which acts as an unified interface or entry point, and it expects a
|
||||
* configuration array containing the list of providers you want to use, their respective credentials
|
||||
* and authorized callback.
|
||||
*/
|
||||
class Hybridauth
|
||||
{
|
||||
/**
|
||||
* Hybridauth config.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Storage.
|
||||
*
|
||||
* @var StorageInterface
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* HttpClient.
|
||||
*
|
||||
* @var HttpClientInterface
|
||||
*/
|
||||
protected $httpClient;
|
||||
|
||||
/**
|
||||
* Logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* @param array|string $config Array with configuration or Path to PHP file that will return array
|
||||
* @param HttpClientInterface $httpClient
|
||||
* @param StorageInterface $storage
|
||||
* @param LoggerInterface $logger
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
$config,
|
||||
HttpClientInterface $httpClient = null,
|
||||
StorageInterface $storage = null,
|
||||
LoggerInterface $logger = null
|
||||
) {
|
||||
if (is_string($config) && file_exists($config)) {
|
||||
$config = include $config;
|
||||
} elseif (!is_array($config)) {
|
||||
throw new InvalidArgumentException('Hybridauth config does not exist on the given path.');
|
||||
}
|
||||
|
||||
$this->config = $config + [
|
||||
'debug_mode' => Logger::NONE,
|
||||
'debug_file' => '',
|
||||
'curl_options' => null,
|
||||
'providers' => []
|
||||
];
|
||||
$this->storage = $storage;
|
||||
$this->logger = $logger;
|
||||
$this->httpClient = $httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate the given provider and authentication or authorization protocol.
|
||||
*
|
||||
* If not authenticated yet, the user will be redirected to the provider's site for
|
||||
* authentication/authorisation, otherwise it will simply return an instance of
|
||||
* provider's adapter.
|
||||
*
|
||||
* @param string $name adapter's name (case insensitive)
|
||||
*
|
||||
* @return \Hybridauth\Adapter\AdapterInterface
|
||||
* @throws InvalidArgumentException
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
public function authenticate($name)
|
||||
{
|
||||
$adapter = $this->getAdapter($name);
|
||||
|
||||
$adapter->authenticate();
|
||||
|
||||
return $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance of a provider's adapter by name
|
||||
*
|
||||
* @param string $name adapter's name (case insensitive)
|
||||
*
|
||||
* @return \Hybridauth\Adapter\AdapterInterface
|
||||
* @throws InvalidArgumentException
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
public function getAdapter($name)
|
||||
{
|
||||
$config = $this->getProviderConfig($name);
|
||||
|
||||
$adapter = isset($config['adapter']) ? $config['adapter'] : sprintf('Hybridauth\\Provider\\%s', $name);
|
||||
|
||||
if (!class_exists($adapter)) {
|
||||
$adapter = null;
|
||||
$fs = new \FilesystemIterator(__DIR__ . '/Provider/');
|
||||
/** @var \SplFileInfo $file */
|
||||
foreach ($fs as $file) {
|
||||
if (!$file->isDir()) {
|
||||
$provider = strtok($file->getFilename(), '.');
|
||||
if ($name === mb_strtolower($provider)) {
|
||||
$adapter = sprintf('Hybridauth\\Provider\\%s', $provider);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($adapter === null) {
|
||||
throw new InvalidArgumentException('Unknown Provider.');
|
||||
}
|
||||
}
|
||||
|
||||
return new $adapter($config, $this->httpClient, $this->storage, $this->logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get provider config by name.
|
||||
*
|
||||
* @param string $name adapter's name (case insensitive)
|
||||
*
|
||||
* @throws UnexpectedValueException
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProviderConfig($name)
|
||||
{
|
||||
$name = strtolower($name);
|
||||
|
||||
$providersConfig = array_change_key_case($this->config['providers'], CASE_LOWER);
|
||||
|
||||
if (!isset($providersConfig[$name])) {
|
||||
throw new InvalidArgumentException('Unknown Provider.');
|
||||
}
|
||||
|
||||
if (!$providersConfig[$name]['enabled']) {
|
||||
throw new UnexpectedValueException('Disabled Provider.');
|
||||
}
|
||||
|
||||
$config = $providersConfig[$name];
|
||||
$config += [
|
||||
'debug_mode' => $this->config['debug_mode'],
|
||||
'debug_file' => $this->config['debug_file'],
|
||||
];
|
||||
|
||||
if (!isset($config['callback']) && isset($this->config['callback'])) {
|
||||
$config['callback'] = $this->config['callback'];
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean of whether the user is connected with a provider
|
||||
*
|
||||
* @param string $name adapter's name (case insensitive)
|
||||
*
|
||||
* @return bool
|
||||
* @throws InvalidArgumentException
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
public function isConnectedWith($name)
|
||||
{
|
||||
return $this->getAdapter($name)->isConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of enabled adapters names
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProviders()
|
||||
{
|
||||
$providers = [];
|
||||
|
||||
foreach ($this->config['providers'] as $name => $config) {
|
||||
if ($config['enabled']) {
|
||||
$providers[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of currently connected adapters names
|
||||
*
|
||||
* @return array
|
||||
* @throws InvalidArgumentException
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
public function getConnectedProviders()
|
||||
{
|
||||
$providers = [];
|
||||
|
||||
foreach ($this->getProviders() as $name) {
|
||||
if ($this->isConnectedWith($name)) {
|
||||
$providers[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of new instances of currently connected adapters
|
||||
*
|
||||
* @return \Hybridauth\Adapter\AdapterInterface[]
|
||||
* @throws InvalidArgumentException
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
public function getConnectedAdapters()
|
||||
{
|
||||
$adapters = [];
|
||||
|
||||
foreach ($this->getProviders() as $name) {
|
||||
$adapter = $this->getAdapter($name);
|
||||
|
||||
if ($adapter->isConnected()) {
|
||||
$adapters[$name] = $adapter;
|
||||
}
|
||||
}
|
||||
|
||||
return $adapters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect all currently connected adapters at once
|
||||
*/
|
||||
public function disconnectAllAdapters()
|
||||
{
|
||||
foreach ($this->getProviders() as $name) {
|
||||
$adapter = $this->getAdapter($name);
|
||||
|
||||
if ($adapter->isConnected()) {
|
||||
$adapter->disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Logger;
|
||||
|
||||
use Hybridauth\Exception\RuntimeException;
|
||||
use Hybridauth\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Debugging and Logging utility.
|
||||
*/
|
||||
class Logger implements LoggerInterface
|
||||
{
|
||||
const NONE = 'none'; // turn logging off
|
||||
const DEBUG = 'debug'; // debug, info and error messages
|
||||
const INFO = 'info'; // info and error messages
|
||||
const ERROR = 'error'; // only error messages
|
||||
|
||||
/**
|
||||
* Debug level.
|
||||
*
|
||||
* One of Logger::NONE, Logger::DEBUG, Logger::INFO, Logger::ERROR
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $level;
|
||||
|
||||
/**
|
||||
* Path to file writeable by the web server. Required if $this->level !== Logger::NONE.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* @param bool|string $level One of Logger::NONE, Logger::DEBUG, Logger::INFO, Logger::ERROR
|
||||
* @param string $file File where to write messages
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function __construct($level, $file)
|
||||
{
|
||||
$this->level = self::NONE;
|
||||
|
||||
if ($level && $level !== self::NONE) {
|
||||
$this->initialize($file);
|
||||
|
||||
$this->level = $level === true ? Logger::DEBUG : $level;
|
||||
$this->file = $file;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function initialize($file)
|
||||
{
|
||||
if (!$file) {
|
||||
throw new InvalidArgumentException('Log file is not specified.');
|
||||
}
|
||||
|
||||
if (!file_exists($file) && !touch($file)) {
|
||||
throw new RuntimeException(sprintf('Log file %s can not be created.', $file));
|
||||
}
|
||||
|
||||
if (!is_writable($file)) {
|
||||
throw new RuntimeException(sprintf('Log file %s is not writeable.', $file));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function info($message, array $context = [])
|
||||
{
|
||||
if (!in_array($this->level, [self::DEBUG, self::INFO])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->log(self::INFO, $message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function debug($message, array $context = [])
|
||||
{
|
||||
if (!in_array($this->level, [self::DEBUG])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->log(self::DEBUG, $message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function error($message, array $context = [])
|
||||
{
|
||||
if (!in_array($this->level, [self::DEBUG, self::INFO, self::ERROR])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->log(self::ERROR, $message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function log($level, $message, array $context = [])
|
||||
{
|
||||
$datetime = new \DateTime();
|
||||
$datetime = $datetime->format(DATE_ATOM);
|
||||
|
||||
$content = sprintf('%s -- %s -- %s -- %s', $level, $_SERVER['REMOTE_ADDR'], $datetime, $message);
|
||||
$content .= ($context ? "\n" . print_r($context, true) : '');
|
||||
$content .= "\n";
|
||||
|
||||
file_put_contents($this->file, $content, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Logger;
|
||||
|
||||
/**
|
||||
* Logger interface, forward-compatible with PSR-3.
|
||||
*/
|
||||
interface LoggerInterface
|
||||
{
|
||||
/**
|
||||
* Interesting events.
|
||||
*
|
||||
* Example: User logs in, SQL logs.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
*/
|
||||
public function info($message, array $context = array());
|
||||
|
||||
/**
|
||||
* Detailed debug information.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
*/
|
||||
public function debug($message, array $context = array());
|
||||
|
||||
/**
|
||||
* Runtime errors that do not require immediate action but should typically
|
||||
* be logged and monitored.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
*/
|
||||
public function error($message, array $context = array());
|
||||
|
||||
/**
|
||||
* Logs with an arbitrary level.
|
||||
*
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
*/
|
||||
public function log($level, $message, array $context = array());
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Logger;
|
||||
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
|
||||
/**
|
||||
* Wrapper for PSR3 logger.
|
||||
*/
|
||||
class Psr3LoggerWrapper implements LoggerInterface
|
||||
{
|
||||
use LoggerAwareTrait;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function info($message, array $context = [])
|
||||
{
|
||||
$this->logger->info($message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function debug($message, array $context = [])
|
||||
{
|
||||
$this->logger->debug($message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function error($message, array $context = [])
|
||||
{
|
||||
$this->logger->error($message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function log($level, $message, array $context = [])
|
||||
{
|
||||
$this->logger->log($level, $message, $context);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Adapter\OpenID;
|
||||
|
||||
/**
|
||||
* AOL OpenID provider adapter.
|
||||
*/
|
||||
class AOLOpenID extends OpenID
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $openidIdentifier = 'http://openid.aol.com/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiDocumentation = ''; // Not available
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2019 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Adapter\OAuth2;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\User;
|
||||
|
||||
/**
|
||||
* Amazon OAuth2 provider adapter.
|
||||
*/
|
||||
class Amazon extends OAuth2
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $scope = 'profile';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiBaseUrl = 'https://api.amazon.com/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $authorizeUrl = 'https://www.amazon.com/ap/oa';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $accessTokenUrl = 'https://api.amazon.com/auth/o2/token';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiDocumentation = 'https://developer.amazon.com/docs/login-with-amazon/documentation-overview.html';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
if ($this->isRefreshTokenAvailable()) {
|
||||
$this->tokenRefreshParameters += [
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUserProfile()
|
||||
{
|
||||
$response = $this->apiRequest('user/profile');
|
||||
|
||||
$data = new Data\Collection($response);
|
||||
|
||||
if (!$data->exists('user_id')) {
|
||||
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
|
||||
}
|
||||
|
||||
$userProfile = new User\Profile();
|
||||
|
||||
$userProfile->identifier = $data->get('user_id');
|
||||
$userProfile->displayName = $data->get('name');
|
||||
$userProfile->email = $data->get('email');
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2020 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Exception\InvalidArgumentException;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Exception\InvalidApplicationCredentialsException;
|
||||
use Hybridauth\Exception\UnexpectedValueException;
|
||||
|
||||
use Hybridauth\Adapter\OAuth2;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\User;
|
||||
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
use \Firebase\JWT\JWT;
|
||||
use \Firebase\JWT\JWK;
|
||||
|
||||
/**
|
||||
* Apple OAuth2 provider adapter.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* $config = [
|
||||
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
|
||||
* 'keys' => ['id' => '', 'team_id' => '', 'key_id' => '', 'key_file' => '', 'key_content' => ''],
|
||||
* 'scope' => 'name email',
|
||||
*
|
||||
* // Apple's custom auth url params
|
||||
* 'authorize_url_parameters' => [
|
||||
* 'response_mode' => 'form_post'
|
||||
* ]
|
||||
* ];
|
||||
*
|
||||
* $adapter = new Hybridauth\Provider\Apple($config);
|
||||
*
|
||||
* try {
|
||||
* $adapter->authenticate();
|
||||
*
|
||||
* $userProfile = $adapter->getUserProfile();
|
||||
* $tokens = $adapter->getAccessToken();
|
||||
* $response = $adapter->setUserStatus("Hybridauth test message..");
|
||||
* } catch (\Exception $e) {
|
||||
* echo $e->getMessage() ;
|
||||
* }
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* composer require codercat/jwk-to-pem
|
||||
* composer require firebase/php-jwt
|
||||
*
|
||||
* @see https://github.com/sputnik73/hybridauth-sign-in-with-apple
|
||||
* @see https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api
|
||||
*/
|
||||
class Apple extends OAuth2
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $scope = 'name email';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiBaseUrl = 'https://appleid.apple.com/auth/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $authorizeUrl = 'https://appleid.apple.com/auth/authorize';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $accessTokenUrl = 'https://appleid.apple.com/auth/token';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiDocumentation = 'https://developer.apple.com/documentation/sign_in_with_apple';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* The Sign in with Apple servers require percent encoding (or URL encoding)
|
||||
* for its query parameters. If you are using the Sign in with Apple REST API,
|
||||
* you must provide values with encoded spaces (`%20`) instead of plus (`+`) signs.
|
||||
*/
|
||||
protected $AuthorizeUrlParametersEncType = PHP_QUERY_RFC3986;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
$this->AuthorizeUrlParameters['response_mode'] = 'form_post';
|
||||
|
||||
if ($this->isRefreshTokenAvailable()) {
|
||||
$this->tokenRefreshParameters += [
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$keys = $this->config->get('keys');
|
||||
$keys['secret'] = $this->getSecret();
|
||||
$this->config->set('keys', $keys);
|
||||
return parent::configure();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* include id_token $tokenNames
|
||||
*/
|
||||
public function getAccessToken()
|
||||
{
|
||||
$tokenNames = [
|
||||
'access_token',
|
||||
'id_token',
|
||||
'access_token_secret',
|
||||
'token_type',
|
||||
'refresh_token',
|
||||
'expires_in',
|
||||
'expires_at',
|
||||
];
|
||||
|
||||
$tokens = [];
|
||||
|
||||
foreach ($tokenNames as $name) {
|
||||
if ($this->getStoredData($name)) {
|
||||
$tokens[$name] = $this->getStoredData($name);
|
||||
}
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function validateAccessTokenExchange($response)
|
||||
{
|
||||
$collection = parent::validateAccessTokenExchange($response);
|
||||
|
||||
$this->storeData('id_token', $collection->get('id_token'));
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
public function getUserProfile()
|
||||
{
|
||||
$id_token = $this->getStoredData('id_token');
|
||||
|
||||
$verifyTokenSignature =
|
||||
$this->config->exists('verifyTokenSignature') ? $this->config->get('verifyTokenSignature') : true;
|
||||
|
||||
if (!$verifyTokenSignature) {
|
||||
// payload extraction by https://github.com/omidborjian
|
||||
// https://github.com/hybridauth/hybridauth/issues/1095#issuecomment-626479263
|
||||
// JWT splits the string to 3 components 1) first is header 2) is payload 3) is signature
|
||||
$payload = explode('.', $id_token)[1];
|
||||
$payload = json_decode(base64_decode($payload));
|
||||
} else {
|
||||
// validate the token signature and get the payload
|
||||
$publicKeys = $this->apiRequest('keys');
|
||||
|
||||
\Firebase\JWT\JWT::$leeway = 120;
|
||||
|
||||
$error = false;
|
||||
$payload = null;
|
||||
|
||||
foreach ($publicKeys->keys as $publicKey) {
|
||||
try {
|
||||
$rsa = new RSA();
|
||||
$jwk = (array)$publicKey;
|
||||
|
||||
$rsa->loadKey(
|
||||
[
|
||||
'e' => new BigInteger(base64_decode($jwk['e']), 256),
|
||||
'n' => new BigInteger(base64_decode(strtr($jwk['n'], '-_', '+/'), true), 256)
|
||||
]
|
||||
);
|
||||
$pem = $rsa->getPublicKey();
|
||||
|
||||
$payload = JWT::decode($id_token, $pem, ['RS256']);
|
||||
break;
|
||||
} catch (\Exception $e) {
|
||||
$error = $e->getMessage();
|
||||
if ($e instanceof \Firebase\JWT\ExpiredException) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($error && !$payload) {
|
||||
throw new \Exception($error);
|
||||
}
|
||||
}
|
||||
|
||||
$data = new Data\Collection($payload);
|
||||
|
||||
if (!$data->exists('sub')) {
|
||||
throw new UnexpectedValueException('Missing token payload.');
|
||||
}
|
||||
|
||||
$userProfile = new User\Profile();
|
||||
$userProfile->identifier = $data->get('sub');
|
||||
$userProfile->email = $data->get('email');
|
||||
$this->storeData('expires_at', $data->get('exp'));
|
||||
|
||||
if (!empty($_REQUEST['user'])) {
|
||||
$objUser = json_decode($_REQUEST['user']);
|
||||
$user = new Data\Collection($objUser);
|
||||
if (!$user->isEmpty()) {
|
||||
$name = $user->get('name');
|
||||
$userProfile->firstName = $name->firstName;
|
||||
$userProfile->lastName = $name->lastName;
|
||||
$userProfile->displayName = join(' ', [$userProfile->firstName, $userProfile->lastName]);
|
||||
}
|
||||
}
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string secret token
|
||||
*/
|
||||
private function getSecret()
|
||||
{
|
||||
// Your 10-character Team ID
|
||||
if (!$team_id = $this->config->filter('keys')->get('team_id')) {
|
||||
throw new InvalidApplicationCredentialsException(
|
||||
'Missing parameter team_id: your team id is required to generate the JWS token.'
|
||||
);
|
||||
}
|
||||
|
||||
// Your Services ID, e.g. com.aaronparecki.services
|
||||
if (!$client_id = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key')) {
|
||||
throw new InvalidApplicationCredentialsException(
|
||||
'Missing parameter id: your client id is required to generate the JWS token.'
|
||||
);
|
||||
}
|
||||
|
||||
// Find the 10-char Key ID value from the portal
|
||||
if (!$key_id = $this->config->filter('keys')->get('key_id')) {
|
||||
throw new InvalidApplicationCredentialsException(
|
||||
'Missing parameter key_id: your key id is required to generate the JWS token.'
|
||||
);
|
||||
}
|
||||
|
||||
// Find the 10-char Key ID value from the portal
|
||||
$key_content = $this->config->filter('keys')->get('key_content');
|
||||
|
||||
// Save your private key from Apple in a file called `key.txt`
|
||||
if (!$key_content) {
|
||||
if (!$key_file = $this->config->filter('keys')->get('key_file')) {
|
||||
throw new InvalidApplicationCredentialsException(
|
||||
'Missing parameter key_content or key_file: your key is required to generate the JWS token.'
|
||||
);
|
||||
}
|
||||
|
||||
if (!file_exists($key_file)) {
|
||||
throw new InvalidApplicationCredentialsException(
|
||||
"Your key file $key_file does not exist."
|
||||
);
|
||||
}
|
||||
|
||||
$key_content = file_get_contents($key_file);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'iat' => time(),
|
||||
'exp' => time() + 86400 * 180,
|
||||
'iss' => $team_id,
|
||||
'aud' => 'https://appleid.apple.com',
|
||||
'sub' => $client_id
|
||||
];
|
||||
|
||||
$secret = JWT::encode($data, $key_content, 'ES256', $key_id);
|
||||
|
||||
return $secret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Adapter\OAuth2;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\User;
|
||||
|
||||
/**
|
||||
* Authentiq OAuth2 provider adapter.
|
||||
*/
|
||||
class Authentiq extends OAuth2
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $scope = 'aq:name email~rs aq:push openid';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiBaseUrl = 'https://connect.authentiq.io/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $authorizeUrl = 'https://connect.authentiq.io/authorize';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $accessTokenUrl = 'https://connect.authentiq.io/token';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiDocumentation = 'http://developers.authentiq.io/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
$this->AuthorizeUrlParameters += [
|
||||
'prompt' => 'consent'
|
||||
];
|
||||
|
||||
$this->tokenExchangeHeaders = [
|
||||
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
|
||||
];
|
||||
|
||||
$this->tokenRefreshHeaders = [
|
||||
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUserProfile()
|
||||
{
|
||||
$response = $this->apiRequest('userinfo');
|
||||
|
||||
$data = new Data\Collection($response);
|
||||
|
||||
if (!$data->exists('sub')) {
|
||||
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
|
||||
}
|
||||
|
||||
$userProfile = new User\Profile();
|
||||
|
||||
$userProfile->identifier = $data->get('sub');
|
||||
|
||||
$userProfile->displayName = $data->get('name');
|
||||
$userProfile->firstName = $data->get('given_name');
|
||||
// $userProfile->middleName = $data->get('middle_name'); // not supported
|
||||
$userProfile->lastName = $data->get('family_name');
|
||||
|
||||
if (!empty($userProfile->displayName)) {
|
||||
$userProfile->displayName = join(' ', array($userProfile->firstName,
|
||||
// $userProfile->middleName,
|
||||
$userProfile->lastName));
|
||||
}
|
||||
|
||||
$userProfile->email = $data->get('email');
|
||||
$userProfile->emailVerified = $data->get('email_verified') ? $userProfile->email : '';
|
||||
|
||||
$userProfile->phone = $data->get('phone');
|
||||
// $userProfile->phoneVerified = $data->get('phone_verified') ? $userProfile->phone : ''; // not supported
|
||||
|
||||
$userProfile->profileURL = $data->get('profile');
|
||||
$userProfile->webSiteURL = $data->get('website');
|
||||
$userProfile->photoURL = $data->get('picture');
|
||||
$userProfile->gender = $data->get('gender');
|
||||
$userProfile->address = $data->filter('address')->get('street_address');
|
||||
$userProfile->city = $data->filter('address')->get('locality');
|
||||
$userProfile->country = $data->filter('address')->get('country');
|
||||
$userProfile->region = $data->filter('address')->get('region');
|
||||
$userProfile->zip = $data->filter('address')->get('postal_code');
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2020 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Adapter\OAuth2;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\User;
|
||||
|
||||
/**
|
||||
* AutoDesk OAuth2 provider adapter.
|
||||
*/
|
||||
class AutoDesk extends OAuth2
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $scope = 'data:read';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiBaseUrl = 'https://developer.api.autodesk.com/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $authorizeUrl
|
||||
= 'https://developer.api.autodesk.com/authentication/v1/authorize';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $accessTokenUrl
|
||||
= 'https://developer.api.autodesk.com/authentication/v1/gettoken';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $refreshTokenUrl
|
||||
= 'https://developer.api.autodesk.com/authentication/v1/refreshtoken';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiDocumentation
|
||||
= 'https://forge.autodesk.com/en/docs/oauth/v2/developers_guide/overview/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
if ($this->isRefreshTokenAvailable()) {
|
||||
$this->tokenRefreshParameters += [
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
'grant_type' => 'refresh_token',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* See: https://forge.autodesk.com/en/docs/oauth/v2/reference/http/users-@me-GET/
|
||||
*/
|
||||
public function getUserProfile()
|
||||
{
|
||||
$response = $this->apiRequest('userprofile/v1/users/@me');
|
||||
|
||||
$collection = new Data\Collection($response);
|
||||
|
||||
$userProfile = new User\Profile();
|
||||
|
||||
$userProfile->identifier = $collection->get('userId');
|
||||
$userProfile->displayName
|
||||
= $collection->get('firstName') .' '. $collection->get('lastName');
|
||||
$userProfile->firstName = $collection->get('firstName');
|
||||
$userProfile->lastName = $collection->get('lastName');
|
||||
$userProfile->email = $collection->get('emailId');
|
||||
$userProfile->language = $collection->get('language');
|
||||
$userProfile->webSiteURL = $collection->get('websiteUrl');
|
||||
$userProfile->photoURL
|
||||
= $collection->filter('profileImages')->get('sizeX360');
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Adapter\OAuth2;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\User;
|
||||
|
||||
/**
|
||||
* Set up your OAuth2 at https://bitbucket.org/<yourusername>/workspace/settings/api
|
||||
*/
|
||||
|
||||
/**
|
||||
* BitBucket OAuth2 provider adapter.
|
||||
*/
|
||||
class BitBucket extends OAuth2
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $scope = 'email';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiBaseUrl = 'https://api.bitbucket.org/2.0/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $authorizeUrl = 'https://bitbucket.org/site/oauth2/authorize';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $accessTokenUrl = 'https://bitbucket.org/site/oauth2/access_token';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiDocumentation = 'https://developer.atlassian.com/bitbucket/concepts/oauth2.html';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUserProfile()
|
||||
{
|
||||
$response = $this->apiRequest('user');
|
||||
|
||||
$data = new Data\Collection($response);
|
||||
|
||||
if (!$data->exists('uuid')) {
|
||||
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
|
||||
}
|
||||
|
||||
$userProfile = new User\Profile();
|
||||
|
||||
$userProfile->identifier = $data->get('uuid');
|
||||
$userProfile->profileURL = 'https://bitbucket.org/' . $data->get('username') . '/';
|
||||
$userProfile->displayName = $data->get('display_name');
|
||||
$userProfile->email = $data->get('email');
|
||||
$userProfile->webSiteURL = $data->get('website');
|
||||
$userProfile->region = $data->get('location');
|
||||
|
||||
$userProfile->displayName = $userProfile->displayName ?: $data->get('username');
|
||||
|
||||
if (empty($userProfile->email) && strpos($this->scope, 'email') !== false) {
|
||||
try {
|
||||
// user email is not mandatory so keep it quiet
|
||||
$userProfile = $this->requestUserEmail($userProfile);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request user email
|
||||
*
|
||||
* @param $userProfile
|
||||
*
|
||||
* @return User\Profile
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function requestUserEmail($userProfile)
|
||||
{
|
||||
$response = $this->apiRequest('user/emails');
|
||||
|
||||
foreach ($response->values as $idx => $item) {
|
||||
if (!empty($item->is_primary) && $item->is_primary == true) {
|
||||
$userProfile->email = $item->email;
|
||||
|
||||
if (!empty($item->is_confirmed) && $item->is_confirmed == true) {
|
||||
$userProfile->emailVerified = $userProfile->email;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Adapter\OAuth2;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\User;
|
||||
|
||||
/**
|
||||
* Blizzard Battle.net OAuth2 provider adapter.
|
||||
*/
|
||||
class Blizzard extends OAuth2
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $scope = '';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiBaseUrl = 'https://us.battle.net/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $authorizeUrl = 'https://us.battle.net/oauth/authorize';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $accessTokenUrl = 'https://us.battle.net/oauth/token';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiDocumentation = 'https://develop.battle.net/documentation';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUserProfile()
|
||||
{
|
||||
$response = $this->apiRequest('oauth/userinfo');
|
||||
|
||||
$data = new Data\Collection($response);
|
||||
|
||||
if (!$data->exists('id')) {
|
||||
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
|
||||
}
|
||||
|
||||
$userProfile = new User\Profile();
|
||||
|
||||
$userProfile->identifier = $data->get('id');
|
||||
$userProfile->displayName = $data->get('battletag') ?: $data->get('login');
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Adapter\OAuth2;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\User;
|
||||
|
||||
/**
|
||||
* Blizzard US/SEA Battle.net OAuth2 provider adapter.
|
||||
*/
|
||||
class BlizzardAPAC extends Blizzard
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiBaseUrl = 'https://apac.battle.net/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $authorizeUrl = 'https://apac.battle.net/oauth/authorize';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $accessTokenUrl = 'https://apac.battle.net/oauth/token';
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Adapter\OAuth2;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\User;
|
||||
|
||||
/**
|
||||
* Blizzard EU Battle.net OAuth2 provider adapter.
|
||||
*/
|
||||
class BlizzardEU extends Blizzard
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiBaseUrl = 'https://eu.battle.net/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $authorizeUrl = 'https://eu.battle.net/oauth/authorize';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $accessTokenUrl = 'https://eu.battle.net/oauth/token';
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Adapter\OAuth2;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\User;
|
||||
|
||||
/**
|
||||
* DeviantArt OAuth2 provider adapter.
|
||||
*/
|
||||
class DeviantArt extends OAuth2
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $scope = 'user';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiBaseUrl = 'https://www.deviantart.com/api/v1/oauth2/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $authorizeUrl = 'https://www.deviantart.com/oauth2/authorize';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $accessTokenUrl = 'https://www.deviantart.com/oauth2/token';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiDocumentation = 'https://www.deviantart.com/developers/http/v1/20200519';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
if ($this->isRefreshTokenAvailable()) {
|
||||
$this->tokenRefreshParameters += [
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* See: https://www.deviantart.com/developers/http/v1/20200519/user_whoami/2413749853e66c5812c9beccc0ab3495
|
||||
*/
|
||||
public function getUserProfile()
|
||||
{
|
||||
$response = $this->apiRequest('user/whoami');
|
||||
|
||||
$data = new Data\Collection($response);
|
||||
|
||||
$userProfile = new User\Profile();
|
||||
|
||||
$full_name = explode(' ', $data->filter('profile')->get('real_name'));
|
||||
if (count($full_name) < 2) {
|
||||
$full_name[1] = '';
|
||||
}
|
||||
|
||||
$userProfile->identifier = $data->get('userid');
|
||||
$userProfile->displayName = $data->get('username');
|
||||
$userProfile->profileURL = $data->get('usericon');
|
||||
$userProfile->webSiteURL = $data->filter('profile')->get('website');
|
||||
$userProfile->firstName = $full_name[0];
|
||||
$userProfile->lastName = $full_name[1];
|
||||
$userProfile->profileURL = $data->filter('profile')->filter('profile_pic')->get('url');
|
||||
$userProfile->gender = $data->filter('details')->get('sex');
|
||||
$userProfile->age = $data->filter('details')->get('age');
|
||||
$userProfile->country = $data->filter('geo')->get('country');
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Adapter\OAuth2;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\User;
|
||||
|
||||
/**
|
||||
* Discord OAuth2 provider adapter.
|
||||
*/
|
||||
class Discord extends OAuth2
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $scope = 'identify email';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiBaseUrl = 'https://discordapp.com/api/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $authorizeUrl = 'https://discordapp.com/api/oauth2/authorize';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $accessTokenUrl = 'https://discordapp.com/api/oauth2/token';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiDocumentation = 'https://discordapp.com/developers/docs/topics/oauth2';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
if ($this->isRefreshTokenAvailable()) {
|
||||
$this->tokenRefreshParameters += [
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUserProfile()
|
||||
{
|
||||
$response = $this->apiRequest('users/@me');
|
||||
|
||||
$data = new Data\Collection($response);
|
||||
|
||||
if (!$data->exists('id')) {
|
||||
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
|
||||
}
|
||||
|
||||
// Makes display name more unique.
|
||||
$displayName = $data->get('username') ?: $data->get('login');
|
||||
if ($discriminator = $data->get('discriminator')) {
|
||||
$displayName .= "#{$discriminator}";
|
||||
}
|
||||
|
||||
$userProfile = new User\Profile();
|
||||
|
||||
$userProfile->identifier = $data->get('id');
|
||||
$userProfile->displayName = $displayName;
|
||||
$userProfile->email = $data->get('email');
|
||||
|
||||
if ($data->get('verified')) {
|
||||
$userProfile->emailVerified = $data->get('email');
|
||||
}
|
||||
|
||||
if ($data->get('avatar')) {
|
||||
$userProfile->photoURL = 'https://cdn.discordapp.com/avatars/';
|
||||
$userProfile->photoURL .= $data->get('id') . '/' . $data->get('avatar') . '.png';
|
||||
}
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Adapter\OAuth2;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\User;
|
||||
|
||||
/**
|
||||
* Disqus OAuth2 provider adapter.
|
||||
*/
|
||||
class Disqus extends OAuth2
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $scope = 'read,email';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiBaseUrl = 'https://disqus.com/api/3.0/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $authorizeUrl = 'https://disqus.com/api/oauth/2.0/authorize';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $accessTokenUrl = 'https://disqus.com/api/oauth/2.0/access_token/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiDocumentation = 'https://disqus.com/api/docs/auth/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
$this->apiRequestParameters = [
|
||||
'api_key' => $this->clientId, 'api_secret' => $this->clientSecret
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUserProfile()
|
||||
{
|
||||
$response = $this->apiRequest('users/details');
|
||||
|
||||
$data = new Data\Collection($response);
|
||||
|
||||
if (!$data->filter('response')->exists('id')) {
|
||||
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
|
||||
}
|
||||
|
||||
$userProfile = new User\Profile();
|
||||
|
||||
$data = $data->filter('response');
|
||||
|
||||
$userProfile->identifier = $data->get('id');
|
||||
$userProfile->displayName = $data->get('name');
|
||||
$userProfile->description = $data->get('bio');
|
||||
$userProfile->profileURL = $data->get('profileUrl');
|
||||
$userProfile->email = $data->get('email');
|
||||
$userProfile->region = $data->get('location');
|
||||
$userProfile->description = $data->get('about');
|
||||
|
||||
$userProfile->photoURL = $data->filter('avatar')->get('permalink');
|
||||
|
||||
$userProfile->displayName = $userProfile->displayName ?: $data->get('username');
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/*!
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
namespace Hybridauth\Provider;
|
||||
|
||||
use Hybridauth\Adapter\OAuth2;
|
||||
use Hybridauth\Exception\UnexpectedApiResponseException;
|
||||
use Hybridauth\Data;
|
||||
use Hybridauth\User;
|
||||
|
||||
/**
|
||||
* Dribbble OAuth2 provider adapter.
|
||||
*/
|
||||
class Dribbble extends OAuth2
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiBaseUrl = 'https://api.dribbble.com/v2/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $authorizeUrl = 'https://dribbble.com/oauth/authorize';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $accessTokenUrl = 'https://dribbble.com/oauth/token';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $apiDocumentation = 'http://developer.dribbble.com/v2/oauth/';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUserProfile()
|
||||
{
|
||||
$response = $this->apiRequest('user');
|
||||
|
||||
$data = new Data\Collection($response);
|
||||
|
||||
if (!$data->exists('id')) {
|
||||
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
|
||||
}
|
||||
|
||||
$userProfile = new User\Profile();
|
||||
|
||||
$userProfile->identifier = $data->get('id');
|
||||
$userProfile->profileURL = $data->get('html_url');
|
||||
$userProfile->photoURL = $data->get('avatar_url');
|
||||
$userProfile->description = $data->get('bio');
|
||||
$userProfile->region = $data->get('location');
|
||||
$userProfile->displayName = $data->get('name');
|
||||
|
||||
$userProfile->displayName = $userProfile->displayName ?: $data->get('username');
|
||||
|
||||
$userProfile->webSiteURL = $data->filter('links')->get('web');
|
||||
|
||||
return $userProfile;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user