diff --git a/at_login_verify_service/.gitignore b/at_login_verify_service/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/at_login_verify_service/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/at_login_verify_service/CONTRIBUTING.md b/at_login_verify_service/CONTRIBUTING.md new file mode 100644 index 0000000..5ceaed0 --- /dev/null +++ b/at_login_verify_service/CONTRIBUTING.md @@ -0,0 +1,170 @@ + + +# Contributing guidelines + +We 💙 [Pull Requests](https://help.github.com/articles/about-pull-requests/) +for fixing issues or adding features. Thanks for your contribution! + +Please read our [code of conduct](code_of_conduct.md), which is based on +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](code_of_conduct.md) + + +For small changes, especially documentation, you can simply use the "Edit" button +to update the Markdown file, and start the +[pull request](https://help.github.com/articles/about-pull-requests/) process. +Use the preview tab in GitHub to make sure that it is properly +formatted before committing. Please use conventional commits and follow the semantic PR format as documented +[here](https://github.com/atsign-foundation/.github/blob/trunk/atGitHub.md#semantic-prs). +A pull request will cause integration tests to run automatically, so please review +the results of the pipeline and correct any mistakes that are reported. + +If you plan to contribute often or have a larger change to make, it is best to +setup an environment for contribution, which is what the rest of these guidelines +describe. The atsign-foundation GitHub organization's conventions and configurations are documented +[here](https://github.com/atsign-foundation/.github/blob/trunk/atGitHub.md). + +## Development Environment Setup + + +### Prerequisites + + ``` sh + # show how to install the tools needed to work with the code here + ``` + + +### GitHub Repository Clone + +To prepare your dedicated GitHub repository: + +1. Fork in GitHub https://github.com/atsign-foundation/at_libraries +2. Clone *your forked repository* (e.g., `git clone git@github.com:yourname/at_libraries`) +3. Set your remotes as follows: + + ```sh + cd at_libraries + git remote add upstream git@github.com:atsign-foundation/at_libraries.git + git remote set-url upstream --push DISABLED + ``` + + Running `git remote -v` should give something similar to: + + ```text + origin git@github.com:yourname/at_libraries.git (fetch) + origin git@github.com:yourname/at_libraries.git (push) + upstream git@github.com:atsign-foundation/at_libraries.git (fetch) + upstream DISABLED (push) + ``` + + The use of `upstream --push DISABLED` is to prevent those + with `write` access to the main repository from accidentally pushing changes + directly. + +### Development Process + +1. Fetch latest changes from main repository: + + ```sh + git fetch upstream + ``` + +1. Reset your fork's `trunk` branch to exactly match upstream `trunk`: + + ```sh + git checkout trunk + git reset --hard upstream/trunk + git push --force + ``` + + **IMPORTANT**: Do this only once, when you start working on new feature as + the commands above will completely overwrite any local changes in `trunk` content. +1. Edit, edit, edit, and commit your changes to Git: + + ```sh + # edit, edit, edit + git add * + git commit -m 'A useful commit message' + git push + ``` + +1. How to run tests: + + ``` sh + # explain tests here + ``` + +1. Open a new Pull Request to the main repository using your `trunk` branch + + +## @‎library release process + +The Atsign Foundation produces several widgets and libraries that the app developer +can make use of to develop apps on @‎protocol. These libraries are developed in +Dart & Flutter and published to [pub.dev](https://pub.dev/publishers/atsign.org/packages). + +![alt_text](images/image1.png "Version flow") + +## Following the changes + +The Atsign Foundation publishes libraries and widgets to +[https://pub.dev/publishers/atsign.org/packages](https://pub.dev/publishers/atsign.org/packages). +Each of these libraries contains a tab called “Changelog” that shows various +published versions and a short description of what changes that went in. + +![alt_text](images/image2.png "Changelog screenshot") + +Also the “Versions” tab shows the versions published in the reverse +chronological order. + +![alt_text](images/image3.png "Versions screenshot") + +## Reporting a bug + +The best place to start reporting bugs on the libraries published by +@‎protocol would be the “View/report issues” link available on +[pub.dev](https://pub.dev/publishers/atsign.org/packages). + +![alt_text](images/image4.png "View/report issues highlight") + +Once the link is clicked, one should be redirected to GitHub repo where the +issue can be reported by clicking on the “New issue” button. + +![alt_text](images/image5.png "Issues list") + +Clicking on the “New issue” button should take you to the screen to choose +where the issue is a Bug or an Enhancement. + +![alt_text](images/image6.png "Choose Bug report") + +Upon clicking on the “Get started” button against the “Bug Report” you should +be directed to a page with a bug template provided by Atsign. Filling +out all of the fields in the template gives Atsign a better chance to +reproduce and fix the bug. + +![alt_text](images/image7.png "Filling a Bug report") + +## Bug fix and delivery process + +* Bugs will initially be placed into the Sprint Planning Board so that they +can be triaged, estimated and scheduled. +* Once work on a bug is scheduled one or more engineers will be assigned to +fixing the bug, and story points will be allocated to match the time estimated +to fix the bug. +* Progress on fixing the bug will be updated in the associated GitHub issue, +and reviewed during subsequent sprint planning meetings where necessary. +* Once a fix is created we will work with the reporter to ensure that the fix +is appropriate to their needs, and where possible this should happen prior to +release to pub.dev + +## Closure of the bug + +* Where possible the issue associated with the bug should be closed by mutual +consent with the reporter. This could be: + * The reporter closing the issue because they have found a workaround. + * The reporter closing the issue because they are satisfied with a fix + provided. + * A team member closes the issue after the reporter leaves a comment + indicating that they are happy for it to be closed. +* If the reporter does not respond within 14 calendar days then we must assume +that they no longer have an interest in fixing the bug and work in progress can +be closed out at the team’s discretion. diff --git a/at_login_verify_service/LICENSE b/at_login_verify_service/LICENSE new file mode 100644 index 0000000..caf63d7 --- /dev/null +++ b/at_login_verify_service/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2020, The @ Foundation +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/at_login_verify_service/README.md b/at_login_verify_service/README.md new file mode 100644 index 0000000..2c168ab --- /dev/null +++ b/at_login_verify_service/README.md @@ -0,0 +1,96 @@ + + +# at_login key_verification + +## Overview: + +A simple library to verify if a key exists in an atPlatform Secondary Server. This library can start REST-service for information exchange/. +## Get started: + +### Pre-requisites +Java needs to be installed + +### Clone it from github + +Feel free to fork a copy of the source from the [GitHub Repo](https://github.com/atsign-foundation/at_login) + +### Installation: + +This library is built with maven. Run the following in PROJECT_ROOT command to build the project + +```shell +mvn install +``` +### Output +The jar executable will be generated in PROJECT_ROOT/target with the following name +``` +atlogin-verify-service-1.0-jar-with-dependencies +``` + +## Usage + +### Staring the REST Service + +```shell +java -jar target/atlogin-verify-service-1.0-jar-with-dependencies startRest +``` +The REST Server has now been started on your localhost in port=4567 + +### Using the REST Service +All the end-points only accept POST Requests. Make sure to send a body with the request + +#### 1) Generate +To generate a KeyValue pair of a random UUID that can be used as a verification token. +This end-point accepts a request with a jsonBody containing an entry atsign + +The following shell command can be used to send a POST request to the REST end-point: + +```shell +curl -i localhost:4567/generate -X POST -H 'Content-Type: application/json' -d '{"atsign":"@alice"}' + +``` +Response: +``` +{"key":"public:_4d5afb79-7d0f-4b0a-b7c0-cf732d66b501.atlogin@alice","value":"e3def62c-f583-4747-a777-95091b361464"} +``` + +#### 2) Verify +This end-point can to used to verify if a Key with given Value exists in an atSign's secondary. This end-point accepts a request with a jsonEncoded body that has the following fields - atsign, key, value. + +The following shell command can be used to send a POST request to the REST end-point: + +```shell +curl -i localhost:4567/verify -X POST -H 'Content-Type: application/json' -d '{"atsign":"@libra98extended", "key":"public:_159e24c1-66b8-4889-8840-4601b489c115.atlogin@alice", "value":"b45fcf00-b89f-4ce9-8001-6bca575dd5f2"}' + +``` +Response Case-success: +``` +{ +"responseType" : "success", +"verificationStatus" : "true" +} +``` +Response Case-failure: +``` +{ +"responseType" : "failure", +"error" : "Error while verifying", +"cause" : "java.lang.ClassCastException", +"verificationStatus" : "false" +} +``` +#### 3) Stop +This end-point STOPS the REST service. This request does not need a body + +The following shell command can be used to send a POST request to the REST end-point: +```shell +curl -i localhost:4567/stop -X POST +``` +Response: +``` +true +``` +## Open source usage and contributions + +This is freely licensed open source code, so feel free to use it as is, suggest changes or enhancements or create your +own version. See CONTRIBUTING.md for detailed guidance on how to setup tools, tests and make a pull request. \ No newline at end of file diff --git a/at_login_verify_service/SECURITY.md b/at_login_verify_service/SECURITY.md new file mode 100644 index 0000000..6d5607a --- /dev/null +++ b/at_login_verify_service/SECURITY.md @@ -0,0 +1,41 @@ + + +# Atsign Foundation Open Source Security Policies and Procedures + +This document outlines security procedures and general policies for the +Atsign Foundation Open Source projects as found on +https://github.com/atsign-foundation. + + * [Reporting a Vulnerability](#reporting-a-vulnerability) + * [Disclosure Policy](#disclosure-policy) + +## Reporting a Vulnerability + +The Atsign Foundation team and community take all security vulnerabilities +seriously. Thank you for improving the security of our open source +software. We appreciate your efforts and responsible disclosure and will +make every effort to acknowledge your contributions. + +Report security vulnerabilities by emailing the Atsign security team at: + + security@atsign.com + +The lead maintainer will acknowledge your email within 24 hours, and will +send a more detailed response within 48 hours indicating the next steps in +handling your report. After the initial reply to your report, the security +team will endeavor to keep you informed of the progress towards a fix and +full announcement, and may ask for additional information or guidance. + +Please report security vulnerabilities in third-party modules to the person +or team maintaining the module. + +## Disclosure Policy + +When the security team receives a security bug report, they will assign it +to a primary handler. This person will coordinate the fix and release +process, involving the following steps: + + * Confirm the problem and determine the affected versions. + * Audit code to find any potential similar problems. + * Prepare fixes for all releases still under maintenance. These fixes + will be released as fast as possible to pub.dev where applicable. \ No newline at end of file diff --git a/at_login_verify_service/code_of_conduct.md b/at_login_verify_service/code_of_conduct.md new file mode 100644 index 0000000..072d50a --- /dev/null +++ b/at_login_verify_service/code_of_conduct.md @@ -0,0 +1,137 @@ + + +# The Atsign Foundation Code of Conduct + +Based on +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](code_of_conduct.md) + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +conduct@atsign.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available +at [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/at_login_verify_service/pom.xml b/at_login_verify_service/pom.xml new file mode 100644 index 0000000..a64c2cc --- /dev/null +++ b/at_login_verify_service/pom.xml @@ -0,0 +1,108 @@ + + 4.0.0 + org.atsign + atlogin-verify-service + 1.0 + + Archetype - main + https://maven.apache.org + + 11 + 11 + + + + + + + maven-assembly-plugin + + + package + + single + + + + + + + true + org.atsign.atlogin.Main + + + + jar-with-dependencies + + + + + + + src/main/resources + + + + + + + + + com.sparkjava + spark-core + 2.7.2 + + + + com.fasterxml.jackson.core + jackson-core + 2.14.0 + + + + com.fasterxml.jackson.core + jackson-annotations + 2.14.0 + + + + com.fasterxml.jackson.core + jackson-databind + 2.14.0 + + + + org.slf4j + slf4j-api + 1.7.36 + + + org.slf4j + slf4j-log4j12 + 1.7.36 + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.14.0 + + + + junit + junit + 4.13.2 + test + + + + org.mockito + mockito-all + 1.9.5 + test + + + + + diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/Main.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/Main.java new file mode 100644 index 0000000..cf0a9d0 --- /dev/null +++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/Main.java @@ -0,0 +1,34 @@ +package org.atsign.atlogin; + +import org.atsign.atlogin.rest.AtLoginRestImpl; +import org.atsign.atlogin.rest.AtLoginRestWrapper; +import org.atsign.atlogin.service.AtLoginService; +import org.atsign.atlogin.service.AtLoginServiceImpl; +import org.atsign.atlogin.util.ConfigReader; +import org.atsign.atlogin.util.KeyPair; + +import java.io.IOException; + +public class Main { + + public static void main(String[] args) throws IOException { + String rootHost = ConfigReader.getProperty("rootServer", "domain"); + String rootPort = ConfigReader.getProperty("rootServer", "port"); + AtLoginRestWrapper restWrapper = new AtLoginRestImpl(rootHost, rootPort); + if ("startRest".equals(args[0])) { + restWrapper.start(); + } else if ("generateAuthKeyValue".equals(args[0])) { + AtLoginService atLogin = new AtLoginServiceImpl(rootHost, rootPort); + KeyPair keyPair = atLogin.generateAuthenticationKeyAndValue(args[1]); + System.out.println(keyPair.toJson()); + } else if ("verify".equals(args[0])) { + AtLoginService atLogin = new AtLoginServiceImpl(rootHost, rootPort); + if (atLogin.verifyKey(args[0], args[1], args[2])) { + System.out.println("Verified"); + } else { + System.out.println("Verification Failed"); + } + } + + } +} diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestImpl.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestImpl.java new file mode 100644 index 0000000..198bffb --- /dev/null +++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestImpl.java @@ -0,0 +1,74 @@ +package org.atsign.atlogin.rest; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.log4j.BasicConfigurator; +import org.atsign.atlogin.service.AtLoginServiceImpl; +import org.atsign.atlogin.util.ErrorResponse; +import org.atsign.atlogin.util.KeyPair; +import org.atsign.atlogin.util.SuccessResponse; +import spark.Spark; + +import java.util.Map; + +@SuppressWarnings("unchecked") +public class AtLoginRestImpl implements AtLoginRestWrapper { + static final ObjectMapper mapper = new ObjectMapper(); + String rootHost; + String rootPort; + + public AtLoginRestImpl(String rootHost, String rootPort) { + this.rootHost = rootHost; + this.rootPort = rootPort; + } + + public void start() { + BasicConfigurator.configure(); + Spark.init(); + Spark.awaitInitialization(); + + Spark.post("/generate", ((request, response) -> generateUuidKeypair(String.valueOf(request.body())))); + Spark.post("/verify", ((request, response) -> verify(request.body()))); + Spark.post("/stop", (request, response) -> stop()); + } + + private boolean stop() { + Spark.stop(); + return true; + } + + private String verify(String body) throws JsonProcessingException { + Map postParams; + boolean isVerified; + try { + postParams = processRequestBody(body); + } catch (Exception e) { + return new ErrorResponse("Failed processing request body", e.toString()).toJson(); + } + + AtLoginServiceImpl loginService = new AtLoginServiceImpl(rootHost, rootPort); + try { + isVerified = loginService.verifyKey(postParams.get("atsign"), postParams.get("key"), postParams.get("value")); + } catch (Exception e) { + return new ErrorResponse("Error while verifying", e.toString()).toJson(); + } + + return new SuccessResponse(isVerified).toJson(); + } + + private String generateUuidKeypair(String jsonBody) throws JsonProcessingException { + AtLoginServiceImpl loginService = new AtLoginServiceImpl(rootHost, rootPort); + Map postBody = processRequestBody(jsonBody); + System.out.println("Generating UUID Keypair for " + postBody.get("atsign")); + KeyPair keyPair = loginService.generateAuthenticationKeyAndValue(postBody.get("atsign")); + return keyPair.toJson(); + } + + private Map processRequestBody(String jsonBody) throws JsonProcessingException { + Map parmsMap; + parmsMap = mapper.readValue(jsonBody, Map.class); + System.out.println("[AtVerify REST Wrapper] Request Params are: " + parmsMap); + + return parmsMap; + } +} diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestWrapper.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestWrapper.java new file mode 100644 index 0000000..e2ac803 --- /dev/null +++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestWrapper.java @@ -0,0 +1,11 @@ +package org.atsign.atlogin.rest; + +public interface AtLoginRestWrapper { + + /** + * Starts the REST-Service for AtKey verification. + * Service runs on port=4567 by default. + * To stop this service call host:4567/stop + */ + void start(); +} diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginService.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginService.java new file mode 100644 index 0000000..8f2a675 --- /dev/null +++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginService.java @@ -0,0 +1,42 @@ +package org.atsign.atlogin.service; + +import org.atsign.atlogin.util.AtLoginUtil; +import org.atsign.atlogin.util.KeyPair; + +import java.io.IOException; +import java.util.UUID; + +/** + * Contains methods to help login with an atSign + */ +public interface AtLoginService { + + /** + * Verifies if the given key is present with the given value value for the atSign + * + * @param atSign + * @param key + * @param value + * @return true if the value is present in the secondary, else returns false + * @throws Exception the value cannot be looked up due to any network related issues + */ + boolean verifyKey(String atSign, String key, String value) throws IOException; + + /** + * Creates a KeyPair for the given atsign that can be used as authentication token. + * Generates a random UUID that is later formatted into an AtKey format + * + * @param atSign + * @return A KeyPair class with Key and Value that are ready to be put into an atSign secondary + */ + default KeyPair generateAuthenticationKeyAndValue(String atSign) { + // Create a key in the format . format + // UUID is the entity and .atLogin is the namespace + String partKey = UUID.randomUUID() + ".atlogin"; + KeyPair keyValue = new KeyPair(); + keyValue.key = AtLoginUtil.formatAsHiddenPublicKey(partKey, atSign); + keyValue.value = UUID.randomUUID().toString(); + return keyValue; + } + +} diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginServiceImpl.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginServiceImpl.java new file mode 100644 index 0000000..00328c4 --- /dev/null +++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginServiceImpl.java @@ -0,0 +1,101 @@ +package org.atsign.atlogin.service; + +import javax.net.SocketFactory; +import javax.net.ssl.SSLSocketFactory; +import java.io.IOException; +import java.io.PrintWriter; +import java.net.Socket; +import java.net.SocketException; +import java.util.Scanner; + +import static org.atsign.atlogin.util.AtLoginUtil.*; + +public class AtLoginServiceImpl implements AtLoginService { + String rootHost; + String rootPort; + + public AtLoginServiceImpl(String rootHost, String rootPort) { + this.rootHost = rootHost; + this.rootPort = rootPort; + } + + public boolean verifyKey(String atsign, String key, String value) throws IOException { + validateParameter(atsign, "atsign"); + validateParameter(key, "key"); + validateParameter(value, "value"); + + Socket secondarySocket = getSecondarySocket(atsign); + // lookup for key + String response; + try { + response = executeCommand("lookup:" + formatKey(key, atsign), + new PrintWriter(secondarySocket.getOutputStream()), + new Scanner(secondarySocket.getInputStream())); + response = response.replaceFirst("@data:", ""); + } catch (Exception e){ + System.out.println("[Verify Service] Caught Exception: " + e); + throw new SocketException("Unable to lookup key" + key + "on secondary"); + } + System.out.println("[Verify Service] Created socket to secondary server successfully"); + return response.equals(value); + } + + private Socket getSecondarySocket(String atsign) throws SocketException { + // create socket to RootServer + Socket rootSocket; + try { + rootSocket = createSocket(rootHost, rootPort); + } catch (Exception e){ + System.out.println("[Verify Service] Caught Exception: " + e); + throw new SocketException("Unable to connect to root secondary"); + } + System.out.println("[Verify Service] Opened a socket to RootServer successfully"); + // get secondary address + String response; + try { + response = executeCommand(formatAtsign(atsign, false), + new PrintWriter(rootSocket.getOutputStream()), + new Scanner(rootSocket.getInputStream())); + } catch (Exception e){ + System.out.println("[Verify Service] Caught Exception: " + e); + throw new SocketException("Unable to find address for atsign: " + atsign); + } + response = response.replace("@", ""); + String secondaryHost = response.split(":")[0]; + String secondaryPort = response.split(":")[1]; + + // create socket for SecondaryServer + Socket secondarySocket; + try { + secondarySocket = createSocket(secondaryHost, secondaryPort); + } catch (Exception e){ + System.out.println("[Verify Service] Caught Exception: " + e); + throw new SocketException("Unable to connect to secondary server for: " + atsign); + } + return secondarySocket; + } + + private Socket createSocket(String host, String port) throws SocketException { + SocketFactory socketFactory = SSLSocketFactory.getDefault(); + Socket socket; + try { + socket = socketFactory.createSocket(host, Integer.parseInt(port)); + } catch (Exception e){ + System.out.println("[Verify Service] Caught exception: " + e); + throw new SocketException("Unable to create socket for: host=" + host + "port=" + port); + } + return socket; + } + + private String executeCommand(String command, PrintWriter socketWriter, Scanner socketScanner) { + // input atsign into the rootServer + String command1 = command + "\n"; + System.out.println("[Verify Service] Executing command :" + command1); + socketWriter.write(command1); + socketWriter.flush(); + // fetch secondary address from root server + String response = socketScanner.nextLine(); + System.out.println("[Verify Service] Got response: " + response); + return response; + } +} \ No newline at end of file diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/util/AtLoginUtil.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/util/AtLoginUtil.java new file mode 100644 index 0000000..506b66d --- /dev/null +++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/util/AtLoginUtil.java @@ -0,0 +1,50 @@ +package org.atsign.atlogin.util; + +public class AtLoginUtil { + + public static String formatAsHiddenPublicKey(String key, String atSign) { + return "__" + key + formatAtsign(atSign, true); + } + + /** + * Formats the atsign as per the requirement of the caller + * + * @param atsign the atsign that is to be formatted + * @param keepAtSymbol specifies the format requirement of the caller. + * When true: ensures atsign starts with an "@". + * When false: ensures atsign does not start with "@". + */ + public static String formatAtsign(String atsign, boolean keepAtSymbol) { + if (keepAtSymbol && !atsign.startsWith("@")) { + return '@' + atsign; + } else if (!keepAtSymbol && atsign.startsWith("@")) { + return atsign.replaceAll("@", ""); + } + return atsign; + } + + /** + * Ensure that the parameter is not null or does not contain an empty value + * + * @param parameter is the parameter that is to be validated + * @param paramName is the name of the parameter + *

+ * throws IllegalArgumentException if the parameter is null or empty + * Does not throw any exception or return anything when the param is valid + */ + public static void validateParameter(String parameter, String paramName) { + if (parameter == null || parameter.equals("")) { + throw new IllegalArgumentException("Invalid argument provided for parameter: " + paramName); + } + } + + public static String formatKey(String key, String atsign){ + if(key.contains("public:")){ + key = key.replace("public:", ""); + } + if(!key.contains(atsign)){ + return key + formatAtsign(atsign, true); + } + return key; + } +} diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/util/ConfigReader.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/util/ConfigReader.java new file mode 100644 index 0000000..c4b8680 --- /dev/null +++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/util/ConfigReader.java @@ -0,0 +1,42 @@ +package org.atsign.atlogin.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +/** + * Loads, reads and returns properties from the configuration file in the resources + */ +public class ConfigReader { + private static final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + private static HashMap config; + + public static String getProperty(String property, String subProperty) throws IOException { + if (config == null) { + loadConfig(); + } + @SuppressWarnings("unchecked") + Map propertyMap = (Map) config.get(property); + return propertyMap.get(subProperty); + } + + public static String getProperty(String property) throws IOException { + if (config == null) { + loadConfig(); + } + return (String) config.get(property); + } + + /** + * Loads configuration properties from the yaml provided in the java/src/main/resources + * Stores these key-value pairs in the config map + */ + public static void loadConfig() throws IOException { + InputStream inputStream = ClassLoader.getSystemResourceAsStream("config.yaml"); + config = mapper.readValue(inputStream, HashMap.class); + } +} \ No newline at end of file diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/util/ErrorResponse.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/util/ErrorResponse.java new file mode 100644 index 0000000..68c05c5 --- /dev/null +++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/util/ErrorResponse.java @@ -0,0 +1,28 @@ +package org.atsign.atlogin.util; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Wrapper class for REST-Response in case of failure + */ +public class ErrorResponse { + String error; + String cause; + + public ErrorResponse(String error, String cause) { + this.error = error; + this.cause = cause; + } + + public String toJson() throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode node = mapper.createObjectNode(); + node.put("responseType", "failure"); + node.put("error", error); + node.put("cause", cause); + node.put("verificationStatus", "false"); + return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(node); + } +} diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/util/KeyPair.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/util/KeyPair.java new file mode 100644 index 0000000..acd7949 --- /dev/null +++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/util/KeyPair.java @@ -0,0 +1,21 @@ +package org.atsign.atlogin.util; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Bean type class to handle a KeyPair + */ +public class KeyPair { + public String key; + public String value; + + public String toJson() throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode node = mapper.createObjectNode(); + node.put("key", this.key); + node.put("value", this.value); + return mapper.writeValueAsString(node); + } +} diff --git a/at_login_verify_service/src/main/java/org/atsign/atlogin/util/SuccessResponse.java b/at_login_verify_service/src/main/java/org/atsign/atlogin/util/SuccessResponse.java new file mode 100644 index 0000000..795a9f5 --- /dev/null +++ b/at_login_verify_service/src/main/java/org/atsign/atlogin/util/SuccessResponse.java @@ -0,0 +1,24 @@ +package org.atsign.atlogin.util; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Wrapper class for REST-Response for a successful API call + */ +public class SuccessResponse { + boolean verifyStatus; + + public SuccessResponse(boolean verifyStatus) { + this.verifyStatus = verifyStatus; + } + + public String toJson() throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode node = mapper.createObjectNode(); + node.put("responseType", "success"); + node.put("verificationStatus", verifyStatus); + return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(node); + } +} diff --git a/at_login_verify_service/src/main/resources/META-INF/maven/archetype.xml b/at_login_verify_service/src/main/resources/META-INF/maven/archetype.xml new file mode 100644 index 0000000..ac0f01d --- /dev/null +++ b/at_login_verify_service/src/main/resources/META-INF/maven/archetype.xml @@ -0,0 +1,9 @@ + + main + + src/main/java/App.java + + + src/test/java/AppTest.java + + diff --git a/at_login_verify_service/src/main/resources/archetype-resources/pom.xml b/at_login_verify_service/src/main/resources/archetype-resources/pom.xml new file mode 100644 index 0000000..f982f15 --- /dev/null +++ b/at_login_verify_service/src/main/resources/archetype-resources/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + $org.example + $main + $1.0-SNAPSHOT + + + junit + junit + 3.8.1 + test + + + diff --git a/at_login_verify_service/src/main/resources/archetype-resources/src/main/java/App.java b/at_login_verify_service/src/main/resources/archetype-resources/src/main/java/App.java new file mode 100644 index 0000000..339ba84 --- /dev/null +++ b/at_login_verify_service/src/main/resources/archetype-resources/src/main/java/App.java @@ -0,0 +1,10 @@ +package $org.example; + +/** + * Hello world! + */ +public class App { + public static void main(String[] args) { + System.out.println("Hello World!"); + } +} diff --git a/at_login_verify_service/src/main/resources/archetype-resources/src/test/java/AppTest.java b/at_login_verify_service/src/main/resources/archetype-resources/src/test/java/AppTest.java new file mode 100644 index 0000000..c56bc63 --- /dev/null +++ b/at_login_verify_service/src/main/resources/archetype-resources/src/test/java/AppTest.java @@ -0,0 +1,34 @@ +package $org.example; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase { + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest(String testName) { + super(testName); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() { + return new TestSuite(AppTest.class); + } + + /** + * Rigourous Test :-) + */ + public void testApp() { + assertTrue(true); + } +} diff --git a/at_login_verify_service/src/main/resources/config.yaml b/at_login_verify_service/src/main/resources/config.yaml new file mode 100644 index 0000000..cb7f7a2 --- /dev/null +++ b/at_login_verify_service/src/main/resources/config.yaml @@ -0,0 +1,3 @@ +rootServer: + domain: "root.atsign.org" + port: "64" \ No newline at end of file diff --git a/at_login_verify_service/src/test/java/org/atsign/atlogin/service/AtLoginServiceTest.java b/at_login_verify_service/src/test/java/org/atsign/atlogin/service/AtLoginServiceTest.java new file mode 100644 index 0000000..e8e59f2 --- /dev/null +++ b/at_login_verify_service/src/test/java/org/atsign/atlogin/service/AtLoginServiceTest.java @@ -0,0 +1,23 @@ +package org.atsign.atlogin.service; + +import org.mockito.Mock; + +import java.io.PrintWriter; +import java.net.Socket; +import java.util.Scanner; + +public class AtLoginServiceTest { + + +} + +class MockSocket{ + @Mock + Socket socket; + + @Mock + PrintWriter writer; + + @Mock + Scanner input; +} diff --git a/at_login_verify_service/src/test/java/org/atsign/atlogin/util/AtLoginUtilTest.java b/at_login_verify_service/src/test/java/org/atsign/atlogin/util/AtLoginUtilTest.java new file mode 100644 index 0000000..5b8e3b3 --- /dev/null +++ b/at_login_verify_service/src/test/java/org/atsign/atlogin/util/AtLoginUtilTest.java @@ -0,0 +1,47 @@ +package org.atsign.atlogin.util; + +import org.junit.Test; + +import static org.atsign.atlogin.util.AtLoginUtil.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +public class AtLoginUtilTest { + + @Test + public void formatAsHiddenPublicKeyTest(){ + assertEquals ("__test_key@alice", formatAsHiddenPublicKey("test_key", "alice")); + assertEquals ("__test_key1@bob", formatAsHiddenPublicKey("test_key1", "@bob")); + } + + @Test + public void formatAtsignTest(){ + assertEquals ("@alice", formatAtsign("alice", true)); + assertEquals ("@alice", formatAtsign("@alice", true)); + + assertEquals ("bob", formatAtsign("bob", false)); + assertEquals ("bob", formatAtsign("@bob", false)); + } + + @Test + public void formatKeyTest(){ + assertEquals ("test_key@charles", formatKey("test_key", "charles")); + assertEquals ("test_key@charles", formatKey("test_key", "@charles")); + + assertEquals ("__test_key@charles", formatKey("__test_key@charles", "charles")); + assertEquals ("__test_key@charles", formatKey("__test_key@charles", "@charles")); + + assertEquals ("__test_key@charles", formatKey("public:__test_key", "charles")); + assertEquals ("test_key@charles", formatKey("public:test_key", "@charles")); + } + + @Test + public void validateParamTest(){ + assertThrows(IllegalArgumentException.class, + () -> validateParameter("", "testParam")); + assertThrows(IllegalArgumentException.class, + () -> validateParameter(null, "testParam")); + + } + +} diff --git a/at_login_verify_service/src/test/java/org/atsign/atlogin/util/ConfigReaderTest.java b/at_login_verify_service/src/test/java/org/atsign/atlogin/util/ConfigReaderTest.java new file mode 100644 index 0000000..766818c --- /dev/null +++ b/at_login_verify_service/src/test/java/org/atsign/atlogin/util/ConfigReaderTest.java @@ -0,0 +1,20 @@ +package org.atsign.atlogin.util; + +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +public class ConfigReaderTest { + + @Test + public void getRootDomain() throws IOException { + assertEquals("root.atsign.org", ConfigReader.getProperty("rootServer", "domain")); + } + + @Test + public void getRootPort() throws IOException { + assertEquals("64", ConfigReader.getProperty("rootServer", "port")); + } +} diff --git a/at_login_verify_service/target/atlogin-verify-service-1.0-jar-with-dependencies.jar b/at_login_verify_service/target/atlogin-verify-service-1.0-jar-with-dependencies.jar new file mode 100644 index 0000000..f636b47 Binary files /dev/null and b/at_login_verify_service/target/atlogin-verify-service-1.0-jar-with-dependencies.jar differ diff --git a/at_login_verify_service/target/atlogin-verify-service-1.0.jar b/at_login_verify_service/target/atlogin-verify-service-1.0.jar new file mode 100644 index 0000000..f1b3e4d Binary files /dev/null and b/at_login_verify_service/target/atlogin-verify-service-1.0.jar differ diff --git a/at_login_verify_service/target/classes/META-INF/maven/archetype.xml b/at_login_verify_service/target/classes/META-INF/maven/archetype.xml new file mode 100644 index 0000000..ac0f01d --- /dev/null +++ b/at_login_verify_service/target/classes/META-INF/maven/archetype.xml @@ -0,0 +1,9 @@ + + main + + src/main/java/App.java + + + src/test/java/AppTest.java + + diff --git a/at_login_verify_service/target/classes/archetype-resources/pom.xml b/at_login_verify_service/target/classes/archetype-resources/pom.xml new file mode 100644 index 0000000..f982f15 --- /dev/null +++ b/at_login_verify_service/target/classes/archetype-resources/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + $org.example + $main + $1.0-SNAPSHOT + + + junit + junit + 3.8.1 + test + + + diff --git a/at_login_verify_service/target/classes/archetype-resources/src/main/java/App.java b/at_login_verify_service/target/classes/archetype-resources/src/main/java/App.java new file mode 100644 index 0000000..339ba84 --- /dev/null +++ b/at_login_verify_service/target/classes/archetype-resources/src/main/java/App.java @@ -0,0 +1,10 @@ +package $org.example; + +/** + * Hello world! + */ +public class App { + public static void main(String[] args) { + System.out.println("Hello World!"); + } +} diff --git a/at_login_verify_service/target/classes/archetype-resources/src/test/java/AppTest.java b/at_login_verify_service/target/classes/archetype-resources/src/test/java/AppTest.java new file mode 100644 index 0000000..c56bc63 --- /dev/null +++ b/at_login_verify_service/target/classes/archetype-resources/src/test/java/AppTest.java @@ -0,0 +1,34 @@ +package $org.example; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase { + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest(String testName) { + super(testName); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() { + return new TestSuite(AppTest.class); + } + + /** + * Rigourous Test :-) + */ + public void testApp() { + assertTrue(true); + } +} diff --git a/at_login_verify_service/target/classes/config.yaml b/at_login_verify_service/target/classes/config.yaml new file mode 100644 index 0000000..cb7f7a2 --- /dev/null +++ b/at_login_verify_service/target/classes/config.yaml @@ -0,0 +1,3 @@ +rootServer: + domain: "root.atsign.org" + port: "64" \ No newline at end of file diff --git a/at_login_verify_service/target/maven-archiver/pom.properties b/at_login_verify_service/target/maven-archiver/pom.properties new file mode 100644 index 0000000..f2e12fa --- /dev/null +++ b/at_login_verify_service/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 20 19:14:40 IST 2023 +groupId=org.atsign +artifactId=atlogin-verify-service +version=1.0 diff --git a/at_login_verify_service/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/at_login_verify_service/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..716be72 --- /dev/null +++ b/at_login_verify_service/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,10 @@ +org/atsign/atlogin/service/AtLoginService.class +org/atsign/atlogin/rest/AtLoginRestImpl.class +org/atsign/atlogin/util/KeyPair.class +org/atsign/atlogin/rest/AtLoginRestWrapper.class +org/atsign/atlogin/service/AtLoginServiceImpl.class +org/atsign/atlogin/util/ConfigReader.class +org/atsign/atlogin/util/SuccessResponse.class +org/atsign/atlogin/Main.class +org/atsign/atlogin/util/AtLoginUtil.class +org/atsign/atlogin/util/ErrorResponse.class diff --git a/at_login_verify_service/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/at_login_verify_service/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..8a9c665 --- /dev/null +++ b/at_login_verify_service/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,10 @@ +/home/srie/Desktop/work/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestImpl.java +/home/srie/Desktop/work/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginService.java +/home/srie/Desktop/work/at_login_verify_service/src/main/java/org/atsign/atlogin/util/AtLoginUtil.java +/home/srie/Desktop/work/at_login_verify_service/src/main/java/org/atsign/atlogin/service/AtLoginServiceImpl.java +/home/srie/Desktop/work/at_login_verify_service/src/main/java/org/atsign/atlogin/util/SuccessResponse.java +/home/srie/Desktop/work/at_login_verify_service/src/main/java/org/atsign/atlogin/Main.java +/home/srie/Desktop/work/at_login_verify_service/src/main/java/org/atsign/atlogin/rest/AtLoginRestWrapper.java +/home/srie/Desktop/work/at_login_verify_service/src/main/java/org/atsign/atlogin/util/ErrorResponse.java +/home/srie/Desktop/work/at_login_verify_service/src/main/java/org/atsign/atlogin/util/ConfigReader.java +/home/srie/Desktop/work/at_login_verify_service/src/main/java/org/atsign/atlogin/util/KeyPair.java diff --git a/at_login_verify_service/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/at_login_verify_service/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst new file mode 100644 index 0000000..fa0ed62 --- /dev/null +++ b/at_login_verify_service/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst @@ -0,0 +1,4 @@ +org/atsign/atlogin/service/AtLoginServiceTest.class +org/atsign/atlogin/util/ConfigReaderTest.class +org/atsign/atlogin/service/MockSocket.class +org/atsign/atlogin/util/AtLoginUtilTest.class diff --git a/at_login_verify_service/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/at_login_verify_service/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..eb9dd2e --- /dev/null +++ b/at_login_verify_service/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst @@ -0,0 +1 @@ +/home/srie/Desktop/work/at_login_verify_service/src/test/java/org/atsign/atlogin/util/AtLoginUtilTest.java diff --git a/at_login_verify_service/target/surefire-reports/TEST-org.atsign.atlogin.util.AtLoginUtilTest.xml b/at_login_verify_service/target/surefire-reports/TEST-org.atsign.atlogin.util.AtLoginUtilTest.xml new file mode 100644 index 0000000..8e59b74 --- /dev/null +++ b/at_login_verify_service/target/surefire-reports/TEST-org.atsign.atlogin.util.AtLoginUtilTest.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/at_login_verify_service/target/surefire-reports/TEST-org.atsign.atlogin.util.ConfigReaderTest.xml b/at_login_verify_service/target/surefire-reports/TEST-org.atsign.atlogin.util.ConfigReaderTest.xml new file mode 100644 index 0000000..0ae5382 --- /dev/null +++ b/at_login_verify_service/target/surefire-reports/TEST-org.atsign.atlogin.util.ConfigReaderTest.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/at_login_verify_service/target/surefire-reports/org.atsign.atlogin.util.AtLoginUtilTest.txt b/at_login_verify_service/target/surefire-reports/org.atsign.atlogin.util.AtLoginUtilTest.txt new file mode 100644 index 0000000..d5dc909 --- /dev/null +++ b/at_login_verify_service/target/surefire-reports/org.atsign.atlogin.util.AtLoginUtilTest.txt @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: org.atsign.atlogin.util.AtLoginUtilTest +------------------------------------------------------------------------------- +Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.153 sec diff --git a/at_login_verify_service/target/surefire-reports/org.atsign.atlogin.util.ConfigReaderTest.txt b/at_login_verify_service/target/surefire-reports/org.atsign.atlogin.util.ConfigReaderTest.txt new file mode 100644 index 0000000..476600f --- /dev/null +++ b/at_login_verify_service/target/surefire-reports/org.atsign.atlogin.util.ConfigReaderTest.txt @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: org.atsign.atlogin.util.ConfigReaderTest +------------------------------------------------------------------------------- +Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.067 sec diff --git a/node_demo_server_atLogin/README.md b/node_demo_server_atLogin/README.md new file mode 100644 index 0000000..93ac56d --- /dev/null +++ b/node_demo_server_atLogin/README.md @@ -0,0 +1,76 @@ +# At Login Demo - Codebase + +## Description : + +1. This project demonstrates password less login using @sign +2. This project consumes @login as REST +3. this Project uses two java REST end points + + a. Generate : http://localhost:4567/generate + + b. Verify : http://localhost:4567/verify + + +## How to run Java server +Open a terminal at jar located folder and run below command + + java -jar atlogin-verify-service-1.0-jar-with-dependencies.jar startRest + + +## Environmental Setup + +### Required pieces of software: + + Node v10.24.1 + Visual Studio Code v11.0 + +### Installation Instructions + +##### 1. Node v10.24.1 (LTS) + + +Install and setup Node according to the OS using below link + +- **Ubuntu**: + +Execute following commands in the terminal + ``` .tm +sudo apt-get update + ``` + ``` .tm +sudo apt-get install build-essential libssl-dev curl + ``` + ``` .tm +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash + ``` + ``` .tm +source ~/.bashrc + ``` + ``` .tm +nvm install 10 + ``` + + +##### 2. Visual Studio Code + +**Install and setup VS Code according to the OS using below link** + +[https://code.visualstudio.com/download](https://code.visualstudio.com/download) + +## Project Execution: + +**To build the node modules, run the command below :** +```.tm +npm i +``` + +**To run the project, execute the command below :** +```.tm +node index.js +``` + +**Go to any internet browser and enter below link** +```.tm +http://localhost:5000/loginPage +``` + diff --git a/node_demo_server_atLogin/atlogin-verify-service-1.0-jar-with-dependencies.jar b/node_demo_server_atLogin/atlogin-verify-service-1.0-jar-with-dependencies.jar new file mode 100644 index 0000000..ce5ccfc Binary files /dev/null and b/node_demo_server_atLogin/atlogin-verify-service-1.0-jar-with-dependencies.jar differ diff --git a/node_demo_server_atLogin/index.js b/node_demo_server_atLogin/index.js new file mode 100644 index 0000000..ebbbbf6 --- /dev/null +++ b/node_demo_server_atLogin/index.js @@ -0,0 +1,129 @@ +const express = require('express'); +const fetch = require('node-fetch'); +const btoa = require('btoa'); +const { v5: uuidv5 } = require('uuid'); +require('dotenv').config(); +const app = express(); +const port = 5000; + +const fs = require('fs'); +const cheerio = require('cheerio'); +const { Console } = require('console'); + +app.use(express.static(__dirname + '/styling')); +app.use(express.static(__dirname + '/pages')); + +// for parsing application/json +app.use(express.json()); + +// for parsing application/x-www-form-urlencoded +app.use(express.urlencoded({ extended: true })); + + +app.get('/loginPage', (req, res) => { + res.sendFile('pages/client.html', {root: __dirname}); +}); + +app.get('/login', (req, res) => { + + console.log("url********"+req.url); + var atsign = req.url.split('?')[1].split('=')[1].split('%40')[1]; + console.log("key------------"+atsign); + // make a request to the server-side endpoint + fetch("http://localhost:4567/generate", { + method: "POST", + headers : { + 'Content-Type': 'application/json', + + }, + body: JSON.stringify({ + 'atsign': "@"+atsign, + + }) + .toString() + }) + .then(response => response.json()) + .then(data => { + console.log("keyValuePair", data); + if (data.key != null) { + // Convert the response data to JSON String + const jsonData = JSON.stringify(data); + + // Write the JSON data to a file + fs.writeFile('pages/uuid.json', jsonData, (err) => { + if (err) throw err; + console.log('Data saved to file'); + }); + // redirect to login page + res.sendFile('pages/login.html', {root: __dirname}); + } else { + console.log("Failed to get access token. Please try again."); + } + }) + .catch(error => { + console.error(error); + }); +}); + + +app.get('/loginResponse', (req, res) => { + var key; + var value; + var atsign; + // read json using fs + fs.readFile('pages/uuid.json', 'utf8', function (err, data) { + if (err) throw err; + // fetch the uuid json data + key = JSON.parse(data).key; + value = JSON.parse(data).value; + atsign = "@" +key.split("@")[1] + // console.log("object----"+data); + // make a request to the server-side endpoint + fetch("http://localhost:4567/verify", { + method: "POST", + headers : { + 'Content-Type': 'application/json', + + }, + body: JSON.stringify({ + "atsign": atsign, + "key": key, + "value": value, + }) + .toString() + }) + .then(response => response.json()) + .then(data => { + console.log("response", data); + console.log("responseTyoe", data.responseType); + if (data.responseType != null) { + // Convert the response data to JSON String + const jsonData = JSON.stringify(data); + // Write the JSON data to a file + fs.writeFile('pages/response_json.json', jsonData, (err) => { + if (err) throw err; + console.log('output saved to file'); + console.log(data.verificationStatus); + // check VerificationStatus + if(data.verificationStatus==true){ + res.sendFile('pages/loginResponse.html', {root: __dirname}); + } else if(data.verificationStatus==false){ + res.sendFile('pages/login.html', {root: __dirname}); + res.end(); + } + }); + } else { + console.log("verification failed. Please try again."); + } + }) + .catch(error => { + console.error(error); + }); + + }); + +}); + +app.listen(port, () => { + console.log(`Now listening on port ${port}`); +}); \ No newline at end of file diff --git a/node_demo_server_atLogin/package-lock.json b/node_demo_server_atLogin/package-lock.json new file mode 100644 index 0000000..1a58071 --- /dev/null +++ b/node_demo_server_atLogin/package-lock.json @@ -0,0 +1,785 @@ +{ + "name": "oauth-node-server", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "alert": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/alert/-/alert-5.1.4.tgz", + "integrity": "sha512-fVgDH06nzfNvaBp5+KPgTL4ezq2FrwzQ10l5626Txyelf7xp7ZbskIBu/c4tHCv/0JJ8vLwZy+sIbO+dKORcYA==", + "requires": { + "is-program-installed": "2.3.4" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "axios": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz", + "integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "btoa": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", + "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==" + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "requires": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + } + }, + "cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "requires": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "requires": { + "domelementtype": "^2.3.0" + } + }, + "domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + } + }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "requires": { + "jake": "^10.8.5" + } + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "requires": { + "minimatch": "^5.0.1" + }, + "dependencies": { + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + } + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-program-installed": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/is-program-installed/-/is-program-installed-2.3.4.tgz", + "integrity": "sha512-b4e65BxUsiLkoFSOu8RAca7Rz7rPvnbw0u0lS431BFyI37C4lM6F+OjQ5DNODMakjKfcoOY9aeaPqXgFoezhsg==" + }, + "jake": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "requires": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "node-fetch": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "requires": { + "boolbase": "^1.0.0" + } + }, + "object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, + "parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "requires": { + "entities": "^4.4.0" + } + }, + "parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "requires": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "popups": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/popups/-/popups-1.1.3.tgz", + "integrity": "sha512-2sQ2KuUHXx3L8CxLX3JDfVnenNKbcjXIhfy94mvs08VhnxTLSBNShaUEEeOJxf8Hz6rcv2EphMiycFipyNd2ig==" + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + }, + "uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } +} diff --git a/node_demo_server_atLogin/package.json b/node_demo_server_atLogin/package.json new file mode 100644 index 0000000..36b5fb2 --- /dev/null +++ b/node_demo_server_atLogin/package.json @@ -0,0 +1,23 @@ +{ + "name": "oauth-node-server", + "version": "1.0.0", + "description": "nodejs server for oauth", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "shris", + "license": "ISC", + "dependencies": { + "alert": "^5.1.4", + "axios": "^1.3.5", + "btoa": "^1.2.1", + "cheerio": "^1.0.0-rc.12", + "dotenv": "^16.0.3", + "ejs": "^3.1.9", + "express": "^4.18.2", + "node-fetch": "^2.6.6", + "popups": "^1.1.3", + "uuid": "^9.0.0" + } +} diff --git a/node_demo_server_atLogin/styling/authentication_style.css b/node_demo_server_atLogin/styling/authentication_style.css new file mode 100644 index 0000000..1d607bd --- /dev/null +++ b/node_demo_server_atLogin/styling/authentication_style.css @@ -0,0 +1,87 @@ +body { + font-family: Arial, sans-serif; + background-color: #F0F0F0; +} +form { + background-color: #FFF; + border-radius: 5px; + padding: 20px; + width: 300px; + margin: 0 auto; + margin-top: 100px; + box-shadow: 0px 2px 5px rgba(0,0,0,0.3); +} +h2 { + text-align: center; + margin-top: 0; +} +input[type=text]{ + width: 100%; + padding: 12px 20px; + margin: 8px 0; + display: inline-block; + border: 1px solid #ccc; + border-radius: 4px; + box-sizing: border-box; +} +.center { + display: block; + margin-left: auto; + margin-right: auto; + width: 50%; +} + + + + +.button-container { + display: flex; + justify-content: space-between; + width: 200px; + margin: 20px auto; + } + + + +h1 { + font-size: 36px; + margin-bottom: 20px; + } + + #refresh-btn { + background-color: #4CAF50; + border: none; + color: white; + padding: 10px 20px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin-top: 20px; + cursor: pointer; + border-radius: 5px; + } + + #refresh-btn:hover { + background-color: #3e8e41; + } + + #login-btn { + background-color: #4CAF50; + border: none; + color: white; + padding: 10px 20px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin-top: 20px; + cursor: pointer; + border-radius: 5px; + } + + #login-btn:hover { + background-color: #3e8e41; + } + + \ No newline at end of file diff --git a/node_demo_server_atLogin/styling/client_style.css b/node_demo_server_atLogin/styling/client_style.css new file mode 100644 index 0000000..6511b43 --- /dev/null +++ b/node_demo_server_atLogin/styling/client_style.css @@ -0,0 +1,165 @@ +body { + font-family: "Open Sans", sans-serif; + background-color: #f8f8f8; +} + +.container { + max-width: 500px; + margin: 0 auto; + padding: 40px; + background-color: #fff; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); + border-radius: 10px; + text-align: center; +} + +h1 { + color: #333; + font-weight: 600; +} + +.col { + flex: 1; + /* display: table-column; */ + margin-bottom: 5px; +} + +input[type=text], input[type="email"] { + width: 30%; + border-radius: 4px; + padding: 12px 20px; + margin: 10px 18px; + box-sizing: border-box; + display: table-cell; +} + +label { + display: inline-block; + /* text-align: justify; */ + font-weight: 300; +} + +.row { + display: ruby-base; + /* flex-wrap: nowrap; */ + /* margin-bottom: 15px; */ + /* padding: 15px; */ +} + + +button[type="submit"] { + background-color: #333; + color: #fff; + padding: 10px 20px; + border: none; + border-radius: 5px; + cursor: pointer; + transition: all 0.2s ease; + font-family: "Open Sans", sans-serif; + font-size: 16px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 1px; +} + +button[type="submit"]:hover { + background-color: #555; +} + +.error { + color: red; + font-size: 14px; + margin-top: 10px; +} + +img{ + border-radius: 4px; + padding: 5px; + width: 200px; +} + +h2 { + width: 80%; + text-align: left; +} + +.atsign { + background-color: #cd6230; + border: none; + color: white; + padding: 15px 32px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + border-radius: 12px; +} + +input[type=submit]{ + width: 150px; + overflow: hidden; + padding: 12px; + background: #d8cfcb; + border-radius: 10px ; +} + + +h2 span { + background:#fff; + padding:0 10px; + font-size:14px; +} + + +.or { + color: rgb(15, 14, 14); + text-align: center; + margin: 20px 0; +} + +.or::before, +.or::after { + content: ""; + display: inline-block; + width: 30%; + margin: 0 10px; + border-top: 1px solid #080808; +} + +.or span { + display: inline-block; + padding: 0 10px; + font-size: 14px; + font-weight: bold; + color: #0f0f0f; + text-transform: uppercase; +} + +/* .atsign-input-container { + display: flex; + width: 400px; + padding-left: 100px; +} */ +/* .atsign-input-container { + display: inline-flex; + width: 800px; + height: auto; + margin: 20px auto; + padding-left: 20px; +} + +.atsign-input-container h5 { + margin-right: 0px; +} + +.input-wrapper { + flex: 0; +} */ + +.atsign-input-container { + display: flex; + justify-content: space-between; + width: 250px; + margin: 20px auto; + padding-left: 50px; +} \ No newline at end of file diff --git a/node_demo_server_atLogin/styling/login_response.css b/node_demo_server_atLogin/styling/login_response.css new file mode 100644 index 0000000..1704e2c --- /dev/null +++ b/node_demo_server_atLogin/styling/login_response.css @@ -0,0 +1,14 @@ +form { + background-color: #FFF; + border-radius: 5px; + padding: 50px; + width: 500px; + margin: 0 auto; + margin-top: 100px; + box-shadow: 0px 2px 5px rgba(0,0,0,0.3); +} + +h1 { + text-align: center; + margin-top: 0; +} \ No newline at end of file diff --git a/node_demo_server_atLogin/styling/login_style.css b/node_demo_server_atLogin/styling/login_style.css new file mode 100644 index 0000000..352dc44 --- /dev/null +++ b/node_demo_server_atLogin/styling/login_style.css @@ -0,0 +1,159 @@ +body { + font-family: Arial, sans-serif; + background-color: #F0F0F0; +} +form { + background-color: #FFF; + border-radius: 5px; + padding: 50px; + width: 800px; + margin: 0 auto; + margin-top: 100px; + box-shadow: 0px 2px 5px rgba(0,0,0,0.3); +} +img{ + border-radius: 4px; + padding: 5px; + width: 250px; +} +h2 { + text-align: center; + margin-top: 0; +} +h6 { + text-align: center; + margin-top: 0; +} +.center { + display: block; + margin-left: auto; + margin-right: auto; + width: 25%; + } + +/* .div-center { + display: block; + margin-left: auto; + margin-right: auto; + width: 25%; + } */ + +.div-center { + display: block; + flex-wrap: wrap; + margin-left: auto; + margin-right: auto; + width: 25%; + } + +/* h4 { + text-align: center; + margin-top: 0; +} */ + +input[type=text] { + width: 100%; + padding: 12px 20px; + margin: 8px 0; + display: inline-block; + border: 1px solid #ccc; + border-radius: 5px; + box-sizing: border-box; +} +input[type=atsign] { + width: 100%; + padding: 12px 20px; + /* margin: 8px 0; */ + display: inline-block; + border: 1px solid #ccc; + border-radius: 5px; + box-sizing: border-box; +} +button[type=submit] { + background-color: #4CAF50; + color: white; + padding: 14px 20px; + margin: 8px 0; + border: none; + border-radius: 4px; + cursor: pointer; + width: 100%; +} +button[type=submit]:hover { + background-color: #45a049; +} +.button-container { + display: flex; + justify-content: space-between; + width: 250px; + margin: 20px auto; + padding-left: 50px; + } + +.input-container { + display: inline-flex; + justify-content: space-between; + width: 800px; + height: auto; + margin: 20px auto; + padding-left: 20px; + } + +.refresh-icon { + margin-left: 20px; /* adjust as needed */ + margin-top: 15px; + height: 50px; + padding-top: 5px; + + } + + +h4 { + padding: 10px; /* Add 10 pixels of padding around each h4 element */ + } + +#refresh-btn { + background-color: #4CAF50; + border: white; + color: white; + padding-bottom: 10px; + border-radius: 5px; + } + + #refresh-btn:hover { + background-color: #3e8e41; + } + + #login-btn { + background-color: #4CAF50; + border: none; + color: white; + padding: 10px 20px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin-top: 20px; + cursor: pointer; + border-radius: 5px; + } + + #login-btn:hover { + background-color: #3e8e41; + } + + .atsign-input-container { + display: flex; + width: 400px; + padding-left: 200px; + } + + .atsign-input-container h5 { + margin-right: 5px; + } + + .input-wrapper { + flex: 1; + } + + \ No newline at end of file diff --git a/node_demo_server_atLogin/webPages/atlogin-1.0-jar-with-dependencies.jar b/node_demo_server_atLogin/webPages/atlogin-1.0-jar-with-dependencies.jar new file mode 100644 index 0000000..356c3d8 Binary files /dev/null and b/node_demo_server_atLogin/webPages/atlogin-1.0-jar-with-dependencies.jar differ diff --git a/node_demo_server_atLogin/webPages/atsign_logo.png b/node_demo_server_atLogin/webPages/atsign_logo.png new file mode 100644 index 0000000..e368b04 Binary files /dev/null and b/node_demo_server_atLogin/webPages/atsign_logo.png differ diff --git a/node_demo_server_atLogin/webPages/client.html b/node_demo_server_atLogin/webPages/client.html new file mode 100644 index 0000000..b6fb83e --- /dev/null +++ b/node_demo_server_atLogin/webPages/client.html @@ -0,0 +1,23 @@ + + + + + + + + oAuth app + + +

+
+ logo +

Login Page

+ +

+ +
+
+ + + diff --git a/node_demo_server_atLogin/webPages/login.html b/node_demo_server_atLogin/webPages/login.html new file mode 100644 index 0000000..263f858 --- /dev/null +++ b/node_demo_server_atLogin/webPages/login.html @@ -0,0 +1,55 @@ + + + + Login Page + + + + + + + +
+ logo +

Please create the below key with the value specified in the secondary server and press login to proceed

+
+

Key

+ +

Value

+ + +
+
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/node_demo_server_atLogin/webPages/loginResponse.html b/node_demo_server_atLogin/webPages/loginResponse.html new file mode 100644 index 0000000..84aad60 --- /dev/null +++ b/node_demo_server_atLogin/webPages/loginResponse.html @@ -0,0 +1,16 @@ + + + + Authentication Page + + + + + +
+ logo +

Login successfully

+
+ + + diff --git a/node_demo_server_atLogin/webPages/logo.jpg b/node_demo_server_atLogin/webPages/logo.jpg new file mode 100644 index 0000000..e22132a Binary files /dev/null and b/node_demo_server_atLogin/webPages/logo.jpg differ diff --git a/node_demo_server_atLogin/webPages/response_json.json b/node_demo_server_atLogin/webPages/response_json.json new file mode 100644 index 0000000..4be4161 --- /dev/null +++ b/node_demo_server_atLogin/webPages/response_json.json @@ -0,0 +1 @@ +{"responseType":"success","verificationStatus":true} \ No newline at end of file diff --git a/node_demo_server_atLogin/webPages/uuid.json b/node_demo_server_atLogin/webPages/uuid.json new file mode 100644 index 0000000..5049193 --- /dev/null +++ b/node_demo_server_atLogin/webPages/uuid.json @@ -0,0 +1 @@ +{"key":"__504c20d3-d546-403e-9f64-3ea22978338e.atlogin@worriedcrow80","value":"9e8110d4-c641-4b81-80ca-b7e51646de75"} \ No newline at end of file