1
0
Fork 0
Commit Graph

765 Commits (master)

Author SHA1 Message Date
Mike Gerwitz 44ad6437e2 {src,test}/.npmignore: New files
NPM was not publishing the compiled JS files (from the TS input) because
they were present in generated .gitignore files.  .npmignore takes
precedence.
2019-10-21 13:22:24 -04:00
Mike Gerwitz cca36622eb tsconfig.json (include): Whitelist files to build
This ended up being necessary because the distdir was being considered and
resulting in duplicate symbols.
2019-10-21 10:27:47 -04:00
Mike Gerwitz 813b1ccee9 Makefile.am (EXTRA_DIST): Add tsconfig.json
This was forgotten when this file was originally introduced.
2019-10-21 10:24:17 -04:00
Mike Gerwitz 596944a4ea Server-side DataAPI request precedence and TypeScript introduction
This change was used as a guinea pig for introducing TypeScript, so there's
a lot here.

<<
2019-10-18 16:10:27 -04:00
Mike Gerwitz decf6497de doc/server.text (Server-Side DataAPI): Mention request superceding 2019-10-18 10:02:19 -04:00
Mike Gerwitz b81022b568 doc/hacking.texi (Typescript Migration): New section 2019-10-18 10:02:18 -04:00
Mike Gerwitz 16409a014f TokenedDataApi: Accept or kill token
Rather than leaving a token in a DONE state, we should either transition to
ACCEPTED or DEAD depending on whether the token was superceded.

* src/server/dapi/TokenedDataApi.ts (_replyUnlessStale): Accept token when
  not superceded, otherwise kill.
  [store]: New param.
  (request): Use it.
* test/server/dapi/TokenedDataApiTest.ts: Update accordingly.
2019-10-18 09:55:11 -04:00
Mike Gerwitz 544fe1a1fe RestrictedDataApi: Provide error to event if present
Rather than always providing an "Response data is not an array" error.

* src/dapi/RestrictedDataApi.js (_checkResponse)[err]: New first parameter.
  (request): Use it.
2019-10-18 09:55:11 -04:00
Mike Gerwitz e003abcd4b Integrate TokenedDataApi into system
This changes the easejs interface for DataApi, which requires adding the
param to everything.  The TS interface was created in a previous commit and
already contained this parameter.  The idea is to remove the easejs
interface in the future, but traits are a barrier to that atm.

DocumentServer and controller demonstrate the mess that we have with regards
to instantiating dependencies.  This needs to change---DocumentServer itself
was something that was started but never fully realized.  It makes this
incredibly confusing, difficult to follow, and complicates important error
handling that ought to be taking place.  It also discourages implementing
additional dependencies.

I'm not going to go through and provide a ChangeLog-style commit message for
this commit.  I'm too exhausted by this crap.
2019-10-18 09:55:11 -04:00
Mike Gerwitz d8c065817f NodeCallback<T, R>: New type to simplify callback declarations
Just trying to reduce some boilerplate.  I kept this as a separate commit to
illustrate clearly how this type of things is done since we'll have people
learning TypeScript.

* src/types/misc.ts (NodeCallback<T,R>): New type.
* src/server/dapi/TokenedDataApi.ts: Use it.
* test/server/dapi/TokenedDataApiTest.ts: Use it.
2019-10-18 09:55:11 -04:00
Mike Gerwitz 07c8b55475 TokenedDataApi: New class
This integrates the PersistentTokenStore into the DataAPI system via a
decorator.  Unfortunately, it requires an API change and propagating data
through the system is a huge mess, which is the topic of a following
commit.  The API modification was a compromise.

This modifies the interface of DataApi to include a third parameter.  I am
continuing to export the old easejs interface for an incremental migration
away from it.  That old interface will be modified next commit, since
it requires modifying a lot of files and will muddy up this commit.

* src/dapi/DataApi.ts: Rename from js.  Add types.  Add new interface.
  Continue exporting old.
* src/server/dapi/TokenedDataApi.ts: New class.
* test/server/dapi/TokenedDataApiTest.ts: New test cases.
2019-10-18 09:55:11 -04:00
Mike Gerwitz b3ab082e9c {=>Persistent}TokenStore
This creates an interface for TokenStore.  The main motivation of this right
now is testing, since I'm punting on figuring out a mock framework right
now (due to time constraints).

* src/server/token/TokenStore.ts: Rename file.
* src/server/token/store/PersistentTokenStore.ts: Rename from TokenStore.
* test/server/token/TokenStoreTest.ts: Rename file.
* test/server/token/store/PersistentTokenStoreTest.ts: Rename from TokenStoreTest.
2019-10-18 09:55:11 -04:00
Mike Gerwitz d1f72cf5b3 MongoTokenDao, TokenStore: Simplify constructors
This is a feature that I originally wished I could introduce into easejs.  I
enjoyed it in Scala.  Cuts down on a lot of boilerplate.

* src/server/token/MongoTokenDao.ts (constructor): Remove fields and replace
  with inline definitions.
* src/server/token/TokenStore.ts (constructor): Likewise.
2019-10-18 09:55:10 -04:00
Mike Gerwitz c8589a1c57 TokenDao, TokenStore: Track most recently created tokens
This is much more useful information than the last modified.  For example:

- Token A is created.  It becomes the last modified.
- Token B is created.  It becomes the last modified.
- Token A completes.  Mismatch.  It becomes the last modified.
- Token B completes.  Mismatch.  It becomes the last modified.

So in this case, we're unable to use the flag to determine whether we should
ignore the token.  But if we instead us the new flag to see what token was
last _created_, the problem is solved.

This should have been obvious the first time around.

* src/server/token/MongoTokenDao.ts (updateToken): Query
    `lastState'.  Return its value.  Update its value.
  (getToken): Query lastState.  Return its value.
* src/server/token/Token.ts (Token)[last_state]: New field.
* src/server/token/TokenDao.ts (TokenQueryResult, TokenNamespaceResults):
    Use type instead of interface.
  (TokenStateHistory): New type.
  (TokenNamespaceData)[lastState]: New optional field.
  (TokenData)[prev_state]: New field.
* src/server/token/TokenStore.ts: Return previous state data for each
    method.
* test/server/token/MongoTokenDaoTest.ts: Add last_state.
* test/server/token/TokenStoreTest.ts: Likewise.
2019-10-18 09:55:10 -04:00
Mike Gerwitz 0a9a5fe56e TokenStore: Provide document id via constructor
The primary use case for this is currently the DataAPI, and the quote id is
only available at the highest level of the server, before dapis are
processed.

In any case, the TokenStore was already described in terms of a combination
of document id; namespace; and root field; so it makes sense for doc id to
be part of the constructor.

If a more generic TokenStore is needed in the future, we could go back to
the previous API and wrap it in another class, like a partially applied
function (e.g. `DocumentTokenStore`).

* src/server/token/TokenStore.ts: Move doc_id out of arguments and into the
  constructor.
* test/server/token/TokenStoreTest.ts: Update accordingly.
2019-10-18 09:55:10 -04:00
Mike Gerwitz 929acf0e90 TokenStore: Implement for token lookups and creation
Does not yet support token updates.

* src/server/token/Token.ts (TokenStateDeadable, TokenStateDoneable,
  TokenStateAcceptable, Token): New types.
* src/server/token/TokenStore.ts: New class.
* test/server/token/TokenStoreTest.ts: New test case.
2019-10-18 09:55:10 -04:00
Mike Gerwitz 9997da3f65 TokenDao: Return previous state
This causes the DAO to return the state of the document prior to the
database operation (in the case of a retrieval, the previous state is the
same as the current state).  This will allow determining whether other
tokens were modified since a previous request.

* src/server/token/MongoTokenDao.ts: Stop using TokenType in favor of new
    TokenState.
  (updateToken): Query for and return previous state.  Use findAndModify
    instead of update.
  (getToken): Return previous state.  Minor changes to account for new
    TokenQueryResult types (null=>undefined).
* src/server/token/Token.ts: Add comments for existing Token{Id,Namespace}
    nominal types.
  (TokenState): New string enum.
* src/server/token/TokenDao.ts: Import new TokenState.
  (TokenDao)[updateToken]: Use it.
  (TokenType): Remove.
  (TokenQueryResult, TokenNamespaceResults, TokenNamespaceData):
    null=>undefined for unavailable value.  null was wrong.
  (TokenStatus): Token{Type=>State}.
  (TokenData)[prev_state, prev_status]: New fields.
* test/server/token/MongoTokenDaoTest.ts: Update tests accordingly.
2019-10-18 09:55:10 -04:00
Mike Gerwitz ddf5892c83 src/types/mongo.d.ts: Add findAndModify
* src/types/mongo.d.ts (MongoCollection)[#findAndModify]: New method.
2019-10-18 09:55:10 -04:00
Mike Gerwitz 5b279f77cb TokenDao (#updateToken): Return updated data
Since some of these data are generated within TokenDao (e.g. the timestamp),
the caller cannot infer all values.

* src/server/token/MongoTokenDao.ts (updateToken): Return
  Promise<{void=>TokenData}>.
* src/server/token/TokenDao.ts (TokenDao)[#updateToken]: Update interface
  accordingly.
* test/server/token/MongoTokenDaoTest.ts: Update test accordingly.
2019-10-18 09:55:10 -04:00
Mike Gerwitz 4454e40e19 TokenDao: Add error context 2019-10-18 09:55:10 -04:00
Mike Gerwitz fe10578949 {Context,Chained}Error: New modules
This will allow us to provide additional useful information for structure
logging.
2019-10-18 09:55:09 -04:00
Mike Gerwitz 1f66a25658 TokenDao: Better error handling for unknown tokens
Rather than replying with null, which complicates using the returned promise
efficiently, we'll respond with a unique error that allows us to distinguish
between a database failure and a missing token.

These are more traditional errors, but we're moving toward structured
logging, so I want error objects that provide more context.  I'll explore
that a bit more in next commit.  Unfortunately, the untypedness of Promise
rejections make for a less than desirable situation here.  Async/await is
not yet an option since we're still compiling to ES5 (have to support
IE11), and TS compiles async/await into generators for environments that
don't support them, which also are not available in ES5.

* src/server/service/TokenedService.js (_getQuoteToken): Remove null check,
  since this situation can no longer occur.
* src/server/token/MongoTokenDao.ts (getToken): Remove null from return type
  union; reject with `UnknownTokenError' instead.
* src/server/token/TokenDao.ts: Modify interface accordingly.
* src/server/token/UnknownTokenError.ts: New class.
* test/server/token/MongoTokenDaoTest.ts: Modify tests accordingly.  Add
  missing test for latest token namespace missing.
2019-10-17 11:47:14 -04:00
Mike Gerwitz fb88ceeae6 TokenDao: class=>interface
TokenDao has been renamed to MongoTokenDao.  While it's good for this to
have its own interface anyway, the immediate motivation was for unit tests:
I started playing with mocking with TypeScript and researching some
libraries, but I don't have time to research enough to commit to any of them
at the moment.  Interfaces remove the need to mock at all.

This also stops using `export default' in favor of just importing by
name.  Using defaults only saves us a few characters, and it makes for
awkward syntax in various cases (e.g. with multiple exports).  But I'm still
new to TS, so who knows if I'll be flip-flopping on this decision in the
future.  If we kept to our normal 1:1 file:definition convention, it
wouldn't cause problems, but based on the types I've had to define so far,
that'd cause way too much bloat and boilerplate.

* src/server/daemon/controller.js: No long import `default'.  Use
  `MongoTokenDao'.
* src/server/token/TokenedService.js: Stop checking type (since TS
  interfaces do not result in compiler output, easejs cannot validate
  against them.)
* src/server/token/MongoTokenDao.ts: Rename from `TokenDao.ts'.
* src/server/token/TokenDao.ts: Rename from `TokenQueryResult.ts'.
  (TokenDao): New interface.
* src/server/token/TokenQueryResult.ts: Rename to `TokenDao.ts'.
* test/server/token/MongoTokenDaoTest.ts: Rename from `TokenDaoTest.ts'.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 37f1b86ac1 TokenDao: "quote"=>"document" with nominal type
* src/document/Document.ts: New file.
* src/server/token/TokenDao.ts: quote=>document and use DocumentId.
* test/server/token/TokenDaoTest.ts: Likewise.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 54b3f0db72 TokenDao: Nominal typing
This beings an experiment with nominal typing using what the TS community
calls "branding".  The lack of nominal types was one of my biggest
disappointments with TS, so this should really help to mitigate bugs
resulting from misappropriation of data.

* src/server/token/Token.ts: New file.
* src/server/token/TokenDao.ts: Use Token{Id,Namespace}.
* src/server/token/TokenQueryResult.ts: Likewise.
* src/types/misc.d.ts: Introduce NominalType and UnixTimestamp.
* test/server/token/TokenDaoTest.ts: Use nominal types.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 9ea66c0440 TokenDao: Lift out nondeterminism (date)
* src/server/daemon/controller.js (getUnixTimestamp): New method.  Not
  ideal, but better than where it was.
  (_initExportService): Pass to TokenDao constructor.
* src/server/token/TokenDao.ts (_getTimestamp): New field.
  (constructor)[get_timestamp]: New param.
  (updateToken): Use it.
* test/server/token/TokenDaoTest.ts: Provide stub timestamp function.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 9dd1ae3428 TokenDao: Export as default alongside TokenData
Our coding standards are to create a separate file for classes and
interfaces, but this is a bit different: this "interface" is more like a
struct, and it's used to define the return type of a method of this
class.  Since it's inherently coupled, I'm keeping it in the same file.

The idea is that the caller will provide its own abstraction rather than
continuing to export this one.  Note that Typescript does support
re-exporting symbols if need be.

* src/server/daemon/controller.js: Adjust import of TokenDao (TS compiles
  default modules as `default').
* src/server/service/TokenedService.js: Adjust import of TokenDao.
* src/server/token/TokenDao.ts: Export TokenDao as `default'.  Export
  TokenData.
* test/server/token/TokenDaoTest.ts: Adjust import of TokenDao.  Import
  TokenData.
2019-10-17 11:47:14 -04:00
Mike Gerwitz c90757a6d3 TokenDao: Callbacks=>promises
This makes minimal changes to TokenedService, even though there is obvious
refactoring that can be done to reduce duplication, because the class is
currently untested.

* src/server/service/TokenedService.js (_getQuoteToken, generateToken,
    killToken, acceptToken, completeToken): Expect promise.
* src/server/token/TokenDao.ts (updateToken, getToken): Remove callback
    param, return Promise.
* test/server/token/TokenDaoTest.ts: Use promises.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 9eb5d6c118 package.json.in: Restrict chai-as-promised and add @types
* package.json.in (devDependencies)[chai-as-promised]: Restrict version.
    [@types/chai-as-promised]: Add and restrict to same version.  Otherwise,
      there is a typescript incompatibility.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 18e86ebfe7 TokenDao: Add test and further refine types
This tests the existing state of TokenDao before additional modifications
are made.  This commit also further refines the types introduced in a
previous commit.

This is also the first test written in Typescript.

* package.json.in (devDependencies): Add node, chai, and mocha types.
* src/server/token/TokenDao.ts (updateToken): `data` accepts null (as it
    should).  Do not conditionall add data to object (it doesn't matter for
    later retrieval).  Note nondeterminism with date.  More concise syntax
    for object fields.
* src/server/token/TokenQueryResult.ts: Make all fields readonly.
  (TokenStatus): Date is no longer optional (see above mention).
* src/types/mongodb.d.ts: Remove generics (erroneously added).
  (Collection)[update]: Remove 3-argument declaration (see comment).
* test/server/token/TokenDaoTest.ts: New test case.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 742955a671 TokenDao: Make root field configurable
This was previously hard-coded to "exports", which is so named because the
system is currently used only to export data to another system.

This change retains the previous functionality.

* src/server/daemon/controller.js (_initExportService): Pass new TokenDao
    argument.
* src/server/token/TokenDao.ts (TokenDao)[_rootField]: New property.
  (constructor, getToken, _genRoot): Use it.
2019-10-17 11:47:14 -04:00
Mike Gerwitz b83f13f480 TokenDao: Add type information for Mongo interactions
This adds type information for both MongoCollection and some details about
the structure of the data itself as it is stored in the database.

* src/server/token/TokenDao.ts: Import types from TokenQueryResult.
  (TokenType): Move to TokenQueryResult module.
  (TokenData)[status]: string=>TokenStatus.
  (TokenDao)[_collection]: Remove optional type specifier.
    [_collection]: Make readonly.
    [updateToken]: Use TokenStatus type for token_entry.
    [getToken]: Add return type.  Add type for query result.  Remove useless
      length check (no such field exists).  Add types for variables.
    [_getLatestToken]: Use interface instead of inline type definition.
    [_getRequestedToken]: Use type definition for `data' instead of
      `any'.  Add type of variable.
* src/server/token/TokenQueryResult.ts: Define structure of data in Mongo.
* src/types/mongodb.d.ts: Add type information for methods used by TokenDao.
2019-10-17 11:47:14 -04:00
Mike Gerwitz c909599ab5 TokenDao: Move to src/server/{service=>token}
This is no longer going to be coupled with the concept of a "service",
though it'll continue to be used by it.

* src/server/daemon/controller.js: Change TokenDao import path.
* src/server/service/TokenedService.js: Likewise.
* src/server/service/TokenDao.ts: Rename (delete).
* src/server/token/TokenDao.ts: New name.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 22bfb6071b Makefile.am: Copyright range update 2019-10-17 11:47:14 -04:00
Mike Gerwitz 5fafe4a469 Generate .gitignores for compiled JS files
This will help until all files are typescript.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 5a1b84c271 TokenDao: Typescript conversion
This is the first test of integrating typescript.  I'm using the `export ='
syntax to keep imports the same using `require', but note that the `new'
keyword is now required for instantiation (whereas it was not with easejs).
2019-10-17 11:47:14 -04:00
Mike Gerwitz bacefb0752 Build typescript files
* .gitignore (tsconfig.tsbuildinfo): Ignore generated file (used for
    incremental builds).
* Makefile.am (tsout): New variable an recipe.
  (modindex, check): Depend on tsout.
* dummy.ts: New (temporary) file.  Will be removed once we have at least one
  ts file.
* npm-shrinkwrap.json: Update.
* package.json.in (devDependencies)[typescript]: New dependency.
* tsconfig.json: New configuration file.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 4f8aa3c90b FieldVisibilityEventHandler: Fix arrow function notation
This was a syntax recognized back in the day.
2019-10-17 11:47:14 -04:00
Joseph Frazer 20ddff0f6e [DEV-5872] Catch when an element is not present
Merge branch 'jira-5872'

* jira-5872:
  [DEV-5872] Catch when an element is not present
2019-09-26 13:46:50 -04:00
Joseph Frazer 28cac6917f [DEV-5872] Catch when an element is not present
When a question has been removed, but exists in a bucket for an existing
quote, it cannot find the element to hide and it ends up showing all (or
mostly all) question elements. We are ignoring this case since the
possible side effects of ignoring them are less severe than what happens
now. Additionally, the way this works will be changing in the future.
2019-09-26 13:24:39 -04:00
Mike Gerwitz 0553060f42 Add optional rate event delay
I've long been opposed to adding this delay, but a proper fix (for deferred,
async rating) that meets the needs of our current project will require
changes that I don't have time to take on for a little while.  As such, this
will be a temporary solution for hopefully no more than a month's time.

* src/client/Client.js (_initBeforeLoadHook): Pass value to event in
  addition to step id.
* src/client/event/RateEventHandler.js: Implement delay.

DEV-6145
2019-09-19 10:54:21 -04:00
Joseph Frazer b2c05fb136 [DEV-5657] Check for TLD in email addresses
Merge branch 'jira-5657'

* jira-5657:
  [DEV-5657] Check for TLD in email addresses
2019-09-12 11:29:34 -04:00
Joseph Frazer 28f938853a [DEV-5657] Check for TLD in email addresses
The DocuSign service rejects email addresses without a TLD, even though
they are valid.
2019-09-12 09:30:23 -04:00
Mike Gerwitz 27d570578d quicksave: Remove saving and restoring of state
The quicksave feature was added back in 2011 when the framework was somewhat
unstable---we were taking calls from users and it wasn't a pleasent
experience to tell them that they had to refresh the page to work around
some issue with bad state, and lose all unsaved data.

This feature is now more trouble than it's worth, since it causes a number
of bugs and can even cause data corruption.  If this is reintroduced in the
future, I'd prefer it be done by periodically saving quote state after every
or a few bucket modifications, to permit Meteor-like features.

This keeps the feature available on the client as a heartbeat for quote
locking; this can be removed in the future when we handle distributed
locking.

* src/client/Client.js (_changeQuote): Stop setting quicksave data from
    request.
  (_mergeQuickSaveData): Remove now-unused method.
  (_createUi): Stop merging quicksave data on render.
  (saveStaging): Add note that this method is now only used as a heartbeat.
* src/client/quote/ClientQuote.js (saveStaging): Add comment indicating that
    this is now used for a heartbeat.
  (setQuickSaveData, getQuickSaveData): Remove methods.
* src/quote/BaseQuote.js (_quickSaveData): Remove field.
  (setQuickSaveData, getQuickSaveData): Remove methods.
* src/server/Server.js (initQuote): Do not create or initialize quicksave
    data.
  (handleQuickSave): Remove method.
* src/server/daemon/controller.js (doRoute): Return empty reply without
    processing quicksave data.  Continue touching session to retain quote
    lock.
* src/server/db/MongoServerDao.js (saveQuote): Do not clear quicksave.
  (quickSaveQuote): Remove method.
2019-09-04 11:59:36 -04:00
Mike Gerwitz e058c8b509 Copyright range update
All files now have the same range, beginning from the conception of this
project.
2019-08-30 09:41:35 -04:00
Mike Gerwitz 2c49156ba3 controller: Add missing returns
This was broken when the controller was made async; the returns were
converted into resolves.
2019-08-28 15:17:04 -04:00
Schaffer, Austin f16d8f53ec [DEV-5752] Allow override for dynamic submit messages
See merge request floss/liza!61
2019-08-01 15:53:13 -04:00
Schaffer, Austin 858efdce84 [DEV-5752] Allow override for dynamic submit messages 2019-08-01 15:53:13 -04:00
Goldsmith, Mark 20b06ee64d [DEV-5618] Expose meta bucket to init route
See merge request floss/liza!60
2019-08-01 13:37:31 -04:00
Mark Goldsmith 6e99e65167 [DEV-5618] Expose meta bucket to init route 2019-08-01 12:20:22 -04:00