@msout/microsoft-webauth 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,25 @@
1
+ name: Publish Package
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ id-token: write # Required for OIDC
10
+ contents: read
11
+
12
+ jobs:
13
+ publish:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v6
17
+
18
+ - uses: actions/setup-node@v6
19
+ with:
20
+ node-version: '24'
21
+ package-manager-cache: false # never use caching in release builds
22
+ - run: npm ci
23
+ - run: npm run build --if-present
24
+ - run: npm test
25
+ - run: npm publish --access public --provenance
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 enola/phptr/msout
3
+ Copyright (c) 2026 enoola/phptr/msout
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,18 +1,24 @@
1
1
  # microsoft-webauth
2
2
 
3
3
  A tool to authenticate against microsoft online (live or professionnal tenants)
4
+ We do not rely on GraphAPI.
4
5
  e.g:
5
6
  - https://onenote.cloud.microsoft/notebooks
6
7
  - https://outlook.live.com/mail/
7
8
  - and by extension https://login.microsoft.com
8
9
 
9
- Microsoft web authentication via Playwright — extracted from [MSOneNote Exporter](https://github.com/msout/Microsoft-OneNote-Exporter).
10
+ Microsoft web authentication via Playwright — extracted from [MSOneNote Exporter](https://github.com/enoola/Microsoft-OneNote-Exporter).
11
+ I did extract it realising it might be useful out of the box for other projects.
12
+ And it will make it easier to maintain as far as I see it.
10
13
 
11
14
  This is a standalone CLI tool for authenticating with Microsoft accounts using Playwright. It handles:
15
+ - NO GraphAPI
12
16
  - Automated login with email/password
13
17
  - Manual login in browser
14
18
  - MFA/2FA support (OTC codes, number matching)
15
19
  - Session persistence
20
+
21
+
16
22
  ## Available on npmjs
17
23
 
18
24
  You can find this package here: https://www.npmjs.com/package/@msout/microsoft-webauth
package/jest.config.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @fileoverview Jest configuration.
3
+ * @author phptr,enoola,msout
4
+ * @copyright 2026 phptr,enoola,msout
5
+ */
6
+ module.exports = {
7
+ testEnvironment: 'node',
8
+ testPathIgnorePatterns: ['/node_modules/', '/dist/'],
9
+ collectCoverageFrom: ['src/**/*.js'],
10
+ coverageDirectory: 'coverage',
11
+ verbose: true
12
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@msout/microsoft-webauth",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "Microsoft web authentication module, using playwright to automate the login process and retrieve cookies for authenticated sessions.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -22,7 +22,7 @@
22
22
  "javascript"
23
23
  ],
24
24
  "author": "msout@tuta.io",
25
- "license": "MIT",
25
+ "license": "Apache-2.0",
26
26
  "repository": {
27
27
  "type": "git",
28
28
  "url": "git+https://github.com/Ms-OneNote-Exporter/microsoft-webauth.git"
package/src/auth.js CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @fileoverview This file handles user authentication logic.
3
+ * @author phptr,enoola,msout
4
+ * @copyright 2026 phptr,enoola,msout
5
+ */
1
6
  const { chromium } = require('playwright');
2
7
  const fs = require('fs-extra');
3
8
  const logger = require('./utils/logger');
@@ -486,7 +491,7 @@ async function login(credentials = {}) {
486
491
  } catch (e) {
487
492
  logger.debug(`Post-password verification handling skipped or failed: ${e.message}`);
488
493
  }
489
-
494
+
490
495
  // 2.7. Handle "Help protect your account" interrupt screen
491
496
  try {
492
497
  const interruptPrompt = page.getByText(/Help protect your account/i).first();
package/src/config.js CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @fileoverview Returns the directory where auth files (auth.json, auth-meta.json) are stored.
3
+ * @author phptr,enoola,msout
4
+ * @copyright 2026 phptr,enoola,msout
5
+ */
1
6
  const path = require('path');
2
7
 
3
8
  /**
package/src/index.js CHANGED
@@ -1,4 +1,9 @@
1
1
  #!/usr/bin/env node
2
+ /**
3
+ * @fileoverview Main CLI interface to handle authentication commands.
4
+ * @author phptr,enoola,msout
5
+ * @copyright 2026 phptr,enoola,msout
6
+ */
2
7
  const { program } = require('commander');
3
8
  const logger = require('./utils/logger');
4
9
  const { login, checkAuth, getAuthMeta, logout } = require('./auth');
@@ -1,38 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(git add *)",
5
- "Bash(git commit *)",
6
- "Bash(git push)",
7
- "Bash(cat)",
8
- "Bash(let *)",
9
- "Bash(beforeeach)",
10
- "Bash(jest.clearallmocks)",
11
- "Bash(fs.removesync)",
12
- "Bash(config *)",
13
- "Bash('../src/config')",
14
- "Bash(auth *)",
15
- "Bash('../src/auth')",
16
- "Bash(})",
17
- "Bash(expect)",
18
- "Bash(.tobe)",
19
- "Bash(eof)",
20
- "Bash(npm test)",
21
- "Bash(head *)",
22
- "Bash(import *)",
23
- "Bash(with)",
24
- "Bash(as *)",
25
- "Bash(content *)",
26
- "Bash(old_test *)",
27
- "Bash(new_test *)",
28
- "Bash(const *)",
29
- "Bash('https://mock.test/nonexistent')",
30
- "Bash(// *)",
31
- "Bash(conservative *)",
32
- "Bash(}, *)",
33
- "Bash('''\n\ncontent = content.replace(old_test, new_test)\n\nwith open('/users/enola/workspace-msout/microsoft-webauth-playwright-js/test/auth.test.js', 'w)",
34
- "Bash(node *)"
35
- ]
36
- },
37
- "$version": 4
38
- }
package/test/auth.test.js DELETED
@@ -1,134 +0,0 @@
1
- const path = require('path');
2
- const fs = require('fs-extra');
3
-
4
- // Mock the modules before requiring auth
5
- jest.mock('../src/config', () => ({
6
- AUTH_FILE: '/tmp/test-auth.json',
7
- ONENOTE_URL: 'https://www.onenote.com/notebooks',
8
- OUTLOOK_URL: 'https://outlook.cloud.microsoft/mail/',
9
- USER_DATA_DIR: '/tmp'
10
- }));
11
-
12
- jest.mock('../src/utils/logger', () => ({
13
- info: jest.fn(),
14
- warn: jest.fn(),
15
- error: jest.fn(),
16
- success: jest.fn(),
17
- debug: jest.fn(),
18
- step: jest.fn(),
19
- getDumpDir: async () => '/tmp/dumps',
20
- getDumpDisplayPath: () => 'logs/dumps/test'
21
- }));
22
-
23
- describe('Auth Module', () => {
24
- let auth;
25
- let config;
26
-
27
- beforeEach(() => {
28
- jest.clearAllMocks();
29
- // Clean up test files before each test
30
- fs.removeSync('/tmp/test-auth.json');
31
- fs.removeSync('/tmp/test-auth-meta.json');
32
-
33
- // Re-import after mocks are set up
34
- config = require('../src/config');
35
- auth = require('../src/auth');
36
- });
37
-
38
- afterAll(async () => {
39
- // Clean up after all tests
40
- fs.removeSync('/tmp/test-auth.json');
41
- fs.removeSync('/tmp/test-auth-meta.json');
42
- });
43
-
44
- describe('getAuthMeta', () => {
45
- it('should return null when no auth meta file exists', async () => {
46
- const { getAuthMeta } = require('../src/auth');
47
- const meta = await getAuthMeta();
48
- expect(meta).toBeNull();
49
- });
50
-
51
- it('should return metadata when auth meta file exists', async () => {
52
- // Create a test meta file
53
- await fs.writeJson('/tmp/test-auth-meta.json', {
54
- email: 'test@example.com',
55
- loginTime: new Date().toISOString()
56
- });
57
-
58
- const { getAuthMeta } = require('../src/auth');
59
- const meta = await getAuthMeta();
60
-
61
- expect(meta).toBeDefined();
62
- expect(meta.email).toBe('test@example.com');
63
- expect(meta.loginTime).toBeDefined();
64
- });
65
- });
66
-
67
- describe('logout', () => {
68
- it('should remove auth files', async () => {
69
- // Create test files
70
- await fs.writeJson('/tmp/test-auth.json', { test: true });
71
- await fs.writeJson('/tmp/test-auth-meta.json', { email: 'test@example.com' });
72
-
73
- const { logout } = require('../src/auth');
74
- await logout();
75
-
76
- expect(await fs.pathExists('/tmp/test-auth.json')).toBe(false);
77
- expect(await fs.pathExists('/tmp/test-auth-meta.json')).toBe(false);
78
- });
79
- });
80
-
81
- describe('checkAuth', () => {
82
- it('should return false when no auth file exists', async () => {
83
- const { checkAuth } = require('../src/auth');
84
- const isAuth = await checkAuth();
85
- expect(isAuth).toBe(false);
86
- });
87
-
88
- it('should handle network errors gracefully', async () => {
89
- // Create a dummy auth file
90
- await fs.writeJson('/tmp/test-auth.json', { test: true });
91
-
92
- const { checkAuth } = require('../src/auth');
93
- // Use mock URL that won't actually connect
94
- const isAuth = await checkAuth('https://mock.test/nonexistent');
95
-
96
- // Should return true on error (conservative approach)
97
- expect(isAuth).toBe(true);
98
- }, 10000);
99
- });
100
-
101
- describe('getAuthenticatedContext', () => {
102
- it('should throw error when no auth file exists', async () => {
103
- const { getAuthenticatedContext } = require('../src/auth');
104
-
105
- await expect(getAuthenticatedContext(null)).rejects.toThrow(
106
- 'No authentication state found. Please run "login" command first.'
107
- );
108
- });
109
- });
110
- });
111
-
112
- describe('config', () => {
113
- let config;
114
-
115
- beforeEach(() => {
116
- jest.clearAllMocks();
117
- fs.removeSync('/tmp/test-auth.json');
118
- fs.removeSync('/tmp/test-auth-meta.json');
119
- config = require('../src/config');
120
- auth = require('../src/auth');
121
- });
122
-
123
- it('should export AUTH_FILE', () => {
124
- expect(config.AUTH_FILE).toBe('/tmp/test-auth.json');
125
- });
126
-
127
- it('should export ONENOTE_URL', () => {
128
- expect(config.ONENOTE_URL).toBe('https://www.onenote.com/notebooks');
129
- });
130
-
131
- it('should export OUTLOOK_URL', () => {
132
- expect(config.OUTLOOK_URL).toBe('https://outlook.cloud.microsoft/mail/');
133
- });
134
- });