Does a ValidatedMethod is hidden from client if not in server folder? - meteor

For bdd CRUD i write my Collection.insert , update, etc in a ValidatedMethod (mdg:validated-method) and call these methods from the client.
// /object/methods.js
export const insertObject = new ValidatedMethod({
name: 'insertObject',
run({object}) {
ObjectCollection.insert(object);
},
});
// /object/view.js
import {insertObject} from './methods.js'
insertObject.call(object , callback());
Is the bdd operation code protected (not on the client) by the used of Validatedmethod? Despise the import of the file.
Or do i need to put bdd code in a /server directory?
It bugs me cause on https://github.com/meteor/todos the crud methods are not in a /server folder, exposing them to the client...
note: unsecure package is removed.

If you import a method to client code, that method will be visible to client side. To avoid that you could just use Meteor.call or Meteor.apply to execute the method.

Related

NextJS: How can I create a server side request context

I need to forward a header from the browser to an external API I call from the server side.
The external API is called from getServerSideProps and API routes.
I was thinking about implementing some sort of a request context (using AsyncLocalStorage for example) that I can access from anywhere in the server side code.
That way I could create a middleware that will save the header to the context, and in the external API client I'll fetch it from the context and add it to the requests.
For example:
// context.ts
export const context = new AsyncLocalStorage<string>();
// middleware.ts
export function middleware(request: NextRequest) {
const store = request.headers[SOME_HEADER];
return context.run(store, () => NextResponse.next());
}
// client.ts
axios.post(EXTERNAL_API, DATA, {
headers: {
SOME_HEADER: context.getStore()
}
}).then(...)
Currently I simply send it as a parameter which is pretty tedious.
Is there a way of achieving it?
I tried adding async_hooks to my project but it got really messy when I tried to build the project.

Is it possible to stub meteor methods and publications in cypress tests?

Is it possible to stub meteor methods and publications in cypress tests?
In the docs (https://docs.cypress.io/guides/getting-started/testing-your-app#Stubbing-the-server) it says:
This means that instead of resetting the database, or seeding it with
the state we want, you can force the server to respond with whatever
you want it to. (...) and even test all of the edge cases, without needing a server.
But I do not find more details about that. All I can find is, that when not using the virtual user in the tests to fill the database, it is possible to call API calls on the app, like so:
cy.request('POST', '/test/seed/user', { username: 'jane.lane' })
.its('body')
.as('currentUser')
In my opinion that is not a "stub". It is a method to "seed" the database.
Is it possible to tell cypress to answer a meteor method in the client code like
Meteor.call('getUser', { username: 'jane.lane' }, callbackFunction);
with some data, it would give back in production?
I can only show an example using sinon to stub Meteor method calls:
const stub = sinon.stub(Meteor, 'call')
stub.callsFake(function (name, obj, callback) {
if (name === 'getUser' && obj.username === 'jane.lane') {
setTimeout(function () {
callback(/* your fake data here */)
})
}
})
That would be of corse a client-side stub. You could also simply override your Meteor method for this one test.

Using NodeJS EventEmitter on Meteor server

I’m implementing an app that makes uses of EventEmitter. My aim is to use it on both client and server. But strangely, emitting an event on the server does not work:
Emitter.emit('SomeEvent', {
user,
document,
}
);
The above will work on the client, but not on the server.
I’ve tried importing the event like Emitter = new (require('events').EventEmitter);
I’ve also tried to import a file with
import EventEmitter from 'events';
class ClassEmitter extends EventEmitter {}
const Emitter = new ClassEmitter();
export default Emitter;
My aim is to emit such an event after each database query on the server. I am using apollo and graphql.
Any idea on this would be very thankful.

Access application wide client when using Redux?

I'm using Redux to manage state and Apollo to execute graphQL queries.
I create an Apollo client that should be accessible from various React components.
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
const link = new HttpLink({
uri: getGraphqlEndpointUrl,
headers: {
'x-api-key': getApiKey(),
'Authorization': jwtToken,
},
});
const client = new ApolloClient({
link: link,
cache: new InMemoryCache(),
});
How do I do this with Redux? Do I store the client in a variable in the Redux store? That seems a bit strange to me, but not unreasonable. Is there a better way though?
Only serializable objects should be stored through redux -- functions or objects that have functions as properties do not belong in a redux store. If you need to reference the Apollo client outside of the component hierarchy of your React app, just create a module that exports the client object itself (not a function that creates a client). Then you can just import the client whereever (including the code that includes your ApolloProvider) and all your code will point at the same instance of the client (and the same cache).
It's important that the module for your client export the instantiated client itself -- if you export a function that creates the client, you'll be recreating it each time you import it.

firebase serve: From a locally served app, call locally served functions

How can I properly simulate a cloud function locally so that it has all data as when being invoked on firebase servers? (e.g. the context.auth)
I am serving my project with firebase serve, it runs ok on http://localhost:5000/, however, my cloud functions are being called from https://us-central1-<my-app>.cloudfunctions.net/getUser. (The function is not even deployed.)
To avoid XY problem, I am trying to debug my function, but calling it from firebase shell results in context.auth being undefined, same when calling via postman from http://localhost:5000/<my-app>/us-central1/getUser.
This is my ./functions/src/index.ts file
import * as functions from 'firebase-functions'
import admin from 'firebase-admin'
import { inspect } from 'util'
admin.initializeApp()
export const getUser = functions.https.onCall((data, context) => {
console.debug('== getUser called =========================================')
console.log('getUser', inspect(data), inspect(context.auth))
return admin.database().ref('userRights/admin').child(context.auth.uid).once('value', snapshot => {
console.log(snapshot.val())
if (snapshot.val() === true) {
return 'OK'
// return {status: 'OK'}
} else {
return 'NOK'
// return {status: 'error', code: 401, message: 'Unauthorized'}
}
})
})
file ./firebase.functions.ts
import { functions } from '~/firebase'
export const getUser = functions.httpsCallable('getUser')
Consumer ./src/pages/AdminPanel/index.tsx
import { getUser } from '~/firebase.functions'
//...
getUser({myDataX: 'asd'}).then(response => console.debug('response', response))
UPDATE - April/2021
As of April/2021, method useFunctionsEmulator has been deprecated. It is suggested to use method useEmulator(host, port) instead.
Original post:
By default, firebase serve sends queries to CLOUD function instead of localhost, but it is possible to change it to to point to localhost.
#gregbkr found a workaround for that at this github thread.
You basically add this after firebase initialization script (firebase/init.js) in html head.
<script>
firebase.functions().useFunctionsEmulator("http://localhost:5001");
</script>
Make sure to REMOVE it when deploying to SERVER
There is currently no support for local testing of callable functions like this. The team is working on a way for you to specify the URL endpoint of a callable function so that you can redirect it to a different location for testing.
Just found a workaround.
using fiddlers AutoResponder to redirect the function call to the local served function.
step 1
copy the target url of the function from the client
step 2
copy the local served function url
step 3
active the auto respoder and use the following rules
(the second rule is also importent to allow all outher requests
That worked for me, thank you #GorvGoyl!
script src="/__/firebase/init.js?useEmulator=true"></script

Resources