Eloquent - Latest entry per user - laravel

I'm trying to get the latest db entry for today for each user.
This is what I have, but it is returning the first entry, instead of the last.
$activity = UserJourney::where('datetime', '>', date('Y-m-d 00:00:00') )
->orderBy('id', 'desc')
->groupBy('user_id')
->get()
->keyBy('user_id')
;
Any ideas?
Thanks
EDIT:
This is the output:
[
{
"id": 1562,
"user_id": 10,
"datetime": "2015-02-05 11:03:41",
"url": "/",
"device": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:35.0) Gecko/20100101 Firefox/35.0",
"created_at": "2015-02-05 11:03:41",
"updated_at": "2015-02-05 11:03:41",
"deleted_at": null
},
{
"id": 1555,
"user_id": 148,
"datetime": "2015-02-05 09:20:56",
"url": "/dashboard/sales",
"device": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.94 Safari/537.36",
"created_at": "2015-02-05 09:20:56",
"updated_at": "2015-02-05 09:20:56",
"deleted_at": null
},
{
"id": 1553,
"user_id": 149,
"datetime": "2015-02-05 09:19:10",
"url": "/",
"device": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.94 Safari/537.36",
"created_at": "2015-02-05 09:19:10",
"updated_at": "2015-02-05 09:19:10",
"deleted_at": null
}
]

Related

Add custom header to each request intercepted by Zalando Logbook

I am using Zalando/LogBook in my Spring Boot with Maven project, I have added dependency logbook-spring-boot-starter in my pom.xml.
Everything is working fine, i have a userId field which after validating the authorization token in Spring Filter Chain i want to set it with each input request that LogBook Intercept.
Is there a way to add custom userId header in each request once it validates Spring Filter Chain.
<dependency>
<groupId>org.zalando</groupId>
<artifactId>logbook-spring-boot-starter</artifactId>
<version>2.14.0</version>
</dependency>
Presently I have
{
"origin": "remote",
"type": "request",
"correlation": "f99b6ba7d39911aa",
"protocol": "HTTP/1.1",
"remote": "0:0:0:0:0:0:0:1",
"method": "GET",
"uri": "/",
"host": "localhost",
"path": "",
"scheme": "http",
"port": "8080",
"headers": {
"user-agent": [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"
]
}
}
What i want is
{
"origin": "remote",
"type": "request",
"correlation": "f99b6ba7d39911aa",
"userId" : "123",
"protocol": "HTTP/1.1",
"remote": "0:0:0:0:0:0:0:1",
"method": "GET",
"uri": "/",
"host": "localhost",
"path": "",
"scheme": "http",
"port": "8080",
"headers": {
"user-agent": [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"
]
}
}

Getting user ID in lambda function (go 1.x) from AWS API Gateway

I updated the API (rest) via the amplify CLI to add a path and function (go 1.x), and within the function, I was able to retrieve the user ID via the following:
event.RequestContext.Identity.CognitoAuthenticationProvider
and this worked just fine.
I repeated the same steps above, however, when trying to retrieve the user id (sub) from the same as above, nothing is being retrieved. I'm not sure why, I've checked API gateway, and the settings seem to be the same, but maybe I'm missing something?
Any idea how to get the user id/sub in the function?
further info:
When accessing the "invoke URL" for the former function, an error message shows:
{"message":"Missing Authentication Token"}
However, this is not the case when accessing the invoke URL for the latter function. The latter function is not expecting an authentication token, how can that be changed?
EDIT: as requested, the JSON response for event.RequestContext:
{
"accountId": "000000000000",
"resourceId": "00aaaa",
"stage": "dev",
"domainName": "a00aaaaa00.execute-api.eu-west-2.amazonaws.com",
"domainPrefix": "a00aaaaa00",
"requestId": "000aa0a0-000a-0000-0000-aa0000a00aaa",
"protocol": "HTTP/1.1",
"identity": {
"cognitoIdentityPoolId": "",
"accountId": "",
"cognitoIdentityId": "",
"caller": "",
"apiKey": "",
"apiKeyId": "",
"accessKey": "",
"sourceIp": "00.000.000.000",
"cognitoAuthenticationType": "",
"cognitoAuthenticationProvider": "",
"userArn": "",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36",
"user": ""
},
"resourcePath": "/xxxxpath",
"path": "/dev/xxxxpath",
"authorizer": null,
"httpMethod": "POST",
"requestTime": "14/May/2022:23:09:05 +0000",
"requestTimeEpoch": 1652569745072,
"apiId": "a00aaaaa00"
}
Thanks

Unable to determine event type for AWS Lambda serverless function

I have a very simple handler that I'm using to familiarize myself with serverless lambda functions.
const example: APIGatewayProxyHandler = async event => {
console.log(JSON.stringify(event, null, 2));
return {
statusCode: 200,
body: JSON.stringify({
message: 'Success',
}),
};
};
Here is my serverless.yml file:
service: lambda-example
frameworkVersion: '2'
provider:
name: aws
runtime: nodejs12.x
plugins:
- serverless-offline
functions:
example:
handler: lib/handler.example
events:
- http:
path: example
method: get
integration: lambda
When I hit the API it works just fine...
{
statusCode: 200,
body: "{"message":"Success"}"
}
I'm using this URL to trigger the event http://localhost:3000/dev/example?url=https://google.com/ and I'm console logging the event itself when the endpoint is hit...
{
"body": {},
"method": "GET",
"principalId": "offlineContext_authorizer_principalId",
"stage": "dev",
"cognitoPoolClaims": {
"sub": ""
},
"enhancedAuthContext": {
"principalId": "offlineContext_authorizer_principalId"
},
"headers": {
"Host": "localhost:3000",
"Connection": "keep-alive",
"Cache-Control": "max-age=0",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Sec-Fetch-Site": "none",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-User": "?1",
"Sec-Fetch-Dest": "document",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9,la;q=0.8"
},
"query": {
"url": "https://google.com/"
},
"path": {},
"identity": {
"accountId": "offlineContext_accountId",
"apiKey": "offlineContext_apiKey",
"apiKeyId": "offlineContext_apiKeyId",
"caller": "offlineContext_caller",
"cognitoAuthenticationProvider": "offlineContext_cognitoAuthenticationProvider",
"cognitoAuthenticationType": "offlineContext_cognitoAuthenticationType",
"sourceIp": "127.0.0.1",
"user": "offlineContext_user",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
"userArn": "offlineContext_userArn"
},
"stageVariables": {},
"requestPath": "/example"
}
I'm interested in accessing the 'query' attribute of this object but TypeScript gets mad at me when I try...
console.log(event.query);
===
Property 'query' does not exist on type 'APIGatewayProxyEvent'.
The query attribute very clearly exists on the event object as shown in my console log so I'm assuming I'm incorrectly typing this function, but I can't seem to find the proper type. What am I doing wrong here?
Additional Info (package.json):
"dependencies": {
"axios": "^0.21.0",
"cheerio": "^1.0.0-rc.3"
},
"devDependencies": {
"#types/aws-lambda": "^8.10.64",
"#types/cheerio": "^0.22.22",
"#types/node": "^14.14.2",
"#typescript-eslint/eslint-plugin": "^4.5.0",
"#typescript-eslint/parser": "^4.5.0",
"eslint": "^7.12.0",
"eslint-config-prettier": "^6.14.0",
"husky": "^4.3.0",
"prettier": "^2.1.2",
"prettier-plugin-organize-imports": "^1.1.1",
"serverless-dotenv-plugin": "^3.1.0",
"serverless-offline": "^6.8.0",
"typescript": "^4.0.3"
}
It turns out the problem was the
integration: lambda
addition to my serverless.yml file. When I removed this line the APIGatewayProxyHandler interface worked as expected.

what is the correct way to get the origin header in a serverless deployed lambda fronted by api gateway?

I am using the serverless framework to deploy a simple lambda (written in node/ express) behind api gateway...
In a GET I can see the origin header, but in a POST I cannot - it's not passed into my lambda function!
Anyone know why not and how to make it pass?
Background:
I did notice that in the POST the origin appears to be appended to the query string in the logs:
originalUrl: '/dev/endpoint?Origin=MY%20ORIGIN%20HERE',
So, I could extract the origin from the query string values, but I want to know if this is the correct way to do things on the serverless framework or should I be setting something to allow the API Gateway to send the origin through on a POST like it does on a GET ? Why are the 2 verbs behaving differently?
My Code/ Config:
the function definition in the serverless.yml looks like:
myGetFunction:
handler: lambda/index.handler
events:
- http:
path: /endpoint
method: get
cors: true
myPostFunction:
handler: lambda/index.handler
events:
- http:
path: /endpoint
method: post
cors: true
If I just put the following in my index.handler:
app.use((req, res) => {
console.log('LOG REQUEST', req)
res.send('interesting')
})
In my handler function, I only want to get the origin request header that was sent. In the GET it's easy: the cloudwatch logs show that it's available in the GET request in the headers object:
headers:
{
accept: '*/*',
'accept-encoding': 'gzip, deflate',
'cache-control': 'no-cache',
'cloudfront-forwarded-proto': 'https',
'cloudfront-is-desktop-viewer': 'true',
'cloudfront-is-mobile-viewer': 'false',
'cloudfront-is-smarttv-viewer': 'false',
'cloudfront-is-tablet-viewer': 'false',
'cloudfront-viewer-country': 'GB',
host: 'X.execute-api.us-east-1.amazonaws.com',
origin: 'MY ORIGIN HERE',
BUT: in the POST all the other headers are there, but origin is blank.
I did a bit of digging on this and ran into a couple realizations.
By default, it seems that no "origin" header passed in the API Gateway events. (I created a fresh serverless project, and just echoed back exactly what the API gateway event was.) So this is coming from some other source. I figured it may be a custom domain, and tested that. No dice.
My only other guess is that you have this behind some other layer (CloudFront?) that is forwarding these headers for you. If that ends up being the case, I would suggest you look and see if you can make it forward these headers for the POST request as it is for the GET request.
My only other final thought if none of the above is true is that there is some magic going on in some of the express middleware. I doubt this is the case.
For reference, this was my full serverless.yml and handler.js I tested with as well as a full unaltered event object I got in the endpoint.
service: so-test
provider:
name: aws
runtime: nodejs8.10
functions:
myGetFunction:
handler: handler.hello
events:
- http:
path: /endpoint
method: get
cors: true
myPostFunction:
handler: handler.hello
events:
- http:
path: /endpoint
method: post
cors: true
And the nodejs code:
'use strict';
module.exports.hello = async (event, context) => {
return {
statusCode: 200,
body: JSON.stringify({
message: 'Go Serverless v1.0! Your function executed successfully!',
input: event,
}),
};
};
Finally the response object
{
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": {
"resource": "/endpoint",
"path": "/test/endpoint",
"httpMethod": "GET",
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Host": "so-test.serverless-examples.com",
"upgrade-insecure-requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
"Via": "2.0 f92491812e422470607f365e923929b5.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "6AwZPV3uCYxseJIAmsGzhApzRostCiLXwwM3XsbSJP4K8hQx11MSgw==",
"X-Amzn-Trace-Id": "Root=1-5c086dd9-bce03ab0c216116fa6de9786",
"X-Forwarded-For": "55.55.55.555, 70.132.32.155",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
"Accept": [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
],
"Accept-Encoding": [
"gzip, deflate, br"
],
"Accept-Language": [
"en-US,en;q=0.9"
],
"CloudFront-Forwarded-Proto": [
"https"
],
"CloudFront-Is-Desktop-Viewer": [
"true"
],
"CloudFront-Is-Mobile-Viewer": [
"false"
],
"CloudFront-Is-SmartTV-Viewer": [
"false"
],
"CloudFront-Is-Tablet-Viewer": [
"false"
],
"CloudFront-Viewer-Country": [
"US"
],
"Host": [
"so-test.serverless-examples.com"
],
"upgrade-insecure-requests": [
"1"
],
"User-Agent": [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
],
"Via": [
"2.0 f92491812e422470607f365e923929b5.cloudfront.net (CloudFront)"
],
"X-Amz-Cf-Id": [
"6AwZPV3uCYxseJIAmsGzhApzRostCiLXwwM3XsbSJP4K8hQx11MSgw=="
],
"X-Amzn-Trace-Id": [
"Root=1-5c086dd9-bce03ab0c216116fa6de9786"
],
"X-Forwarded-For": [
"55.55.55.555, 70.132.32.155"
],
"X-Forwarded-Port": [
"443"
],
"X-Forwarded-Proto": [
"https"
]
},
"queryStringParameters": null,
"multiValueQueryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"requestContext": {
"resourceId": "mftg6x",
"resourcePath": "/endpoint",
"httpMethod": "GET",
"extendedRequestId": "RdYZ7HaxoAMFQYQ=",
"requestTime": "06/Dec/2018:00:31:21 +0000",
"path": "/test/endpoint",
"accountId": "800708648372",
"protocol": "HTTP/1.1",
"stage": "dev",
"domainPrefix": "so-test",
"requestTimeEpoch": 1544056281163,
"requestId": "410632a3-f8ee-11e8-a7e2-7d886f93a0e4",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"sourceIp": "55.55.55.555",
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
"user": null
},
"domainName": "so-test.serverless-examples.com",
"apiId": "txctij0cnp"
},
"body": null,
"isBase64Encoded": false
}
}

Why doesn't nightwatch pickup my browser configuration

I am using nightwatch for testing a web site. Below is my configuration file. I want to use phantomjs as the browser so it can be run without open a browser. But when I run the tests with nightwatch -c integration-tests/nightwatch.json command, it always open my chrome browser. And I tried to modify the value for browserName and found out that whatever I put in doesn't have any effect. Is there anything wrong with my configuration?
{
"src_folders": [
"./integration-tests/tests"
],
"output_folder": "./integration-tests/reports",
"custom_commands_path": "",
"custom_assertions_path": "",
"page_objects_path": "",
"globals_path": "",
"selenium": {
"start_process": false
},
"test_settings": {
"default": {
"launch_url": "http://localhost:9091",
"selenium_port": 9515,
"selenium_host": "localhost",
"default_path_prefix": "",
"silent": true,
"screenshots": {
"enabled": false,
"path": ""
},
"desiredCapabilities": {
"browserName": "phantomjs",
"javascriptEnabled" : true,
"phantomjs.binary.path" :"node_modules/phantomjs",
"phantomjs.cli.args" : []
}
}
}
}
You need to change the userAgent that PhantomJS was reporting.
{
"src_folders": [
"./integration-tests/tests"
],
"output_folder": "./integration-tests/reports",
"custom_commands_path": "",
"custom_assertions_path": "",
"page_objects_path": "",
"globals_path": "",
"selenium": {
"start_process": false
},
"test_settings": {
"default": {
"launch_url": "http://localhost:9091",
"selenium_port": 9515,
"selenium_host": "localhost",
"default_path_prefix": "",
"silent": true,
"screenshots": {
"enabled": false,
"path": ""
},
"desiredCapabilities": {
"browserName": "phantomjs",
"javascriptEnabled" : true,
"phantomjs.binary.path" :"node_modules/phantomjs",
"phantomjs.cli.args" : [],
"phantomjs.page.settings.userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36"
}
}
}
}
settings {object}
userAgent defines the user agent sent to server when the web page requests resources.
Source: http://phantomjs.org/api/webpage/property/settings.html
If you need more examples:
// Mac Chrome 46
"phantomjs.page.settings.userAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36"
// Windows Chrome 46
"phantomjs.page.settings.userAgent" : "Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36"
// Mac Firefox 42.0
"phantomjs.page.settings.userAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:42.0) Gecko/20100101 Firefox/42.0"
// Windows Firefox 42.0
"phantomjs.page.settings.userAgent" : "Mozilla/5.0 (Windows NT 6.3; rv:42.0) Gecko/20100101 Firefox/42.0"
// PhantomJS 2.0
"phantomjs.page.settings.userAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/538.1 (KHTML, like Gecko) PhantomJS/2.0.0 Safari/538.1"

Resources