go to post Peter Cooper · May 17, 2018 Hi YoavWhat I would look at is creating a Caché class method that does most of the workIn %SYS you can do things likeList all Users&sql(declare c1 cursor forselect ID into :xID from Security.Users....And to open the user objectset oUser=##class(Security.Users).%OpenId(<the_id>)And then the properties you need to update for two factor are oUser.PhoneProvider and oUser.PhoneNumber= =Access management would be by roles - again this is available from oUser.Rolesand the related class is Security.Roles= =Don't know about Captcha - but this would be client side - not serer sideHope this helpsPeter
go to post Peter Cooper · Mar 18, 2018 Hi AnneLooks like we are on the same journey - have a look here on what I have so far= =I have no real answer to the logon issue - I think the "correct" solution is for Intersystems to provide a restful logon service to provide this functionality that can be accessed without being already logged on.One possibility that I can think of that *may* work (have not tried it *yet*) ....create a separate CSP web site that has no restrictions on logging on - with a single restful service "logon" - in can be in the same namespace but with a different dispatch class.The COS then performs a $System.Security.Login("username", "password") and returns success or fail - and sets up the session tokenI can see that there may be issues with CORS - but I don't understand this topic yet :}= =As an aside....I have been working with Caché for (too) may years and their security model/features is hidden away, difficult and subject to change.I can understand this - they need to protect their commercial interests - eg it is technically possible for a minimal license (5 users) to support 1,000's of end user clients - clearly not commercially sensible.Peter
go to post Peter Cooper · Mar 16, 2018 Hey KevTry thisset x1="""this is a quoted string with a ' in it"""set x={"fred":"123", "TheQuotedString":(x1)}write x.%ToJSON(){"fred":"123","TheQuotedString":"\"this is a quoted string with a ' in it\""}The %ToJSON() does the escaping for you - or do you need something else?Peter
go to post Peter Cooper · Mar 13, 2018 Hi EvgenyWe have met briefly at last autumn's Developer meet at the Belfry - keep up the great workNew Tag - absolutely (please)Angular2, Angular4 and now Angular5 are enhancements of the same basic product Angular1 (now AngularJS) is a different thingHave a look at https://dzone.com/articles/learn-different-about-angular-1-angular-2-amp...(that's not a typo the URI is as spelt)or google differences between angularjs and angular2Peter
go to post Peter Cooper · Mar 13, 2018 Hi KevHope you are keeping wellHave you triedwrite $System.OBJ.UnCompile("*") from terminal? - replace the "*" with more specific wild cardwrite $System.OBJ.Delete("class name") orwrite $System.OBJ.DeletePackage("package name")I had similar issues -but difficult to pin downPeter
go to post Peter Cooper · Mar 13, 2018 Hi SabarinathanI use pdfPrintCmd - see http://www.verypdf.com/app/pdf-print-cmd/index.htmlit's not free but I have had no issues with it over many years of useThe idea is:a. Write out the pdf to a directoryb. set xResult=$zf(-1, "print command exe")The great advantage is that it has command line options that control margins, double sided etc etcAlso it can be run in the background - this is very useful when doing batches of pdf where creating the pdf using FOP can take several seconds - the idea isa. scan the data via SQLb. create the pdfc. use printCmd to send to a printerTo give you an idea of it working I have a client that produces around 50 multi page passport a day - the printing takes around 1 hour - it's set going as a Cache background job and the printer just chugs away.Peter
go to post Peter Cooper · Jun 21, 2017 Hi KyleThanks for your excellent commentI agree - sort of....Bit it's a balance (as always) between loading buffers - it may be the case that there is an occasional need to just grab the dates - but if it's only a 10% (say) need whereas the 90% need is to display/process the header and the lines together then, for me, the 90% need should win out.Also if the dates (or whatever) are indexed then a selection on a date range (say) will only select the required rows from the index.= =But as I said before - it depends on the size of the system - my clients have modest needs (maybe 3 million rows max) and with a 64Gb machine all/most of the blocks are in memory anyway But thanks for the thoughts - I will certainly start looking at one-many with a cascade deletePeter