86 Commits

Author SHA1 Message Date
ameye b67f736f04 fix 2022-03-19 11:05:21 -04:00
ameye 79bb8ed05d fix 2022-03-19 11:05:18 -04:00
ameye db39cea49b fix 2022-03-12 15:09:14 -05:00
ameye 41fe987f5d fix 2022-03-12 11:19:32 -05:00
ameye f391716de4 fix 2022-03-11 22:48:43 -05:00
ameye 7f0aff735f fix 2022-03-11 22:48:39 -05:00
ameye f08abbe9f6 fix 2022-03-11 00:29:49 -05:00
ameye 74f3b1d282 fix 2022-03-10 22:22:54 -05:00
ameye 346073b544 fix 2022-03-10 12:34:30 -05:00
ameye 81f0c4c233 fix 2022-03-09 21:07:59 -05:00
ameye 626f381c1b fix 2022-03-09 21:07:54 -05:00
ameye 76024459a9 fix 2022-03-08 08:12:55 -05:00
ameye aea41d6ac5 fix 2022-03-07 19:24:52 -05:00
ameye 92af9cdd81 fix 2022-03-07 18:34:01 -05:00
ameye b9de6b4a98 fix 2022-03-07 14:00:36 -05:00
ameye b0747071e9 fix 2022-03-07 14:00:31 -05:00
ameye f64576f3e8 fix 2022-03-03 23:25:53 -05:00
ameye 9009ec13fb fix 2022-03-02 01:58:23 -05:00
ameye dc77c56b43 fix 2022-03-02 01:58:19 -05:00
ameye a3bd756566 fix 2022-03-02 01:30:33 -05:00
ameye c54974811c fix 2022-03-01 13:35:32 -05:00
ameye 3ca0ce7600 fix 2022-02-28 22:56:08 -05:00
ameye d323cc274b fix 2022-02-28 20:00:43 -05:00
ameye 49e0c1191f fix 2022-02-28 19:31:37 -05:00
ameye 862d129d00 fix 2022-02-26 17:01:15 -05:00
ameye 615f09399d fix 2022-02-22 17:14:21 -05:00
ameye 0c400e3918 fix 2022-02-22 16:22:01 -05:00
ameye f2e9e1550e fix 2022-02-22 15:44:56 -05:00
ameye 18c2b8668c fix 2022-02-20 17:58:29 -05:00
ameye 3c31423bb1 fix 2022-02-20 00:28:48 -05:00
ameye e27259dca9 fix 2022-02-19 23:59:57 -05:00
ameye b949c910ea fix 2022-02-19 23:45:05 -05:00
ameye 944ec49640 fix 2022-02-19 23:11:11 -05:00
ameye ae98daa2ec fix 2022-02-19 22:58:46 -05:00
ameye 902e0031d4 fix 2022-02-19 22:58:32 -05:00
ameye 34406d81fa fix 2022-02-19 18:41:09 -05:00
ameye 7e7080f23c fix 2022-02-19 16:58:54 -05:00
ameye 10917727a8 www 2022-02-19 13:14:41 -05:00
ameye 4d4c75aa48 www 2022-02-19 12:47:31 -05:00
ameye cf8c2131bd www 2022-02-19 10:08:54 -05:00
ameye dff9b496cf www 2022-02-19 08:35:09 -05:00
ameye 961b003078 www 2022-02-19 00:09:18 -05:00
ameye 44e2295bb7 www 2022-02-18 23:08:48 -05:00
ameye cf2e761c5a fix 2022-02-18 19:55:18 -05:00
ameye c2d4a49eb2 fix 2022-02-18 19:55:12 -05:00
ameye 1b025a1563 fix 2022-02-18 18:30:32 -05:00
ameye 83a246ee6e fix 2022-02-18 15:52:41 -05:00
ameye 65e7601bda fix 2022-02-18 00:51:47 -05:00
ameye ee4b81e348 fix 2022-02-18 00:17:29 -05:00
ameye d88c823b9f fix 2022-02-14 19:52:29 -05:00
ameye 7d7f5c00dc fix 2022-02-14 19:46:59 -05:00
ameye 31ae9aa725 fix 2022-02-14 19:34:02 -05:00
ameye e7f26e9a39 fix 2022-02-14 19:33:58 -05:00
ameye 999520c31f fix 2022-02-14 18:37:20 -05:00
ameye 285a4c2cfa fix 2022-02-14 18:29:18 -05:00
ameye 45193b66b8 Merge branch 'master' of ssh://gitlab.chiefsoft.net:10222/WrenchBoard/WrenchBoradWeb 2022-02-14 10:23:55 -05:00
ameye 8a9df7b1df fix 2022-02-14 01:33:06 -05:00
ameye b992d1f9b4 fix 2022-02-14 01:21:46 -05:00
ameye 2261ab9d72 fix 2022-02-13 11:35:02 -05:00
ChiefSoft works 7447f7d96e Fix invalid reference format 2022-02-13 05:16:08 +00:00
ChiefSoft works 0cc56dd4df Force https for docker registry url & fix port for flutterwave transfer micro 2022-02-13 04:27:02 +00:00
ameye dabec5c244 fix 2022-02-07 09:56:26 -05:00
ameye efc87db1ca Email boundary workaround 2022-02-05 23:33:32 -05:00
ameye ad56540080 fix 2022-02-05 13:02:33 -05:00
ameye 6d8cdc01ee fix 2022-02-05 11:47:38 -05:00
ameye 6c40d4f22e fix 2022-02-04 23:32:33 -05:00
ameye ef45fd4b6b fix 2022-02-04 21:13:36 -05:00
ameye 76983004a6 ix 2022-02-04 20:44:55 -05:00
ameye f3c2c37326 fix 2022-02-03 20:17:58 -05:00
ameye 54296bf7d6 fix 2022-02-03 19:47:27 -05:00
ameye e122fb93fc fix 2022-02-03 19:29:27 -05:00
ameye cff0929205 fix 2022-02-03 19:22:19 -05:00
ameye 8b8eaf88f9 fix 2022-02-03 19:08:43 -05:00
ameye 46ed530ec1 fix 2022-02-03 12:46:41 -05:00
ameye 2b38b02530 fix 2022-02-03 12:06:19 -05:00
ameye 90ee3dd46f Merge branch 'master' of ssh://gitlab.chiefsoft.net:10222/WrenchBoard/WrenchBoradWeb 2022-02-03 10:37:48 -05:00
ameye f1e5d7eec7 fix 2022-02-02 22:13:20 -05:00
ameye 0cd1f321f9 fix 2022-02-02 21:00:30 -05:00
jenkins 6956c7f409 Remove extra hots 2022-01-30 02:47:32 -05:00
jenkins a456043ced Added docker-compose configuration 2022-01-30 02:43:39 -05:00
ameye 1edcd3ea58 fix 2022-01-21 21:09:48 -05:00
ameye 80d5044534 start job api expire data 2022-01-01 13:57:26 -05:00
ameye f8b262ae54 start job api expire data 2022-01-01 13:57:20 -05:00
ameye 6cce6a0a45 Swagger interface added 2021-12-19 00:37:58 -05:00
ameye e276b6cb7b Tell the app to listen on all interfaces on port PORT to see the connections originating from outside our Docker container 2021-11-28 00:27:29 -05:00
ameye a43c48cd99 Flutterwave create transfer & get status implemented 2021-11-14 01:53:52 -05:00
494 changed files with 50469 additions and 1822 deletions
@@ -1,4 +1,4 @@
FROM node:boron
FROM node:erbium
# Create app directory
RUN mkdir -p /usr/src/app
@@ -7,17 +7,37 @@ A microservice to handle flitterware payment services
* Build the docker image by `docker build -t flutterwave-transfer-micro .`
# Run
* Set environment variables like `MONGO_URL` and `RABBITMQ_URL`. Full list in the wiki.
* `docker run -p <BINDING> -e PORT=<app_port> -e POSTGRE_URL=<postgre_url> -i -t flutterwave-transfer-micro`
* Set environment variables like `PORT` and `POSTGRE_URL`. Full list in the wiki.
* `docker run -p <BINDING> -e PORT=<app_port> -e POSTGRE_URL=<postgre_url> -e FLUTTERWAVE_API=<flutterwave_config> -i -t flutterwave-transfer-micro`
## Example configurations
* binding: 127.0.0.1:3000:3000/tcp
* app_port: 3000
* postgre_url: postgresql://wrenchboard:wrenchboard@10.10.10.23:5432/wrenchboard
* flutterwave_config: eyJCYXNlQXBpVXJsIjoiaHR0cHM6Ly9hcGkuZmx1dHRlcndhdmUuY29tIiwiUHVibGljS2V5IjoiRkxXUFVCS19URVNULTU0YzkwMTQxYjAyODc4OWQ2NzEwNjdiZDcyZjc4MWE5LVgiLCJTZWNyZXRLZXkiOiJGTFdTRUNLX1RFU1QtYzdiYmM4NmQ3ZTcxMDAyNTRjNWU1YmJmMTYyYmYyYjItWCIsIkVuY3J5cHRpb25LZXkiOiJGTFdTRUNLX1RFU1RlOTQ3NGQ0ZTJjZTYifQ==
## Example command
docker run -p 127.0.0.1:3000:3000/tcp -e PORT=3000 -e POSTGRE_URL='postgresql://wrenchboard:wrenchboard@10.10.10.23:5432/wrenchboard' -i -t flutterwave-transfer-micro
```
docker run -p 127.0.0.1:3000:3000/tcp \
-e PORT=3000 \
-e POSTGRE_URL='postgresql://wrenchboard:wrenchboard@10.10.10.23:5432/wrenchboard' \
-e FLUTTERWAVE_API='eyJCYXNlQXBpVXJsIjoiaHR0cHM6Ly9hcGkuZmx1dHRlcndhdmUuY29tIiwiUHVibGljS2V5IjoiRkxXUFVCS19URVNULTU0YzkwMTQxYjAyODc4OWQ2NzEwNjdiZDcyZjc4MWE5LVgiLCJTZWNyZXRLZXkiOiJGTFdTRUNLX1RFU1QtYzdiYmM4NmQ3ZTcxMDAyNTRjNWU1YmJmMTYyYmYyYjItWCIsIkVuY3J5cHRpb25LZXkiOiJGTFdTRUNLX1RFU1RlOTQ3NGQ0ZTJjZTYifQ==' \
-i -t flutterwave-transfer-micro
```
## Flutterwave config
Either use a converniece script base64encoder.js or base64 CLI to encode the config:
```
echo '{
"BaseApiUrl":"https://api.flutterwave.com",
"PublicKey":"FLWPUBK_TEST-54c90141b028789d671067bd72f781a9-X",
"SecretKey":"FLWSECK_TEST-c7bbc86d7e7100254c5e5bbf162bf2b2-X",
"EncryptionKey":"FLWSECK_TESTe9474d4e2ce6"
}' | base64
```
# Test
`npm test`
@@ -1,7 +1,7 @@
'use strict';
const properties = require('../package.json')
const distance = require('../service/distance');
const transfer = require('../service/transfer');
var controllers = {
about: function(req, res) {
@@ -11,13 +11,22 @@ var controllers = {
}
res.json(aboutInfo);
},
getDistance: function(req, res) {
distance.find(req, res, function(err, dist) {
if (err)
res.send(err);
res.json(dist);
});
},
postTransfer: function(req, res) {
transfer.create(req, res, function(err, dist) {
if (err) {
res.send(err);
}
res.json(dist);
});
},
getStatus: function(req, res) {
transfer.get(req, res, function(err, dist) {
if (err) {
res.send(err);
}
res.json(dist);
});
},
};
module.exports = controllers;
@@ -5,6 +5,8 @@ const controller = require('./controller');
module.exports = function(app) {
app.route('/about')
.get(controller.about);
app.route('/distance/:zipcode1/:zipcode2')
.get(controller.getDistance);
app.route('/create')
.post(controller.postTransfer);
app.route('/status/:id')
.get(controller.getStatus);
};
@@ -0,0 +1,9 @@
'use strict';
let data = 'eyJQdWJsaWNLZXkiOiJGTFdQVUJLX1RFU1QtNTRjOTAxNDFiMDI4Nzg5ZDY3MTA2N2JkNzJmNzgxYTktWCIsIlNlY3JldEtleSI6IkZMV1NFQ0tfVEVTVC1jN2JiYzg2ZDdlNzEwMDI1NGM1ZTViYmYxNjJiZjJiMi1YIiwiRW5jcnlwdGlvbktleSI6IkZMV1NFQ0tfVEVTVGU5NDc0ZDRlMmNlNiJ9';
let buff = new Buffer(data, 'base64');
let text = buff.toString('ascii');
let json = JSON.parse(text);
console.log('"' + data + '" converted from Base64 to ASCII is "' + text + '"');
console.log(json);
@@ -0,0 +1,13 @@
'use strict';
let json = {
"BaseApiUrl":"https://api.flutterwave.com",
"PublicKey":"FLWPUBK_TEST-54c90141b028789d671067bd72f781a9-X",
"SecretKey":"FLWSECK_TEST-c7bbc86d7e7100254c5e5bbf162bf2b2-X",
"EncryptionKey":"FLWSECK_TESTe9474d4e2ce6"
};
let data = JSON.stringify(json);
let buff = new Buffer(data);
let base64data = buff.toString('base64');
console.log('"' + data + '" converted to Base64 is "' + base64data + '"');
@@ -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:
File diff suppressed because it is too large Load Diff
@@ -1,10 +1,10 @@
{
"name": "flutterwave-transfer-micro",
"version": "0.0.1",
"description": "A microservice to handle flitterware payment services",
"version": "0.0.4",
"description": "A microservice to handle flutterware payment services",
"main": "server.js",
"scripts": {
"generate-docs": "jsdoc ./api/*.js ./api/**/*.js ./service/*.js ./services/**/*.js -d docs",
"generate-docs": "jsdoc ./api/*.js ./api/**/*.js ./app/*.js ./app/**/*.js ./service/*.js ./service/**/*.js -d docs",
"lint": "eslint ./ --ext .js",
"start": "node server.js",
"start:dev": "nodemon server.js",
@@ -12,9 +12,15 @@
},
"author": "Anatolii Okhotnikov <acidumirae@gmail.com>",
"dependencies": {
"pg": "8.7.1",
"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,10 +1,151 @@
const express = require('express')
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());
const routes = require('./api/routes');
routes(app);
app.listen(port, function() {
app.listen(port, "0.0.0.0", function() {
logger.info('***** Server started on port: ' + port + ' *****');
});
@@ -1,36 +0,0 @@
const request = require('request');
const db = require('../app/db')
const logger = require('../app/logger');
const apiKey = process.env.ZIPCODE_API_KEY || "x4hw36qerDOdewjz5HIx4IR7XO5wsWVb7jFZTJ9jvCYYIHNhvK4aIpMExKb5gEoW";
const zipCodeURL = 'https://www.zipcodeapi.com/rest/';
var distance = {
find: function(req, res, next) {
var url = zipCodeURL + apiKey
+ '/distance.json/' + req.params.zipcode1 + '/'
+ req.params.zipcode2 + '/mile';
logger.info(url);
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
request(url,
function (error, response, body) {
if (!error && response.statusCode == 200) {
response = JSON.parse(body);
res.send(response);
} else {
logger.info(error);
res.send({distance: -1});
}
});
// Sample DB call
db.query('SELECT NOW()', (err, res) => {
if (err) {
throw err;
}
logger.info('time:', res.rows[0])
});
}
};
module.exports = distance;
@@ -0,0 +1,98 @@
'use strict';
const axios = require('axios');
const request = require('request');
const db = require('../app/db')
const logger = require('../app/logger');
// https://developer.flutterwave.com/reference/create-a-transfer
const flutterwaveConfigBuffer = new Buffer(process.env.FLUTTERWAVE_API, 'base64');
const flutterwaveConfig = JSON.parse(flutterwaveConfigBuffer.toString('ascii'));
var transfer = {
create: function(req, res, next) {
var url = flutterwaveConfig.BaseApiUrl + '/v3/transfers';
var headersOpt = {
"Content-Type": "application/json",
"Authorization": "Bearer " + flutterwaveConfig.SecretKey,
};
var data = {
"account_bank": req.body.account_bank,
"account_number": req.body.account_number,
"amount": req.body.amount,
"narration": req.body.narration,
"currency": req.body.currency,
"reference": req.body.reference,
"debit_currency": req.body.debit_currency
};
var options = {
headers: headersOpt
};
logger.info(url);
logger.info(options);
logger.info(data);
// https://blog.logrocket.com/5-ways-to-make-http-requests-in-node-js/
// https://stackoverflow.com/questions/53846709/how-do-i-use-axios-within-expressjs
axios.post(url, data, options)
.then(data => {
res.json(data);
})
.catch(err => {
logger.error(err.message);
//logger.error(err.stack);
logger.error(err.response.data);
//logger.error(err.response.headers);
res.send({
status: "failure",
message: "Invalid response",
details: err.message,
code: err.response.status,
data: err.response.data
});
});
// TODO: Do we save the response in the DB? I assume: YES
db.query('SELECT NOW()', (err, res) => {
if (err) {
throw err;
}
logger.info('time:', res.rows[0])
});
},
get: function(req, res, next) {
var url = flutterwaveConfig.BaseApiUrl + '/v3/transfers/' + req.params.id;
var headersOpt = {
"Authorization": "Bearer " + flutterwaveConfig.SecretKey,
};
var options = {
headers: headersOpt
};
logger.info(url);
axios.get(url, options)
.then(data => {
res.json(data);
})
.catch(err => {
logger.error(err.message);
//logger.error(err.stack);
logger.error(err.response.data);
//logger.error(err.response.headers);
res.send({
status: "failure",
message: "Invalid response",
details: err.message,
code: err.response.status,
data: err.response.data
});
});
// TODO: Do we save the response in the DB? I assume: YES
db.query('SELECT NOW()', (err, res) => {
if (err) {
throw err;
}
logger.info('time:', res.rows[0])
});
}
};
module.exports = transfer;
@@ -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">
&reg; {{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.
&reg; {{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>
+17 -39
View File
@@ -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">
&reg; {{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.
&reg; {{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.
&nbsp;&nbsp;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>
&nbsp;&nbsp;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.
&nbsp;&nbsp;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">
&reg; {{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.
&reg; {{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">
&reg; {{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">
&reg; {{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">
&reg; {{site_name}} 2017<br/>
&reg; {{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>
+13 -23
View File
@@ -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">
&reg; {{site_name}} 2017<br/>
&reg; {{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>
+11 -16
View File
@@ -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">
&reg; {{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.
&reg; {{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>
+6 -3
View File
@@ -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";
+4 -5
View File
@@ -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
## ---------------- ##
+1 -1
View File
@@ -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
+6
View File
@@ -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 -1
View File
@@ -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.
+88 -13
View File
@@ -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
+7 -1
View File
@@ -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());
+2 -2
View File
@@ -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());
+19 -17
View File
@@ -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
+230 -23
View File
@@ -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 )
{
@@ -95,7 +278,11 @@ long WrenchCanceContractPayment( CVars in, CVars &out )
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);
/*
// TEST FOR DUPLICATE
@@ -133,9 +320,12 @@ long WrenchCanceContractPayment( CVars in, CVars &out )
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",x["amount"].Long(),x["member_id"].Long() ); // pay attention to who you pay here
//- Retired this method pgsql_exec("UPDATE members SET balance=balance + %lu WHERE id = %lu",x["amount"].Long(),x["member_id"].Long() ); // 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
Confirmation(payment_id, confirmation, sizeof (confirmation)); // this stamp the offer code directly in that call
UpdateMemberWallet( x["member_id"].Long(), 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 );
@@ -200,7 +390,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 +445,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 );
@@ -280,7 +475,12 @@ long WrenchRefundoffer( CVars in, CVars &out )
REQ_LONG( in, "dir", 1, -1 );
long offer_id = REQ_LONG( in, "offer_id", 1, -1 );
long payment_id = REQ_LONG( in, "payment_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());
if (retDb)
@@ -312,9 +512,10 @@ long WrenchRefundoffer( CVars in, CVars &out )
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",x["amount"].Long() + x["fee"].Long(),in["member_id"].Long() );
// pgsql_exec("UPDATE members SET balance=balance + %lu WHERE id = %lu",x["amount"].Long() + x["fee"].Long(),in["member_id"].Long() );
char confirmation[15] = "";
Confirmation(payment_id, confirmation, sizeof (confirmation)); // this stamp the offer code directly in that call
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 );
@@ -393,8 +594,11 @@ long WrenchContractPayment( CVars in, CVars &out )
return PHP_API_BAD_PARAM; }
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);
/*
// TEST FOR DUPLICATE
@@ -432,9 +636,12 @@ long WrenchContractPayment( CVars in, CVars &out )
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",x["amount"].Long(),x["member_id"].Long() ); // pay attention to who you pay here
//pgsql_exec("UPDATE members SET balance=balance + %lu WHERE id = %lu",x["amount"].Long(),x["member_id"].Long() ); // 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
Confirmation(payment_id, confirmation, sizeof (confirmation)); // this stamp the offer code directly in that call
UpdateMemberWallet( x["member_id"].Long(), 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 );
@@ -496,6 +703,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 +765,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";
}
+376 -3
View File
@@ -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;
}
+7 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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';
+4 -2
View File
@@ -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
+2 -1
View File
@@ -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"],
+9 -1
View File
@@ -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);
+3 -1
View File
@@ -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';
+126 -63
View File
@@ -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>";
+54 -68
View File
@@ -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&nbsp;<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&nbsp;<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;
}
+161 -1
View File
@@ -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;
}
}
+25 -19
View File
@@ -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
}
+37 -8
View File
@@ -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();
+222 -54
View File
@@ -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() {
+4 -3
View File
@@ -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'] = "&nbsp;&nbsp;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 = '';
+107
View File
@@ -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
}
}
+5 -31
View File
@@ -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> ";
}
+10 -3
View File
@@ -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);
}
}
+4 -2
View File
@@ -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() {
+5 -5
View File
@@ -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);
}
}
+3 -1
View File
@@ -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() {
+7 -2
View File
@@ -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;
+21 -3
View File
@@ -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);
*/
}
}
+12
View File
@@ -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
+12
View File
@@ -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);
+89
View File
@@ -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;
}
}
+1
View File
@@ -54,6 +54,7 @@ class Dash_model extends CI_Model {
return $out;
}
public function getNewMessageCount($member_id) {
$out = array();
$out['new_message'] =0;
+24
View File
@@ -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;
}
}
+119
View File
@@ -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']];
}
}
@@ -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
*/
}
@@ -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
{
}
@@ -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
{
}
@@ -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
{
}
@@ -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
{
}
@@ -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
{
}
@@ -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
{
}
@@ -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
{
}
@@ -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
{
}
@@ -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
{
}
@@ -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
{
}
@@ -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');
}
}
+268
View File
@@ -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();
}
}
}
}
+129
View File
@@ -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;
}
}

Some files were not shown because too many files have changed in this diff Show More