https://github.com/manuel-lohmus/ws-user
User authentication and authorization for WebSocket applications.
https://github.com/manuel-lohmus/ws-user
Last synced: about 1 month ago
JSON representation
User authentication and authorization for WebSocket applications.
- Host: GitHub
- URL: https://github.com/manuel-lohmus/ws-user
- Owner: manuel-lohmus
- License: mit
- Created: 2025-03-25T18:29:46.000Z (about 1 month ago)
- Default Branch: master
- Last Pushed: 2025-04-02T07:48:45.000Z (about 1 month ago)
- Last Synced: 2025-04-02T08:32:29.733Z (about 1 month ago)
- Language: JavaScript
- Size: 41 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.html
- License: LICENSE
Awesome Lists containing this project
README
WS-User
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 980px;
margin: 0 auto;
padding: 45px;
}@media (max-width: 767px) {
.markdown-body {
padding: 15px;
}
}.markdown-body {
--base-size-4: 0.25rem;
--base-size-8: 0.5rem;
--base-size-16: 1rem;
--base-size-24: 1.5rem;
--base-size-40: 2.5rem;
--base-text-weight-normal: 400;
--base-text-weight-medium: 500;
--base-text-weight-semibold: 600;
--fontStack-monospace: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
--fgColor-accent: Highlight;
}@media (prefers-color-scheme: dark) {
.markdown-body, [data-theme="dark"] {
/* dark */
color-scheme: dark;
--focus-outlineColor: #1f6feb;
--fgColor-default: #f0f6fc;
--fgColor-muted: #9198a1;
--fgColor-accent: #4493f8;
--fgColor-success: #3fb950;
--fgColor-attention: #d29922;
--fgColor-danger: #f85149;
--fgColor-done: #ab7df8;
--bgColor-default: #0d1117;
--bgColor-muted: #151b23;
--bgColor-neutral-muted: #656c7633;
--bgColor-attention-muted: #bb800926;
--borderColor-default: #3d444d;
--borderColor-muted: #3d444db3;
--borderColor-neutral-muted: #3d444db3;
--borderColor-accent-emphasis: #1f6feb;
--borderColor-success-emphasis: #238636;
--borderColor-attention-emphasis: #9e6a03;
--borderColor-danger-emphasis: #da3633;
--borderColor-done-emphasis: #8957e5;
--color-prettylights-syntax-comment: #9198a1;
--color-prettylights-syntax-constant: #79c0ff;
--color-prettylights-syntax-constant-other-reference-link: #a5d6ff;
--color-prettylights-syntax-entity: #d2a8ff;
--color-prettylights-syntax-storage-modifier-import: #f0f6fc;
--color-prettylights-syntax-entity-tag: #7ee787;
--color-prettylights-syntax-keyword: #ff7b72;
--color-prettylights-syntax-string: #a5d6ff;
--color-prettylights-syntax-variable: #ffa657;
--color-prettylights-syntax-brackethighlighter-unmatched: #f85149;
--color-prettylights-syntax-brackethighlighter-angle: #9198a1;
--color-prettylights-syntax-invalid-illegal-text: #f0f6fc;
--color-prettylights-syntax-invalid-illegal-bg: #8e1519;
--color-prettylights-syntax-carriage-return-text: #f0f6fc;
--color-prettylights-syntax-carriage-return-bg: #b62324;
--color-prettylights-syntax-string-regexp: #7ee787;
--color-prettylights-syntax-markup-list: #f2cc60;
--color-prettylights-syntax-markup-heading: #1f6feb;
--color-prettylights-syntax-markup-italic: #f0f6fc;
--color-prettylights-syntax-markup-bold: #f0f6fc;
--color-prettylights-syntax-markup-deleted-text: #ffdcd7;
--color-prettylights-syntax-markup-deleted-bg: #67060c;
--color-prettylights-syntax-markup-inserted-text: #aff5b4;
--color-prettylights-syntax-markup-inserted-bg: #033a16;
--color-prettylights-syntax-markup-changed-text: #ffdfb6;
--color-prettylights-syntax-markup-changed-bg: #5a1e02;
--color-prettylights-syntax-markup-ignored-text: #f0f6fc;
--color-prettylights-syntax-markup-ignored-bg: #1158c7;
--color-prettylights-syntax-meta-diff-range: #d2a8ff;
--color-prettylights-syntax-sublimelinter-gutter-mark: #3d444d;
}
}@media (prefers-color-scheme: light) {
.markdown-body, [data-theme="light"] {
/* light */
color-scheme: light;
--focus-outlineColor: #0969da;
--fgColor-default: #1f2328;
--fgColor-muted: #59636e;
--fgColor-accent: #0969da;
--fgColor-success: #1a7f37;
--fgColor-attention: #9a6700;
--fgColor-danger: #d1242f;
--fgColor-done: #8250df;
--bgColor-default: #ffffff;
--bgColor-muted: #f6f8fa;
--bgColor-neutral-muted: #818b981f;
--bgColor-attention-muted: #fff8c5;
--borderColor-default: #d1d9e0;
--borderColor-muted: #d1d9e0b3;
--borderColor-neutral-muted: #d1d9e0b3;
--borderColor-accent-emphasis: #0969da;
--borderColor-success-emphasis: #1a7f37;
--borderColor-attention-emphasis: #9a6700;
--borderColor-danger-emphasis: #cf222e;
--borderColor-done-emphasis: #8250df;
--color-prettylights-syntax-comment: #59636e;
--color-prettylights-syntax-constant: #0550ae;
--color-prettylights-syntax-constant-other-reference-link: #0a3069;
--color-prettylights-syntax-entity: #6639ba;
--color-prettylights-syntax-storage-modifier-import: #1f2328;
--color-prettylights-syntax-entity-tag: #0550ae;
--color-prettylights-syntax-keyword: #cf222e;
--color-prettylights-syntax-string: #0a3069;
--color-prettylights-syntax-variable: #953800;
--color-prettylights-syntax-brackethighlighter-unmatched: #82071e;
--color-prettylights-syntax-brackethighlighter-angle: #59636e;
--color-prettylights-syntax-invalid-illegal-text: #f6f8fa;
--color-prettylights-syntax-invalid-illegal-bg: #82071e;
--color-prettylights-syntax-carriage-return-text: #f6f8fa;
--color-prettylights-syntax-carriage-return-bg: #cf222e;
--color-prettylights-syntax-string-regexp: #116329;
--color-prettylights-syntax-markup-list: #3b2300;
--color-prettylights-syntax-markup-heading: #0550ae;
--color-prettylights-syntax-markup-italic: #1f2328;
--color-prettylights-syntax-markup-bold: #1f2328;
--color-prettylights-syntax-markup-deleted-text: #82071e;
--color-prettylights-syntax-markup-deleted-bg: #ffebe9;
--color-prettylights-syntax-markup-inserted-text: #116329;
--color-prettylights-syntax-markup-inserted-bg: #dafbe1;
--color-prettylights-syntax-markup-changed-text: #953800;
--color-prettylights-syntax-markup-changed-bg: #ffd8b5;
--color-prettylights-syntax-markup-ignored-text: #d1d9e0;
--color-prettylights-syntax-markup-ignored-bg: #0550ae;
--color-prettylights-syntax-meta-diff-range: #8250df;
--color-prettylights-syntax-sublimelinter-gutter-mark: #818b98;
}
}.markdown-body {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
margin: 0;
color: var(--fgColor-default);
background-color: var(--bgColor-default);
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";
font-size: 16px;
line-height: 1.5;
word-wrap: break-word;
}.markdown-body .octicon {
display: inline-block;
fill: currentColor;
vertical-align: text-bottom;
}.markdown-body h1:hover .anchor .octicon-link:before,
.markdown-body h2:hover .anchor .octicon-link:before,
.markdown-body h3:hover .anchor .octicon-link:before,
.markdown-body h4:hover .anchor .octicon-link:before,
.markdown-body h5:hover .anchor .octicon-link:before,
.markdown-body h6:hover .anchor .octicon-link:before {
width: 16px;
height: 16px;
content: ' ';
display: inline-block;
background-color: currentColor;
-webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>");
mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>");
}.markdown-body details,
.markdown-body figcaption,
.markdown-body figure {
display: block;
}.markdown-body summary {
display: list-item;
}.markdown-body [hidden] {
display: none !important;
}.markdown-body a {
background-color: transparent;
color: var(--fgColor-accent);
text-decoration: none;
}.markdown-body abbrWS-User {
border-bottom: none;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
}.markdown-body b,
.markdown-body strong {
font-weight: var(--base-text-weight-semibold, 600);
}.markdown-body dfn {
font-style: italic;
}.markdown-body h1 {
margin: .67em 0;
font-weight: var(--base-text-weight-semibold, 600);
padding-bottom: .3em;
font-size: 2em;
border-bottom: 1px solid var(--borderColor-muted);
}.markdown-body mark {
background-color: var(--bgColor-attention-muted);
color: var(--fgColor-default);
}.markdown-body small {
font-size: 90%;
}.markdown-body sub,
.markdown-body sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}.markdown-body sub {
bottom: -0.25em;
}.markdown-body sup {
top: -0.5em;
}.markdown-body img {
border-style: none;
max-width: 100%;
box-sizing: content-box;
}.markdown-body code,
.markdown-body kbd,
.markdown-body pre,
.markdown-body samp {
font-family: monospace;
font-size: 1em;
}.markdown-body figure {
margin: 1em var(--base-size-40);
}.markdown-body hr {
box-sizing: content-box;
overflow: hidden;
background: transparent;
border-bottom: 1px solid var(--borderColor-muted);
height: .25em;
padding: 0;
margin: var(--base-size-24) 0;
background-color: var(--borderColor-default);
border: 0;
}.markdown-body input {
font: inherit;
margin: 0;
overflow: visible;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}.markdown-body [type=button],
.markdown-body [type=reset],
.markdown-body [type=submit] {
-webkit-appearance: button;
appearance: button;
}.markdown-body [type=checkbox],
.markdown-body [type=radio] {
box-sizing: border-box;
padding: 0;
}.markdown-body [type=number]::-webkit-inner-spin-button,
.markdown-body [type=number]::-webkit-outer-spin-button {
height: auto;
}.markdown-body [type=search]::-webkit-search-cancel-button,
.markdown-body [type=search]::-webkit-search-decoration {
-webkit-appearance: none;
appearance: none;
}.markdown-body ::-webkit-input-placeholder {
color: inherit;
opacity: .54;
}.markdown-body ::-webkit-file-upload-button {
-webkit-appearance: button;
appearance: button;
font: inherit;
}.markdown-body a:hover {
text-decoration: underline;
}.markdown-body ::placeholder {
color: var(--fgColor-muted);
opacity: 1;
}.markdown-body hr::before {
display: table;
content: "";
}.markdown-body hr::after {
display: table;
clear: both;
content: "";
}.markdown-body table {
border-spacing: 0;
border-collapse: collapse;
display: block;
width: max-content;
max-width: 100%;
overflow: auto;
font-variant: tabular-nums;
}.markdown-body td,
.markdown-body th {
padding: 0;
}.markdown-body details summary {
cursor: pointer;
}.markdown-body a:focus,
.markdown-body [role=button]:focus,
.markdown-body input[type=radio]:focus,
.markdown-body input[type=checkbox]:focus {
outline: 2px solid var(--focus-outlineColor);
outline-offset: -2px;
box-shadow: none;
}.markdown-body a:focus:not(:focus-visible),
.markdown-body [role=button]:focus:not(:focus-visible),
.markdown-body input[type=radio]:focus:not(:focus-visible),
.markdown-body input[type=checkbox]:focus:not(:focus-visible) {
outline: solid 1px transparent;
}.markdown-body a:focus-visible,
.markdown-body [role=button]:focus-visible,
.markdown-body input[type=radio]:focus-visible,
.markdown-body input[type=checkbox]:focus-visible {
outline: 2px solid var(--focus-outlineColor);
outline-offset: -2px;
box-shadow: none;
}.markdown-body a:not([class]):focus,
.markdown-body a:not([class]):focus-visible,
.markdown-body input[type=radio]:focus,
.markdown-body input[type=radio]:focus-visible,
.markdown-body input[type=checkbox]:focus,
.markdown-body input[type=checkbox]:focus-visible {
outline-offset: 0;
}.markdown-body kbd {
display: inline-block;
padding: var(--base-size-4);
font: 11px var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace);
line-height: 10px;
color: var(--fgColor-default);
vertical-align: middle;
background-color: var(--bgColor-muted);
border: solid 1px var(--borderColor-neutral-muted);
border-bottom-color: var(--borderColor-neutral-muted);
border-radius: 6px;
box-shadow: inset 0 -1px 0 var(--borderColor-neutral-muted);
}.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
margin-top: var(--base-size-24);
margin-bottom: var(--base-size-16);
font-weight: var(--base-text-weight-semibold, 600);
line-height: 1.25;
}.markdown-body h2 {
font-weight: var(--base-text-weight-semibold, 600);
padding-bottom: .3em;
font-size: 1.5em;
border-bottom: 1px solid var(--borderColor-muted);
}.markdown-body h3 {
font-weight: var(--base-text-weight-semibold, 600);
font-size: 1.25em;
}.markdown-body h4 {
font-weight: var(--base-text-weight-semibold, 600);
font-size: 1em;
}.markdown-body h5 {
font-weight: var(--base-text-weight-semibold, 600);
font-size: .875em;
}.markdown-body h6 {
font-weight: var(--base-text-weight-semibold, 600);
font-size: .85em;
color: var(--fgColor-muted);
}.markdown-body p {
margin-top: 0;
margin-bottom: 10px;
}.markdown-body blockquote {
margin: 0;
padding: 0 1em;
color: var(--fgColor-muted);
border-left: .25em solid var(--borderColor-default);
}.markdown-body ul,
.markdown-body ol {
margin-top: 0;
margin-bottom: 0;
padding-left: 2em;
}.markdown-body ol ol,
.markdown-body ul ol {
list-style-type: lower-roman;
}.markdown-body ul ul ol,
.markdown-body ul ol ol,
.markdown-body ol ul ol,
.markdown-body ol ol ol {
list-style-type: lower-alpha;
}.markdown-body dd {
margin-left: 0;
}.markdown-body tt,
.markdown-body code,
.markdown-body samp {
font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace);
font-size: 12px;
}.markdown-body pre {
margin-top: 0;
margin-bottom: 0;
font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace);
font-size: 12px;
word-wrap: normal;
}.markdown-body .octicon {
display: inline-block;
overflow: visible !important;
vertical-align: text-bottom;
fill: currentColor;
}.markdown-body input::-webkit-outer-spin-button,
.markdown-body input::-webkit-inner-spin-button {
margin: 0;
appearance: none;
}.markdown-body .mr-2 {
margin-right: var(--base-size-8, 8px) !important;
}.markdown-body::before {
display: table;
content: "";
}.markdown-body::after {
display: table;
clear: both;
content: "";
}.markdown-body > *:first-child {
margin-top: 0 !important;
}.markdown-body > *:last-child {
margin-bottom: 0 !important;
}.markdown-body a:not([href]) {
color: inherit;
text-decoration: none;
}.markdown-body .absent {
color: var(--fgColor-danger);
}.markdown-body .anchor {
float: left;
padding-right: var(--base-size-4);
margin-left: -20px;
line-height: 1;
}.markdown-body .anchor:focus {
outline: none;
}.markdown-body p,
.markdown-body blockquote,
.markdown-body ul,
.markdown-body ol,
.markdown-body dl,
.markdown-body table,
.markdown-body pre,
.markdown-body details {
margin-top: 0;
margin-bottom: var(--base-size-16);
}.markdown-body blockquote > :first-child {
margin-top: 0;
}.markdown-body blockquote > :last-child {
margin-bottom: 0;
}.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
color: var(--fgColor-default);
vertical-align: middle;
visibility: hidden;
}.markdown-body h1:hover .anchor,
.markdown-body h2:hover .anchor,
.markdown-body h3:hover .anchor,
.markdown-body h4:hover .anchor,
.markdown-body h5:hover .anchor,
.markdown-body h6:hover .anchor {
text-decoration: none;
}.markdown-body h1:hover .anchor .octicon-link,
.markdown-body h2:hover .anchor .octicon-link,
.markdown-body h3:hover .anchor .octicon-link,
.markdown-body h4:hover .anchor .octicon-link,
.markdown-body h5:hover .anchor .octicon-link,
.markdown-body h6:hover .anchor .octicon-link {
visibility: visible;
}.markdown-body h1 tt,
.markdown-body h1 code,
.markdown-body h2 tt,
.markdown-body h2 code,
.markdown-body h3 tt,
.markdown-body h3 code,
.markdown-body h4 tt,
.markdown-body h4 code,
.markdown-body h5 tt,
.markdown-body h5 code,
.markdown-body h6 tt,
.markdown-body h6 code {
padding: 0 .2em;
font-size: inherit;
}.markdown-body summary h1,
.markdown-body summary h2,
.markdown-body summary h3,
.markdown-body summary h4,
.markdown-body summary h5,
.markdown-body summary h6 {
display: inline-block;
}.markdown-body summary h1 .anchor,
.markdown-body summary h2 .anchor,
.markdown-body summary h3 .anchor,
.markdown-body summary h4 .anchor,
.markdown-body summary h5 .anchor,
.markdown-body summary h6 .anchor {
margin-left: -40px;
}.markdown-body summary h1,
.markdown-body summary h2 {
padding-bottom: 0;
border-bottom: 0;
}.markdown-body ul.no-list,
.markdown-body ol.no-list {
padding: 0;
list-style-type: none;
}.markdown-body ol[type="a s"] {
list-style-type: lower-alpha;
}.markdown-body ol[type="A s"] {
list-style-type: upper-alpha;
}.markdown-body ol[type="i s"] {
list-style-type: lower-roman;
}.markdown-body ol[type="I s"] {
list-style-type: upper-roman;
}.markdown-body ol[type="1"] {
list-style-type: decimal;
}.markdown-body div > ol:not([type]) {
list-style-type: decimal;
}.markdown-body ul ul,
.markdown-body ul ol,
.markdown-body ol ol,
.markdown-body ol ul {
margin-top: 0;
margin-bottom: 0;
}.markdown-body li > p {
margin-top: var(--base-size-16);
}.markdown-body li + li {
margin-top: .25em;
}.markdown-body dl {
padding: 0;
}.markdown-body dl dt {
padding: 0;
margin-top: var(--base-size-16);
font-size: 1em;
font-style: italic;
font-weight: var(--base-text-weight-semibold, 600);
}.markdown-body dl dd {
padding: 0 var(--base-size-16);
margin-bottom: var(--base-size-16);
}.markdown-body table th {
font-weight: var(--base-text-weight-semibold, 600);
}.markdown-body table th,
.markdown-body table td {
padding: 6px 13px;
border: 1px solid var(--borderColor-default);
}.markdown-body table td > :last-child {
margin-bottom: 0;
}.markdown-body table tr {
background-color: var(--bgColor-default);
border-top: 1px solid var(--borderColor-muted);
}.markdown-body table tr:nth-child(2n) {
background-color: var(--bgColor-muted);
}.markdown-body table img {
background-color: transparent;
}.markdown-body img[align=right] {
padding-left: 20px;
}.markdown-body img[align=left] {
padding-right: 20px;
}.markdown-body .emoji {
max-width: none;
vertical-align: text-top;
background-color: transparent;
}.markdown-body span.frame {
display: block;
overflow: hidden;
}.markdown-body span.frame > span {
display: block;
float: left;
width: auto;
padding: 7px;
margin: 13px 0 0;
overflow: hidden;
border: 1px solid var(--borderColor-default);
}.markdown-body span.frame span img {
display: block;
float: left;
}.markdown-body span.frame span span {
display: block;
padding: 5px 0 0;
clear: both;
color: var(--fgColor-default);
}.markdown-body span.align-center {
display: block;
overflow: hidden;
clear: both;
}.markdown-body span.align-center > span {
display: block;
margin: 13px auto 0;
overflow: hidden;
text-align: center;
}.markdown-body span.align-center span img {
margin: 0 auto;
text-align: center;
}.markdown-body span.align-right {
display: block;
overflow: hidden;
clear: both;
}.markdown-body span.align-right > span {
display: block;
margin: 13px 0 0;
overflow: hidden;
text-align: right;
}.markdown-body span.align-right span img {
margin: 0;
text-align: right;
}.markdown-body span.float-left {
display: block;
float: left;
margin-right: 13px;
overflow: hidden;
}.markdown-body span.float-left span {
margin: 13px 0 0;
}.markdown-body span.float-right {
display: block;
float: right;
margin-left: 13px;
overflow: hidden;
}.markdown-body span.float-right > span {
display: block;
margin: 13px auto 0;
overflow: hidden;
text-align: right;
}.markdown-body code,
.markdown-body tt {
padding: .2em .4em;
margin: 0;
font-size: 85%;
white-space: break-spaces;
background-color: var(--bgColor-neutral-muted);
border-radius: 6px;
}.markdown-body code br,
.markdown-body tt br {
display: none;
}.markdown-body del code {
text-decoration: inherit;
}.markdown-body samp {
font-size: 85%;
}.markdown-body pre code {
font-size: 100%;
}.markdown-body pre > code {
padding: 0;
margin: 0;
word-break: normal;
white-space: pre;
background: transparent;
border: 0;
}.markdown-body .highlight {
margin-bottom: var(--base-size-16);
}.markdown-body .highlight pre {
margin-bottom: 0;
word-break: normal;
}.markdown-body .highlight pre,
.markdown-body pre {
padding: var(--base-size-16);
overflow: auto;
font-size: 85%;
line-height: 1.45;
color: var(--fgColor-default);
background-color: var(--bgColor-muted);
border-radius: 6px;
}.markdown-body pre code,
.markdown-body pre tt {
display: inline;
max-width: auto;
padding: 0;
margin: 0;
overflow: visible;
line-height: inherit;
word-wrap: normal;
background-color: transparent;
border: 0;
}.markdown-body .csv-data td,
.markdown-body .csv-data th {
padding: 5px;
overflow: hidden;
font-size: 12px;
line-height: 1;
text-align: left;
white-space: nowrap;
}.markdown-body .csv-data .blob-num {
padding: 10px var(--base-size-8) 9px;
text-align: right;
background: var(--bgColor-default);
border: 0;
}.markdown-body .csv-data tr {
border-top: 0;
}.markdown-body .csv-data th {
font-weight: var(--base-text-weight-semibold, 600);
background: var(--bgColor-muted);
border-top: 0;
}.markdown-body [data-footnote-ref]::before {
content: "[";
}.markdown-body [data-footnote-ref]::after {
content: "]";
}.markdown-body .footnotes {
font-size: 12px;
color: var(--fgColor-muted);
border-top: 1px solid var(--borderColor-default);
}.markdown-body .footnotes ol {
padding-left: var(--base-size-16);
}.markdown-body .footnotes ol ul {
display: inline-block;
padding-left: var(--base-size-16);
margin-top: var(--base-size-16);
}.markdown-body .footnotes li {
position: relative;
}.markdown-body .footnotes li:target::before {
position: absolute;
top: calc(var(--base-size-8)*-1);
right: calc(var(--base-size-8)*-1);
bottom: calc(var(--base-size-8)*-1);
left: calc(var(--base-size-24)*-1);
pointer-events: none;
content: "";
border: 2px solid var(--borderColor-accent-emphasis);
border-radius: 6px;
}.markdown-body .footnotes li:target {
color: var(--fgColor-default);
}.markdown-body .footnotes .data-footnote-backref g-emoji {
font-family: monospace;
}.markdown-body body:has(:modal) {
padding-right: var(--dialog-scrollgutter) !important;
}.markdown-body .pl-c {
color: var(--color-prettylights-syntax-comment);
}.markdown-body .pl-c1,
.markdown-body .pl-s .pl-v {
color: var(--color-prettylights-syntax-constant);
}.markdown-body .pl-e,
.markdown-body .pl-en {
color: var(--color-prettylights-syntax-entity);
}.markdown-body .pl-smi,
.markdown-body .pl-s .pl-s1 {
color: var(--color-prettylights-syntax-storage-modifier-import);
}.markdown-body .pl-ent {
color: var(--color-prettylights-syntax-entity-tag);
}.markdown-body .pl-k {
color: var(--color-prettylights-syntax-keyword);
}.markdown-body .pl-s,
.markdown-body .pl-pds,
.markdown-body .pl-s .pl-pse .pl-s1,
.markdown-body .pl-sr,
.markdown-body .pl-sr .pl-cce,
.markdown-body .pl-sr .pl-sre,
.markdown-body .pl-sr .pl-sra {
color: var(--color-prettylights-syntax-string);
}.markdown-body .pl-v,
.markdown-body .pl-smw {
color: var(--color-prettylights-syntax-variable);
}.markdown-body .pl-bu {
color: var(--color-prettylights-syntax-brackethighlighter-unmatched);
}.markdown-body .pl-ii {
color: var(--color-prettylights-syntax-invalid-illegal-text);
background-color: var(--color-prettylights-syntax-invalid-illegal-bg);
}.markdown-body .pl-c2 {
color: var(--color-prettylights-syntax-carriage-return-text);
background-color: var(--color-prettylights-syntax-carriage-return-bg);
}.markdown-body .pl-sr .pl-cce {
font-weight: bold;
color: var(--color-prettylights-syntax-string-regexp);
}.markdown-body .pl-ml {
color: var(--color-prettylights-syntax-markup-list);
}.markdown-body .pl-mh,
.markdown-body .pl-mh .pl-en,
.markdown-body .pl-ms {
font-weight: bold;
color: var(--color-prettylights-syntax-markup-heading);
}.markdown-body .pl-mi {
font-style: italic;
color: var(--color-prettylights-syntax-markup-italic);
}.markdown-body .pl-mb {
font-weight: bold;
color: var(--color-prettylights-syntax-markup-bold);
}.markdown-body .pl-md {
color: var(--color-prettylights-syntax-markup-deleted-text);
background-color: var(--color-prettylights-syntax-markup-deleted-bg);
}.markdown-body .pl-mi1 {
color: var(--color-prettylights-syntax-markup-inserted-text);
background-color: var(--color-prettylights-syntax-markup-inserted-bg);
}.markdown-body .pl-mc {
color: var(--color-prettylights-syntax-markup-changed-text);
background-color: var(--color-prettylights-syntax-markup-changed-bg);
}.markdown-body .pl-mi2 {
color: var(--color-prettylights-syntax-markup-ignored-text);
background-color: var(--color-prettylights-syntax-markup-ignored-bg);
}.markdown-body .pl-mdr {
font-weight: bold;
color: var(--color-prettylights-syntax-meta-diff-range);
}.markdown-body .pl-ba {
color: var(--color-prettylights-syntax-brackethighlighter-angle);
}.markdown-body .pl-sg {
color: var(--color-prettylights-syntax-sublimelinter-gutter-mark);
}.markdown-body .pl-corl {
text-decoration: underline;
color: var(--color-prettylights-syntax-constant-other-reference-link);
}.markdown-body [role=button]:focus:not(:focus-visible),
.markdown-body [role=tabpanel][tabindex="0"]:focus:not(:focus-visible),
.markdown-body button:focus:not(:focus-visible),
.markdown-body summary:focus:not(:focus-visible),
.markdown-body a:focus:not(:focus-visible) {
outline: none;
box-shadow: none;
}.markdown-body [tabindex="0"]:focus:not(:focus-visible),
.markdown-body details-dialog:focus:not(:focus-visible) {
outline: none;
}.markdown-body g-emoji {
display: inline-block;
min-width: 1ch;
font-family: "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";
font-size: 1em;
font-style: normal !important;
font-weight: var(--base-text-weight-normal, 400);
line-height: 1;
vertical-align: -0.075em;
}.markdown-body g-emoji img {
width: 1em;
height: 1em;
}.markdown-body .task-list-item {
list-style-type: none;
}.markdown-body .task-list-item label {
font-weight: var(--base-text-weight-normal, 400);
}.markdown-body .task-list-item.enabled label {
cursor: pointer;
}.markdown-body .task-list-item + .task-list-item {
margin-top: var(--base-size-4);
}.markdown-body .task-list-item .handle {
display: none;
}.markdown-body .task-list-item-checkbox {
margin: 0 .2em .25em -1.4em;
vertical-align: middle;
}.markdown-body ul:dir(rtl) .task-list-item-checkbox {
margin: 0 -1.6em .25em .2em;
}.markdown-body ol:dir(rtl) .task-list-item-checkbox {
margin: 0 -1.6em .25em .2em;
}.markdown-body .contains-task-list:hover .task-list-item-convert-container,
.markdown-body .contains-task-list:focus-within .task-list-item-convert-container {
display: block;
width: auto;
height: 24px;
overflow: visible;
clip: auto;
}.markdown-body ::-webkit-calendar-picker-indicator {
filter: invert(50%);
}.markdown-body .markdown-alert {
padding: var(--base-size-8) var(--base-size-16);
margin-bottom: var(--base-size-16);
color: inherit;
border-left: .25em solid var(--borderColor-default);
}.markdown-body .markdown-alert > :first-child {
margin-top: 0;
}.markdown-body .markdown-alert > :last-child {
margin-bottom: 0;
}.markdown-body .markdown-alert .markdown-alert-title {
display: flex;
font-weight: var(--base-text-weight-medium, 500);
align-items: center;
line-height: 1;
}.markdown-body .markdown-alert.markdown-alert-note {
border-left-color: var(--borderColor-accent-emphasis);
}.markdown-body .markdown-alert.markdown-alert-note .markdown-alert-title {
color: var(--fgColor-accent);
}.markdown-body .markdown-alert.markdown-alert-important {
border-left-color: var(--borderColor-done-emphasis);
}.markdown-body .markdown-alert.markdown-alert-important .markdown-alert-title {
color: var(--fgColor-done);
}.markdown-body .markdown-alert.markdown-alert-warning {
border-left-color: var(--borderColor-attention-emphasis);
}.markdown-body .markdown-alert.markdown-alert-warning .markdown-alert-title {
color: var(--fgColor-attention);
}.markdown-body .markdown-alert.markdown-alert-tip {
border-left-color: var(--borderColor-success-emphasis);
}.markdown-body .markdown-alert.markdown-alert-tip .markdown-alert-title {
color: var(--fgColor-success);
}.markdown-body .markdown-alert.markdown-alert-caution {
border-left-color: var(--borderColor-danger-emphasis);
}.markdown-body .markdown-alert.markdown-alert-caution .markdown-alert-title {
color: var(--fgColor-danger);
}.markdown-body > *:first-child > .heading-element:first-child {
margin-top: 0 !important;
}.markdown-body .highlight pre:has(+.zeroclipboard-container) {
min-height: 52px;
}
WS-User
This manual is also available in HTML5.
Overview
WS-User module is a library that manages user data over the websocket protocol.
Used when building a single-page application (SPA), this library offers a modern approach.
Now using the specially designed modulews13
to get a better and more stable connection.
It frontends and backends for user data management libraries.
browser.js
is a frontend library that provides a user interface for managing user data.
server.js
is a backend library that provides managing user data over the websocket protocol in real-time.Features
- Create new user
- Login and logout user
- Retrieve user details
- Update existing user information
- Open data link over websocket. Used module
ws13
.- and more...
Installation
You can install
ws-user
using this command:
npm install ws-user
Configuration
You can configure the
ws-user
module using theconfig-sets.json
file:{
"isProduction": true,
"production": {
"ws-user": {
"pathToFrontendErrors": "log/frontend_errors.log",
"pathToLoggedUsers": "logged_users.json",
"pathToUsersDir": "users"
},
"nodemailer": {
"host": "smtp-mail.outlook.com",
"port": 587,
"secureConnection": false,
"tls": {
"ciphers": "SSLv3"
},
"auth": {
"user": "*user*@outlook.com",
"pass": ""
}
}
},
"development": {}
}Usage
On the server side, you can use the following code to start the server:
const CreateWsUser = require('ws-user');
const wsUser = CreateWsUser(options);
if (wsUser) {
wsUser.onerror = (error) => {
console.error(error);
};
wsUser.onopen = () => {
console.log('Server started');
};
wsUser.onclose = () => {
console.log('Server closed');
};
wsUser.onmessage = (event) => {
// Received message from client and websocket is paused, disable to receive messages
console.log(event.data);
wsUser.messageHandled(); // continue, websocket is open, enable to receive messages
};
wsUser.extensionCommands = {
'myCommand': (event) => {
console.log(event);
const myData = event.message; // Received `myData` from client
// Do something
// Send response to client
wsUser.send(`$myCommand:${myData}`);
event.done(); // or wsUser.messageHandled(); `myCommand` is handled > continue, websocket is open
}
};
}On the client side, you can use the following code to connect to the server:
<!DOCTYPE html>
<html>
<head>
<title>WS-User</title>
<!-- STEP 1: Import the library. -->
<!-- Import the library. Routes in the node_modules folder on the server `tiny-https-server` -->
<script async src="node_modules/data-context@2"></script>
<script async src="node_modules/data-context-binding@2"></script>
<script async src="node_modules/ws-user"></script>
<!-- or use CDN -->
<script src="https://cdn.jsdelivr.net/npm/data-context"></script>
<script src="https://cdn.jsdelivr.net/npm/data-context-binding"></script>
<script src="https://cdn.jsdelivr.net/npm/ws-user"></script>
</head>
<body>
<script>
// STEP 3: Use the library.
importModules(['data-context', 'data-context-binding', 'ws-user'], function (dataContext, dataContextBinding, WsUser) {
const wsUser = WsUser({ debugMode });
wsUser.onerror = (error) => {
console.error(error);
};
wsUser.onopen = () => {
console.log('Connected to the server');
};
wsUser.onclose = () => {
console.log('Disconnected from the server');
};
wsUser.onmessage = (event) => {
console.log(event.data);
wsUser.messageHandled();
};
wsUser.extensionCommands = {
'myCommand': (event) => {
console.log(event);
const myData = event.message;
wsUser.send(`$myCommand:${myData}`);
event.done();
}
};
wsUser.onuserinfo = function (event) {
console.log(event);
if (event?.userinfo?.message) { alert(event.userinfo.message); }
};
//wsUser.login(email, password);
//wsUser.logout();
//wsUser.create_account(email, password, name);
//wsUser.update_name(name);
//wsUser.update_password(password);
//wsUser.security_code(email, code, resetPassword);});
// STEP 2: Add the importModules function.
function importModules(importIdentifierArray, cb) {var thisScope = "undefined" != typeof globalThis
? globalThis
: "undefined" != typeof window
? window
: "undefined" != typeof global
? global : "undefined" != typeof self
? self
: {};if (!thisScope.modules) { thisScope.modules = {}; }
waitModules();
function waitModules() {
if (importIdentifierArray.length) {
for (let i = 0; i < importIdentifierArray.length; i++) {
if (!thisScope.modules[importIdentifierArray[i]]) { return setTimeout(waitModules, 10); }
}
}cb.call(thisScope, ...importIdentifierArray.map(function (id) { return thisScope.modules[id]; }));
}
}
</script>
</body>
</html>License
This project is licensed under the MIT License.
Copyright © 2021 Manuel Lõhmus
Donations are welcome and will go towards further development of this project.
(function () {'use strict';
var isIE = !!document.documentMode; // Detect IE
if (!isIE) {
var link, script;
// bootstrap for styling (https://getbootstrap.com/)
link = document.createElement('link');
link.href = 'https://cdn.jsdelivr.net/npm/bootstrap@5/dist/css/bootstrap.min.css';
link.rel = 'stylesheet';
link.crossOrigin = 'anonymous';
document.head.appendChild(link);
script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/bootstrap@5/dist/js/bootstrap.bundle.min.js';
script.crossOrigin = 'anonymous';
document.head.appendChild(script);// prism syntax highlighter for code blocks (https://prismjs.com/)
link = document.createElement('link');
link.href = 'https://cdn.jsdelivr.net/npm/[email protected]/themes/prism.min.css';
link.rel = 'stylesheet';
link.crossOrigin = 'anonymous';
document.head.appendChild(link);
script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/[email protected]/prism.min.js';
script.crossOrigin = 'anonymous';
document.head.appendChild(script);// list-group style for headers
document.querySelectorAll('#list-headers a')
.forEach(function (a) { a.classList.add('list-group-item', 'list-group-item-action') });
}
})();