I am trying to generate a Pusher authentication string. https://pusher.com/docs/auth_signatures. In my Django view, The response is a JSON string with an auth property just as it asked for.
{u'auth': u'1019dcd6d219db50d37e:926260b960edf94509e0fd86547ec756cc4a1006baef4e0b3f8ec35c1e7b8c05'}
but I am getting this error.
Pusher : Error : {"type":"WebSocketError","error":{"type":"PusherError","data":{"code":null,"message":"Auth info required to subscribe to private-account-313"}}}
Is the JSON formatted incorrectly, or does the issues lie somewhere else ? couldn't find anything on it on Pusher's website.
def pusher_auth(request):
# """ -Pusher private channel authentication
# Docs: https//pusher.com/docs/authenticating_users
# """
if request.method == 'POST':
user = request.user
socket_id = request.POST['socket_id']
channel = request.POST['channel_name']
if not (socket_id or channel or user):
raise Exception("Permission denied.")
fragments = channel.split('-')
resource = fragments[1]
resource_id = int(fragments[2])
account = Account.objects.get(email=user.email)
pusher_client = Pusher(app_id='199731', key='1019dcd6d219db50d37e', secret='9550fb09aacce399eeb6',
cluster='ap1', ssl=True)
auth = pusher_client.authenticate(channel, socket_id)
try:
if resource == 'account' and (account.id == resource_id):
print(auth)
context = auth
return composeJsonResponse(200, "", context)
else:
return {'nope'}
except:
raise Exception("Permission denied.")
The angular code where channel is being subscribed to
/**
* pusher-js wrapper as a factory.
* Docs: https://github.com/pusher/pusher-js
*/
(function () {
'use strict';
$pusher.$inject = ["Config"];
angular
.module('app.common')
.factory('$pusher', $pusher);
/** ngInject */
function $pusher(Config) {
var self = this;
self.client = new Pusher(Config.pusher.key, Config.pusher.options || {});
return {
client: self.client
};
}
})();
(function () {
'use strict';
angular
.module('app.core')
.constant('Config', getConfig());
function getConfig() {
return {
api_path: '',
pusher: {
// TODO: add environment-based configs values.
key: '1019dcd6d219db50d37e',
options: {
encrypted: true
}
}
};
}
})();
/**
* Subscribes to user's Pusher channel and binds callback events.
*/
function bindPusher() {
var defer = $q.defer();
var channelName = 'private-account-' + Session.account.id;
var channel = $pusher.client.subscribe(channelName);
channel.bind('pusher:subscription_succeeded', function (data) {
$log.debug('Pusher subscribed: ' + channel.name);
PushListener.bindAndListen(channel);
defer.resolve(data);
});
channel.bind('pusher:subscription_error', function (status) {
if (status === 403) {
var msg = 'Pusher channel not authorized.';
$log.warn(msg);
defer.reject(msg);
}
});
return defer.promise;
}
Related
I am trying to get data from Drive Activity API. The data needs to have the following 4 arguments:
User Information
Filename
Activity Type (Edit, Delete, Copy)
Timestamp
I used the following code to get the required data:
function listDriveActivity() {
var arr = [];
const request = {
pageSize: 10
};
try {
const response = DriveActivity.Activity.query(request);
const activities = response.activities;
if (!activities || activities.length === 0) {
Logger.log('No activity.');
return;
}
for (const activity of activities) {
// get time information of activity.
var time = getTimeInfo(activity);
// get the action details/information
var action = getActionInfo(activity.primaryActionDetail);
// get the actor's details of activity
var actors = activity.actors.map(getActorInfo);
// get target information of activity.
var targets = activity.targets.map(getTargetInfo);
arr.push(actors,targets,[action],[time]);
}
Logger.log(arr);
} catch (err) {
Logger.log('Failed with an error %s', err.message);
}
}
function getOneOf(object) {
for (const key in object) {
return key;
}
return 'unknown';
}
function getTimeInfo(activity) {
if ('timestamp' in activity) {
return activity.timestamp;
}
if ('timeRange' in activity) {
return activity.timeRange.endTime;
}
return 'unknown';
}
function getActionInfo(actionDetail) {
return getOneOf(actionDetail);
}
function getUserInfo(user) {
if ('knownUser' in user) {
const knownUser = user.knownUser;
const isMe = knownUser.isCurrentUser || false;
return isMe ? 'people/me' : knownUser.personName;
}
return getOneOf(user);
}
function getActorInfo(actor) {
if ('user' in actor) {
return getUserInfo(actor.user);
}
return getOneOf(actor);
}
function getTargetInfo(target) {
if ('driveItem' in target) {
const title = target.driveItem.title || 'unknown';
return 'driveItem:"' + title + '"';
}
if ('drive' in target) {
const title = target.drive.title || 'unknown';
return 'drive:"' + title + '"';
}
if ('fileComment' in target) {
const parent = target.fileComment.parent || {};
const title = parent.title || 'unknown';
return 'fileComment:"' + title + '"';
}
return getOneOf(target) + ':unknown';
}
This is the example output, when there is some activity in the drive by a user:
User Information: people/107464693787053536449
Filename: Timesheet
Activity Type: Edit
Timestamp: 2022-04-05T04:51:41.862Z
Now, I want to get the user email in User information rather than user id. Can you please guide me how should I do it? Is there any method/function that I could follow?
You have to use People API if you want to get more information about the user, including the email address:
personName: The identifier for this user that can be used with the People API to get more information. The format is people/ACCOUNT_ID. See https://developers.google.com/people/.
More specifically, call people.get with personFields set to emailAddresses:
function getEmailAddress(resourceName = "people/ACCOUNT_ID") {
const optionalArgs = {
personFields: "emailAddresses",
fields: "emailAddresses(value)"
}
const contact = People.People.get(resourceName, optionalArgs);
const emailAddress = contact.emailAddresses[0].value;
return emailAddress;
}
I downloaded source code from GitHub and try to run it.
It ran but then came the issue with “ipfs-api” so then I install the latest version of “iphs-http-client” now it pops up a lot of error relating to
PLEASE TELL ME IF THIS CAN BE SOLVE IF CANT TELL ME THE REASON TOO, I'm new to this
error in ./node_modules/ipfs-http-client/src/add-all.js
Module parse failed: C:\Users\lione\Sample\Document-verification-on-Blockchain\node_modules\ipfs-http-client\src\add-all.js Unexpected token (16:17)
You may need an appropriate loader to handle this file type.
| * #type {import('../../ipfs/src/core/components/add-all').AddAll<import('.').HttpOptions>}
| */
| async function * addAll (input, options = {}) {
| const progressFn = options.progress
|
# ./node_modules/ipfs-http-client/src/index.js 32:12-32
# ./ethereum/ipfs.js
# ./pages/Org/show.js?entry
# multi ./pages/Org/show.js?entry
this is the error log
add-all.js
'use strict'
const CID = require('cids')
const toCamel = require('./lib/object-to-camel')
const configure = require('./lib/configure')
const multipartRequest = require('./lib/multipart-request')
const toUrlSearchParams = require('./lib/to-url-search-params')
const anySignal = require('any-signal')
const AbortController = require('abort-controller').default
module.exports = configure((api) => {
// eslint-disable-next-line valid-jsdoc
/**
* #type {import('../../ipfs/src/core/components/add-all').AddAll<import('.').HttpOptions>}
*/
async function * addAll (input, options = {}) {
const progressFn = options.progress
// allow aborting requests on body errors
const controller = new AbortController()
const signal = anySignal([controller.signal, options.signal])
const res = await api.post('add', {
searchParams: toUrlSearchParams({
'stream-channels': true,
...options,
progress: Boolean(progressFn)
}),
timeout: options.timeout,
signal,
...(
await multipartRequest(input, controller, options.headers)
)
})
for await (let file of res.ndjson()) {
file = toCamel(file)
if (file.hash !== undefined) {
yield toCoreInterface(file)
} else if (progressFn) {
progressFn(file.bytes || 0)
}
}
}
return addAll
})
/**
* #typedef {import('../../ipfs/src/core/components/add-all').UnixFSEntry} UnixFSEntry
*/
/**
* #returns {UnixFSEntry}
*/
function toCoreInterface ({ name, hash, size, mode, mtime, mtimeNsecs }) {
const output = {
path: name,
cid: new CID(hash),
size: parseInt(size)
}
if (mode != null) {
output.mode = parseInt(mode, 8)
}
if (mtime != null) {
output.mtime = {
secs: mtime,
nsecs: mtimeNsecs || 0
}
}
// #ts-ignore
return output
}
index.js
'use strict'
/* eslint-env browser */
const CID = require('cids')
const multiaddr = require('multiaddr')
const multibase = require('multibase')
const multicodec = require('multicodec')
const multihash = require('multihashes')
const globSource = require('ipfs-utils/src/files/glob-source')
const urlSource = require('ipfs-utils/src/files/url-source')
/**
* #typedef { import("./lib/core").ClientOptions } ClientOptions
*/
/**
* #typedef {object} HttpOptions
* #property {Headers | Record<string, string>} [headers] - An object or [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) instance that can be used to set custom HTTP headers. Note that this option can also be [configured globally](#custom-headers) via the constructor options.
* #property {URLSearchParams | Record<string, string>} [searchParams] - An object or [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) instance that can be used to add additional query parameters to the query string sent with each request.
* #property {object} [ipld]
* #property {any[]} [ipld.formats] - An array of additional [IPLD formats](https://github.com/ipld/interface-ipld-format) to support
* #property {(format: string) => Promise<any>} [ipld.loadFormat] - an async function that takes the name of an [IPLD format](https://github.com/ipld/interface-ipld-format) as a string and should return the implementation of that codec
*/
// eslint-disable-next-line valid-jsdoc
/**
* #param {ClientOptions} options
*/
function ipfsClient (options = {}) {
return {
add: require('./add')(options),
addAll: require('./add-all')(options),
bitswap: require('./bitswap')(options),
block: require('./block')(options),
bootstrap: require('./bootstrap')(options),
cat: require('./cat')(options),
commands: require('./commands')(options),
config: require('./config')(options),
dag: require('./dag')(options),
dht: require('./dht')(options),
diag: require('./diag')(options),
dns: require('./dns')(options),
files: require('./files')(options),
get: require('./get')(options),
getEndpointConfig: require('./get-endpoint-config')(options),
id: require('./id')(options),
key: require('./key')(options),
log: require('./log')(options),
ls: require('./ls')(options),
mount: require('./mount')(options),
name: require('./name')(options),
object: require('./object')(options),
pin: require('./pin')(options),
ping: require('./ping')(options),
pubsub: require('./pubsub')(options),
refs: require('./refs')(options),
repo: require('./repo')(options),
resolve: require('./resolve')(options),
stats: require('./stats')(options),
stop: require('./stop')(options),
shutdown: require('./stop')(options),
swarm: require('./swarm')(options),
version: require('./version')(options)
}
}
Object.assign(ipfsClient, { CID, multiaddr, multibase, multicodec, multihash, globSource, urlSource })
module.exports = ipfsClient
It looks like you're using babel via webpack to transpile the source code and it's failing to parse the async generator function syntax. You may need to add a plugin or otherwise fix your config.
I have a problem consuming data from an ASP.NET Core 2.0 Web API with Angular 5+.
Here the steps i have done:
I have built an ASP.NET Core 2.0 WebAPI and deployed it on a server. I can consume data from postman or swagger without any problems.
Then i have created with NSwagStudio the client TypeScript service classes for my angular frontend app.
Now the problem:
I can make a request to the wep api from the frontend app and i am also recieveing the correct data in JSON-Format.
But while the mapping process to the poco object in the generated client service class, something doesnt work. I always get an object with empty attributes.
Here my code:
product.service.ts
export class ProductService {
private http: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> };
private baseUrl: string;
protected jsonParseReviver: (key: string, value: any) => any = undefined;
constructor() {
this.http = <any>window;
this.baseUrl = "http://testweb01/FurnitureContractWebAPI";
}
getByProductId(productId: string): Promise<Product[]> {
let url_ = this.baseUrl + "/api/Product/GetById?";
if (productId === undefined)
throw new Error("The parameter 'productId' must be defined.");
else
url_ += "productId=" + encodeURIComponent("" + productId) + "&";
url_ = url_.replace(/[?&]$/, "");
let options_ = <RequestInit>{
method: "GET",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processGetByProductId(_response);
});
}
protected processGetByProductId(response: Response): Promise<Product[]> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
if (resultData200 && resultData200.constructor === Array) {
result200 = [];
for (let item of resultData200) {
var x = Product.fromJS(item);
//console.log(x);
result200.push(Product.fromJS(item));
}
}
//console.log(result200);
return result200;
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<Product[]>(<any>null);
}
And here the methods from the Product-class:
init(data?: any) {
console.log(data);
if (data) {
this.productId = data["ProductId"];
this.productNameDe = data["ProductNameDe"];
this.productNameFr = data["ProductNameFr"];
this.productNameIt = data["ProductNameIt"];
this.supplierProductId = data["SupplierProductId"];
this.supplierProductVarId = data["SupplierProductVarId"];
this.supplierProductVarName = data["SupplierProductVarName"];
this.supplierId = data["SupplierId"];
this.supplierName = data["SupplierName"];
this.additionalText = data["AdditionalText"];
this.installationCost = data["InstallationCost"];
this.deliveryCost = data["DeliveryCost"];
this.sectionId = data["SectionId"];
this.categorieId = data["CategorieId"];
this.price = data["Price"];
this.ean = data["Ean"];
this.brand = data["Brand"];
this.modifiedDate = data["ModifiedDate"] ? new Date(data["ModifiedDate"].toString()) : <any>undefined;
this.categorie = data["Categorie"] ? ProductCategory.fromJS(data["Categorie"]) : <any>undefined;
this.section = data["Section"] ? ProductSection.fromJS(data["Section"]) : <any>undefined;
}
}
static fromJS(data: any): Product {
data = typeof data === 'object' ? data : {};
let result = new Product();
result.init(data);
return result;
}
In the init() method when i look at data, it contains all the values i need. But when i for example use data["ProductId"] the value is null/undefined.
Can anyone please help?
Thanks
Here is a screenshot of my console output of the data object:
enter image description here
Now I could figure out, that i can cast the data object directly to Product:
init(data?: any) {
var p = <Product>data;
This works, but i am asking myself, why does the generated class have an init-method with manually setting of the attributes, when it is possible to cast the object directly?
NSwag is misconfigured, use DefaultPropertyNameHandling: CamelCase for ASP.NET Core
Or use the new asp.net core api explorer based swagger generator which automatically detects the contract resolver. (Experimental)
I am trying to create knockout.js component that is getting data from HTML5 Websocket. Websocket code is in separate script e.g. util.js. I am able to connect and get data from socket, but dont know how correctly to set corresponding property in component`s ViewModel.
Websocket - util.js:
var options = {
server: '127.0.0.1',
port: '12345'
};
var socket, loadedFlag;
var timeout = 2000;
var clearTimer = -1;
var data = {};
function handleErrors(sError, sURL, iLine)
{
return true;
};
function getSocketState()
{
return (socket != null) ? socket.readyState : 0;
}
function onMessage(e)
{
data=$.parseJSON(e.data);
// ???? Is it possible to have here something like
// ???? viewModel.getDataWS1(data);
}
function onError()
{
clearInterval(clearTimer);
socket.onclose = function () {
loadedFlag = false;
};
clearTimer = setInterval("connectWebSocket()", timeout);
}
function onClose()
{
loadedFlag = false;
clearInterval(clearTimer);
clearTimer = setInterval("connectWebSocket()", timeout);
}
function onOpen()
{
clearInterval(clearTimer);
console.log("open" + getSocketState());
}
function connectWebSocket()
{
if ("WebSocket" in window)
{
if (getSocketState() === 1)
{
socket.onopen = onOpen;
clearInterval(clearTimer);
console.log(getSocketState());
}
else
{
try
{
host = "ws://" + options.server + ":" + options.port;
socket = new WebSocket(host);
socket.onopen = onOpen;
socket.onmessage = function (e) {
onMessage(e);
};
socket.onerror = onError;
socket.onclose = onClose;
}
catch (exeption)
{
console.log(exeption);
}
}
}
}
Component (productDisplay.js) - creating so that is can be used on multiple pages:
define([
'jquery',
'app/models/productDisplayModel',
'knockout',
'mapping',
'socket'
],
function ($, model, ko, mapping) {
ko.components.register('product', {
viewModel: {require: 'app/models/productModel'},
template: {require: 'text!app/views/product.html'}
});
});
Product ViewModel (productModel.js) - where I struggle to set viewModel property to data from websocket:
var viewModel = {};
define(['knockout', 'mapping', 'jquery'], function (ko, mapping, $) {
function Product(name, rating) {
this.name = name;
this.userRating = ko.observable(rating || null);
}
function MyViewModel() {
this.products = ko.observableArray(); // Start empty
}
MyViewModel.prototype.getDataWS1 = function () {
//Websocket has not connected and returned data yet, so data object is empty
// ???? Is there anyway I can add something like promise so that the value is set once socket is connected?
this.products(data);
};
// apply binding on page load
$(document).ready(function () {
connectToServer1();
viewModel = new MyViewModel();
ko.applyBindings(viewModel);
viewModel.getDataWS1();
});
});
Thank you for any ideas.
You can update an observable when you get a message in the following manner:
util.js
function onMessage(e) {
var productData = $.parseJSON(e.data);
viewModel.addNewProduct(productData);
}
productModel.js
function Product(name, rating) {
this.name = name;
this.userRating = ko.observable(rating || null);
}
function MyViewModel() {
this.products = ko.observableArray(); // Start empty
}
MyViewModel.prototype.addNewProduct(product) {
var newProduct = new Product(product.name, product.rating);
this.products.push(newProduct);
}
Basically the idea is that when you get a message (in onMessage function), you will parse the data and call a function in your viewmodel to add the message data to the viewmodel properties (observables, observableArrays, etc.)
I am trying to work with Symfony2, Doctrine and Angujarjs. There is no problem with Symfony2 or Doctrine but I have issues using an ajax request with angularjs. Either it doesn't load anything and I did make a mistake while loading the json (json comes from Symfony and its working) or if it's working, but the json doesn't contain any of the relationship's data.
So, what's the correct way to
A: create a response for angularjs with relationship data (such as articles and categories)
B: load the requested json into an angularjs variable
Here is my controller.js
var app = angular.module("MyApp", []) .config(['$interpolateProvider', function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
}]);
app.filter('offset', function() {
return function(input, start) {
start = parseInt(start, 10);
return input.slice(start);
};
});
app.filter('htmlToPlaintext', function() {
return function(text) {
return String(text).replace(/<[^>]+>/gm, '');
};
});
app.controller("PaginationCtrl", function($scope, $http) {
$scope.articlesPerPage = 8;
$scope.currentPage = 0;
function htmlToPlaintext(text) {
return String(text).replace(/<[^>]+>/gm, '');
}
// this should load the json from '/admin/jsonallarticles' into the articles variable
$http.get('/admin/jsonallarticles').success(function(data) {
$scope.articles = data;
});
$scope.range = function() {
var rangeSize = 5;
var ret = [];
var start;
start = $scope.currentPage;
if ( start > $scope.pageCount()-rangeSize ) {
start = $scope.pageCount()-rangeSize+1;
}
for (var i=start; i<start+rangeSize; i++) {
ret.push(i);
}
return ret;
};
$scope.prevPage = function() {
if ($scope.currentPage > 0) {
$scope.currentPage--;
}
};
$scope.prevPageDisabled = function() {
return $scope.currentPage === 0 ? "disabled" : "";
};
$scope.pageCount = function() {
return Math.ceil($scope.articles.length/$scope.articlesPerPage)-1;
};
$scope.nextPage = function() {
if ($scope.currentPage < $scope.pageCount()) {
$scope.currentPage++;
}
};
$scope.nextPageDisabled = function() {
return $scope.currentPage === $scope.pageCount() ? "disabled" : "";
};
$scope.setPage = function(n) {
$scope.currentPage = n;
};
});
This is my symfony2 function
public function jsonallarticlesAction() {
$articles = $this->getDoctrine()
->getRepository('AcmeBlogBundle:Articles');
if ( !$articles ) {
throw $this->createNotFoundException(
'Keine Beiträge gefunden!');
}
$queryArticles = $articles->createQueryBuilder('a')
->where('a.status = :status')
->setParameter('status', 0)
->orderBy('a.createdDate', 'DESC')
->getQuery()
->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);;
$articles = array_values($queryArticles);
$response = new Response();
$response->setContent(json_encode($articles));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
EDITED CONTROLLER
I tried using the serializer which comes with Symfony
$encoders = array(new XmlEncoder(), new JsonEncoder());
$normalizers = array(new GetSetMethodNormalizer());
$serializer = new Serializer($normalizers, $encoders);
$articles = $this->getDoctrine()
->getRepository('AcmeBlogBundle:Articles')
->findAll();
if ( !$articles ) {
throw $this->createNotFoundException(
'Keine Artikel gefunden!');
}
$serializer->serialize($articles, 'json');
return new Response(json_encode($json));
But I receive an error:
A circular reference has been detected (configured limit: 1).
For work with Angular.js you must write Rest API. For this you can use https://github.com/FriendsOfSymfony/FOSRestBundle
And for serialize your entities with needed data use http://jmsyst.com/bundles/JMSSerializerBundle
It compatible with FOSRestBundle.
As example of use those bundles you can look one our project https://github.com/stfalcon-studio/lost-and-found
I ran into the same issue and it was due to the fact that my Entity was related back to the same entity from my second entity on a different field. I just simply created this function in my Entity:
public function removeRelationsThatCauseCircularError()
{
$this->companyEvents = NULL;
}
And run the function before going through the serializer.